Merge remote-tracking branch 'upstream/master' into batchDelection
4
Makefile
@ -284,9 +284,11 @@ modify_composefile: modify_composefile_notary modify_composefile_clair
|
||||
@cp $(DOCKERCOMPOSEFILEPATH)/$(DOCKERCOMPOSETPLFILENAME) $(DOCKERCOMPOSEFILEPATH)/$(DOCKERCOMPOSEFILENAME)
|
||||
@cp $(DOCKERCOMPOSEFILEPATH)/ha/$(DOCKERCOMPOSETPLFILENAME) $(DOCKERCOMPOSEFILEPATH)/ha/$(DOCKERCOMPOSEFILENAME)
|
||||
@$(SEDCMD) -i 's/__version__/$(VERSIONTAG)/g' $(DOCKERCOMPOSEFILEPATH)/ha/$(DOCKERCOMPOSEFILENAME)
|
||||
@$(SEDCMD) -i 's/__reg_version__/$(REGISTRYVERSION)-$(VERSIONTAG)/g' $(DOCKERCOMPOSEFILEPATH)/$(DOCKERCOMPOSEFILENAME)
|
||||
@$(SEDCMD) -i 's/__version__/$(VERSIONTAG)/g' $(DOCKERCOMPOSEFILEPATH)/$(DOCKERCOMPOSEFILENAME)
|
||||
@$(SEDCMD) -i 's/__reg_version__/$(REGISTRYVERSION)-$(VERSIONTAG)/g' $(DOCKERCOMPOSEFILEPATH)/$(DOCKERCOMPOSEFILENAME)
|
||||
@$(SEDCMD) -i 's/__reg_version__/$(REGISTRYVERSION)-$(VERSIONTAG)/g' $(DOCKERCOMPOSEFILEPATH)/ha/$(DOCKERCOMPOSEFILENAME)
|
||||
@$(SEDCMD) -i 's/__nginx_version__/$(NGINXVERSION)/g' $(DOCKERCOMPOSEFILEPATH)/$(DOCKERCOMPOSEFILENAME)
|
||||
@$(SEDCMD) -i 's/__nginx_version__/$(NGINXVERSION)/g' $(DOCKERCOMPOSEFILEPATH)/ha/$(DOCKERCOMPOSEFILENAME)
|
||||
|
||||
modify_composefile_notary:
|
||||
@echo "preparing docker-compose notary file..."
|
||||
|
104
docs/expand_hard_disk.md
Normal file
@ -0,0 +1,104 @@
|
||||
# Expand the Hard Disk of Virtual Appliance
|
||||
|
||||
If you install Harbor with OVA, the persistent data(such as images and database) is stored in a hard disk which is mounted on directory "/data", and the default size is 60GB. As more and more images are pushed into it, the capacity may not meet your requirements.
|
||||
|
||||
You can check the space on Harbor web UI by clicking on **Projects**:
|
||||
|
||||
|
||||
|
||||
![lvm](img/lvm/check_on_ui_01.png)
|
||||
|
||||
If your free space is running out, you can expand the size of the hard disk by the following steps:
|
||||
|
||||
1. Add New Hard Disk to VM
|
||||
|
||||
(1) Log in vSphere web client. Power off Harbor's virtual appliance.
|
||||
(2) Right click on the VM and select "Edit Settings".
|
||||
(3) Select "New Hard Disk", and click "OK".
|
||||
|
||||
![lvm](img/lvm/add_new_hard_disk.png)
|
||||
|
||||
We add a 10GB new hard disk to show the operations.
|
||||
|
||||
(4) Power on the VM.
|
||||
|
||||
2. Expand Hard Disk using LVM
|
||||
|
||||
Login from the console of the virtual appliance and run the following commands:
|
||||
|
||||
(1) Check the current size of "/data":
|
||||
```sh
|
||||
df -h /data
|
||||
```
|
||||
|
||||
![lvm](img/lvm/size_of_data_01.png)
|
||||
|
||||
(2) Find the new hard disk, e.g. "/dev/sdc". Replace all "/dev/sdc" with your disk in the following commands.
|
||||
```sh
|
||||
fdisk -l
|
||||
```
|
||||
|
||||
![lvm](img/lvm/find_the_new_harddisk.png)
|
||||
|
||||
(3) Create new physical volume:
|
||||
```sh
|
||||
pvcreate /dev/sdc
|
||||
```
|
||||
|
||||
(4) Check the volume group:
|
||||
```sh
|
||||
vgdisplay
|
||||
```
|
||||
|
||||
![lvm](img/lvm/vg_01.png)
|
||||
|
||||
(5) Expand the volume group:
|
||||
```sh
|
||||
vgextend data1_vg /dev/sdc
|
||||
```
|
||||
|
||||
(6) Check the volume group again:
|
||||
```sh
|
||||
vgdisplay
|
||||
```
|
||||
|
||||
![lvm](img/lvm/vg_02.png)
|
||||
|
||||
(7) Check the logical volume:
|
||||
```sh
|
||||
lvdisplay
|
||||
```
|
||||
|
||||
![lvm](img/lvm/lv_01.png)
|
||||
|
||||
(8) Resize the logical volume:
|
||||
```sh
|
||||
lvresize -l +100%FREE /dev/data1_vg/data
|
||||
```
|
||||
|
||||
![lvm](img/lvm/resize_lv.png)
|
||||
|
||||
(9) Check the logical volume again, note the change of "LV Size":
|
||||
```sh
|
||||
lvdisplay
|
||||
```
|
||||
|
||||
![lvm](img/lvm/lv_02.png)
|
||||
|
||||
(10) Resize the file system:
|
||||
```sh
|
||||
resize2fs /dev/data1_vg/data
|
||||
```
|
||||
|
||||
(11) Check the size "/data" again:
|
||||
```sh
|
||||
df -h /data
|
||||
```
|
||||
|
||||
![lvm](img/lvm/size_of_data_02.png)
|
||||
|
||||
You can also check the size on Harbor web UI:
|
||||
|
||||
![lvm](img/lvm/check_on_ui.png)
|
||||
|
||||
After that, your disk should be expanded successfully. If you want to add more hard disks, do the steps again.
|
Before Width: | Height: | Size: 42 KiB After Width: | Height: | Size: 78 KiB |
Before Width: | Height: | Size: 24 KiB After Width: | Height: | Size: 70 KiB |
Before Width: | Height: | Size: 23 KiB After Width: | Height: | Size: 70 KiB |
Before Width: | Height: | Size: 45 KiB After Width: | Height: | Size: 40 KiB |
Before Width: | Height: | Size: 36 KiB After Width: | Height: | Size: 25 KiB |
Before Width: | Height: | Size: 36 KiB After Width: | Height: | Size: 25 KiB |
Before Width: | Height: | Size: 20 KiB After Width: | Height: | Size: 12 KiB |
Before Width: | Height: | Size: 13 KiB After Width: | Height: | Size: 9.6 KiB |
Before Width: | Height: | Size: 14 KiB After Width: | Height: | Size: 9.6 KiB |
Before Width: | Height: | Size: 36 KiB After Width: | Height: | Size: 26 KiB |
Before Width: | Height: | Size: 38 KiB After Width: | Height: | Size: 26 KiB |
BIN
docs/img/ovainstall/pvscan.png
Normal file
After Width: | Height: | Size: 74 KiB |
BIN
docs/img/ovainstall/removedisk.png
Normal file
After Width: | Height: | Size: 114 KiB |
BIN
docs/img/ovainstall/vappoptions.png
Normal file
After Width: | Height: | Size: 116 KiB |
@ -110,4 +110,8 @@
|
||||
|
||||
![Screenshot of after login](img/ovainstall/afterlogin.png)
|
||||
|
||||
Please run "tdnf distro-sync" command from time to time to keep the OS up to date.
|
||||
To migrate Harbor OVA, please refer [migrate OVA guide](migrate_ova_guide.md)
|
||||
|
||||
To extend the data disk in Harbor OVA, please refer [Expand the Hard Disk of Virtual Appliance](expand_hard_disk.md)
|
||||
|
||||
Please run "tdnf distro-sync" command from time to time to keep the OS up to date.
|
||||
|
41
docs/migrate_ova_guide.md
Normal file
@ -0,0 +1,41 @@
|
||||
# Harbor OVA upgrade and database migration guide
|
||||
|
||||
This guide is limited to migrate a Harbor OVA instance to a next release. All Harbor data storeage settings is not manually changed after the existing Harbor OVA deployed.
|
||||
|
||||
**Steps to migrate Harbor OVA instances:**
|
||||
|
||||
1. Before migration, you need to note down these following items:
|
||||
- Note down the value of db_password in /data/harbor.cfg.
|
||||
- **"Networking properties"** if need to keep these settings. you can find them in **"Edit Settings"** -> **"vApp Options"**
|
||||
![Screenshot of vApp Options](img/ovainstall/vappoptions.png)
|
||||
|
||||
2. In the vSphere Web Client, Select **"Shut Down Guest OS"** on the existing OVA instances, then select **"Edit Settings"**, remove the **"Hard disk 2"**, uncheck **"Delete files from datastore"**. All disks in the logical volume "data1_vg" should be removed if the original logic volume have been extended. Use pvscan command to check disks in logical volume "data1_vg".
|
||||
|
||||
![Screenshot of pvscan](img/ovainstall/pvscan.png)
|
||||
|
||||
Usually, the sda is the Hard Disk1 in the **"Edit Settings"** pannel, and the sdb is Hard Disk2 and so on. Note down all location of disk files in logical volume "data1_vg".
|
||||
|
||||
![Screenshot of Remove Disk](img/ovainstall/removedisk.png)
|
||||
|
||||
3. Deploy a new Harbor OVA instances. You may use different settings or keep same settings.
|
||||
|
||||
| Configuration Section Name |Use Different Settings | Keep Same Settings |
|
||||
|-------------------------------- | ------------------|--------------------------------------------- |
|
||||
| Certificates | Leave blank to use auto-generated certificates or paste in new certificates |Replace files in /data/ca_download and /data/cert with backup files in the same path of prevous Harbor instance and restart Harbor OVA after migration |
|
||||
| Harbor Configuration | N/A |Input a random administrator password to bypass the data validation, it uses previous settings after migration |
|
||||
| LDAP Configuration | N/A |Leave blank, it uses previous settings after migration |
|
||||
| Networking Properties | Input new settings | Input previous settings |
|
||||
| System | Input new settings | Input previous settings |
|
||||
|
||||
4. Copy all disk files of logic volume "data1_vg" in Step 2 to the new Harbor OVA's folder in vSphere's datastore.
|
||||
5. Before powering on the new Harbor OVA instances, select **"Edit Settings"**, after remove the "Hard disk 2", then click **" Existing Hard Disk"** in **"New Device"**, let it point to the disk file copied in Step 4. Please add all disk files in the same order with previous OVA instance.
|
||||
6. Power on the new OVA instance, login to the console and run following commands:
|
||||
```
|
||||
chmod 700 /migrate_OVA.sh
|
||||
/migrate_OVA.sh
|
||||
```
|
||||
When prompt, input the value of db_password that note down in Step 1.
|
||||
7. After the script is complete, visit URL: https://*<DNS Name>* to verify the new Harbor OVA instance. the administrator's password is the same password of previous Harbor instance.
|
||||
|
||||
|
||||
|
@ -9,6 +9,8 @@ When upgrading your existing Habor instance to a newer version, you may need to
|
||||
|
||||
- You must back up your data before any data migration.
|
||||
|
||||
- To migrate harbor OVA, please refer [migrate OVA guide](migrate_ova_guide.md)
|
||||
|
||||
### Upgrading Harbor and migrating data
|
||||
|
||||
1. Log in to the host that Harbor runs on, stop and remove existing Harbor instance if it is still running:
|
||||
|
@ -2,7 +2,7 @@ swagger: '2.0'
|
||||
info:
|
||||
title: Harbor API
|
||||
description: These APIs provide services for manipulating Harbor project.
|
||||
version: 0.3.0
|
||||
version: 1.4.0
|
||||
host: localhost
|
||||
schemes:
|
||||
- http
|
||||
@ -11,7 +11,6 @@ produces:
|
||||
- application/json
|
||||
- text/plain
|
||||
consumes:
|
||||
- text/plain
|
||||
- application/json
|
||||
paths:
|
||||
/search:
|
||||
@ -142,6 +141,8 @@ paths:
|
||||
description: User need to log in first.
|
||||
'409':
|
||||
description: Project name already exists.
|
||||
'415':
|
||||
$ref: '#/responses/UnsupportedMediaType'
|
||||
'500':
|
||||
description: Unexpected internal errors.
|
||||
'/projects/{project_id}':
|
||||
@ -355,6 +356,8 @@ paths:
|
||||
description: User does not have permission to the project.
|
||||
'404':
|
||||
description: Project ID does not exist.
|
||||
'415':
|
||||
$ref: '#/responses/UnsupportedMediaType'
|
||||
'500':
|
||||
description: Internal server errors.
|
||||
'/projects/{project_id}/metadatas/{meta_name}':
|
||||
@ -511,6 +514,8 @@ paths:
|
||||
description: Project ID or username does not exist.
|
||||
'409':
|
||||
description: User has already added as a project role member.
|
||||
'415':
|
||||
$ref: '#/responses/UnsupportedMediaType'
|
||||
'500':
|
||||
description: Unexpected internal errors.
|
||||
'/projects/{project_id}/members/{user_id}':
|
||||
@ -712,6 +717,8 @@ paths:
|
||||
description: >-
|
||||
User registration can only be used by admin role user when
|
||||
self-registration is off.
|
||||
'415':
|
||||
$ref: '#/responses/UnsupportedMediaType'
|
||||
'500':
|
||||
description: Unexpected internal errors.
|
||||
/users/current:
|
||||
@ -1131,6 +1138,8 @@ paths:
|
||||
description: User doesn't have permission to perform the action.
|
||||
'404':
|
||||
description: The image does not exist in Harbor.
|
||||
'415':
|
||||
$ref: '#/responses/UnsupportedMediaType'
|
||||
'503':
|
||||
description: Harbor is not deployed with Clair.
|
||||
/repositories/scanAll:
|
||||
@ -1146,7 +1155,9 @@ paths:
|
||||
- name: project_id
|
||||
in: query
|
||||
type: integer
|
||||
description: When this parm is set only the images under the project identified by the project_id will be scanned.
|
||||
description: >-
|
||||
When this parm is set only the images under the project identified
|
||||
by the project_id will be scanned.
|
||||
responses:
|
||||
'202':
|
||||
description: >-
|
||||
@ -1156,6 +1167,8 @@ paths:
|
||||
description: User needs to login or call the API with correct credentials.
|
||||
'403':
|
||||
description: User doesn't have permission to perform the action.
|
||||
'415':
|
||||
$ref: '#/responses/UnsupportedMediaType'
|
||||
'500':
|
||||
description: Failed to initiate the action.
|
||||
'503':
|
||||
@ -1393,7 +1406,7 @@ paths:
|
||||
description: Unexpected internal errors.
|
||||
put:
|
||||
summary: Update status of jobs. Only stop is supported for now.
|
||||
description: >
|
||||
description: |
|
||||
The endpoint is used to stop the replication jobs of a policy.
|
||||
tags:
|
||||
- Products
|
||||
@ -1417,7 +1430,7 @@ paths:
|
||||
description: Resource requested does not exist.
|
||||
'500':
|
||||
description: Unexpected internal errors.
|
||||
/jobs/replication/{id}:
|
||||
'/jobs/replication/{id}':
|
||||
delete:
|
||||
summary: Delete specific ID job.
|
||||
description: |
|
||||
@ -1442,7 +1455,7 @@ paths:
|
||||
description: Project ID does not exist.
|
||||
'500':
|
||||
description: Unexpected internal errors.
|
||||
/jobs/replication/{id}/log:
|
||||
'/jobs/replication/{id}/log':
|
||||
get:
|
||||
summary: Get job logs.
|
||||
description: |
|
||||
@ -1467,7 +1480,7 @@ paths:
|
||||
description: The specific repository ID's log does not exist.
|
||||
'500':
|
||||
description: Unexpected internal errors.
|
||||
/jobs/scan/{id}/log:
|
||||
'/jobs/scan/{id}/log':
|
||||
get:
|
||||
summary: Get job logs.
|
||||
description: |
|
||||
@ -1492,7 +1505,6 @@ paths:
|
||||
description: The specific repository ID's log does not exist.
|
||||
'500':
|
||||
description: Unexpected internal errors.
|
||||
|
||||
/policies/replication:
|
||||
get:
|
||||
summary: List filters policies by name and project_id
|
||||
@ -1516,13 +1528,13 @@ paths:
|
||||
type: integer
|
||||
format: int32
|
||||
required: false
|
||||
description: 'The page nubmer.'
|
||||
description: The page nubmer.
|
||||
- name: page_size
|
||||
in: query
|
||||
type: integer
|
||||
format: int32
|
||||
required: false
|
||||
description: 'The size of per page.'
|
||||
description: The size of per page.
|
||||
tags:
|
||||
- Products
|
||||
responses:
|
||||
@ -1563,9 +1575,11 @@ paths:
|
||||
description: >-
|
||||
Policy name already used or policy already exists with the same
|
||||
project and target.
|
||||
'415':
|
||||
$ref: '#/responses/UnsupportedMediaType'
|
||||
'500':
|
||||
description: Unexpected internal errors.
|
||||
/policies/replication/{id}:
|
||||
'/policies/replication/{id}':
|
||||
get:
|
||||
summary: Get replication policy.
|
||||
description: |
|
||||
@ -1604,7 +1618,7 @@ paths:
|
||||
description: policy ID
|
||||
- name: policyupdate
|
||||
in: body
|
||||
description: 'Updated properties of the replication policy.'
|
||||
description: Updated properties of the replication policy.
|
||||
required: true
|
||||
schema:
|
||||
$ref: '#/definitions/RepPolicy'
|
||||
@ -1646,6 +1660,8 @@ paths:
|
||||
description: User need to log in first.
|
||||
'404':
|
||||
description: The policy does not exist.
|
||||
'415':
|
||||
$ref: '#/responses/UnsupportedMediaType'
|
||||
'500':
|
||||
description: Unexpected internal errors.
|
||||
/targets:
|
||||
@ -1695,6 +1711,8 @@ paths:
|
||||
description: User need to log in first.
|
||||
'409':
|
||||
description: Replication target name already exists.
|
||||
'415':
|
||||
$ref: '#/responses/UnsupportedMediaType'
|
||||
'500':
|
||||
description: Unexpected internal errors.
|
||||
/targets/ping:
|
||||
@ -1725,6 +1743,8 @@ paths:
|
||||
target.
|
||||
'404':
|
||||
description: Target not found.
|
||||
'415':
|
||||
$ref: '#/responses/UnsupportedMediaType'
|
||||
'500':
|
||||
description: Unexpected internal errors.
|
||||
'/targets/{id}':
|
||||
@ -1852,6 +1872,8 @@ paths:
|
||||
description: User need to log in first.
|
||||
'403':
|
||||
description: User does not have permission of admin role.
|
||||
'415':
|
||||
$ref: '#/responses/UnsupportedMediaType'
|
||||
'500':
|
||||
description: Unexpected internal errors.
|
||||
/systeminfo:
|
||||
@ -1938,6 +1960,8 @@ paths:
|
||||
description: User need to login first.
|
||||
'403':
|
||||
description: Only admin has this authority.
|
||||
'415':
|
||||
$ref: '#/responses/UnsupportedMediaType'
|
||||
'500':
|
||||
description: Unexpected internal errors.
|
||||
/ldap/users/search:
|
||||
@ -1977,6 +2001,8 @@ paths:
|
||||
description: User need to login first.
|
||||
'403':
|
||||
description: Only admin has this authority.
|
||||
'415':
|
||||
$ref: '#/responses/UnsupportedMediaType'
|
||||
'500':
|
||||
description: Unexpected internal errors.
|
||||
/ldap/users/import:
|
||||
@ -2008,6 +2034,8 @@ paths:
|
||||
description: User need to login first.
|
||||
'403':
|
||||
description: Only admin has this authority.
|
||||
'415':
|
||||
$ref: '#/responses/UnsupportedMediaType'
|
||||
'500':
|
||||
description: Failed import some users.
|
||||
schema:
|
||||
@ -2046,7 +2074,9 @@ paths:
|
||||
required: true
|
||||
schema:
|
||||
$ref: '#/definitions/Configurations'
|
||||
description: The configuration map can contain a subset of the attributes of the schema, which are to be updated.
|
||||
description: >-
|
||||
The configuration map can contain a subset of the attributes of the
|
||||
schema, which are to be updated.
|
||||
responses:
|
||||
'200':
|
||||
description: Modify system configurations successfully.
|
||||
@ -2071,6 +2101,8 @@ paths:
|
||||
description: User need to log in first.
|
||||
'403':
|
||||
description: User does not have permission of admin role.
|
||||
'415':
|
||||
$ref: '#/responses/UnsupportedMediaType'
|
||||
'500':
|
||||
description: Unexpected internal errors.
|
||||
/email/ping:
|
||||
@ -2098,8 +2130,14 @@ paths:
|
||||
description: User need to login first.
|
||||
'403':
|
||||
description: Only admin has this authority.
|
||||
'415':
|
||||
$ref: '#responses/UnsupportedMediaType'
|
||||
'500':
|
||||
description: Unexpected internal errors.
|
||||
responses:
|
||||
UnsupportedMediaType:
|
||||
description: The Media Type of the request is not supported, it has to be "application/json"
|
||||
|
||||
definitions:
|
||||
Search:
|
||||
type: object
|
||||
@ -2451,7 +2489,9 @@ definitions:
|
||||
properties:
|
||||
kind:
|
||||
type: string
|
||||
description: The replication policy trigger kind. The valid values are manual, immediate and schedule.
|
||||
description: >-
|
||||
The replication policy trigger kind. The valid values are manual,
|
||||
immediate and schedule.
|
||||
schedule_param:
|
||||
$ref: '#/definitions/ScheduleParam'
|
||||
ScheduleParam:
|
||||
@ -2459,21 +2499,23 @@ definitions:
|
||||
properties:
|
||||
type:
|
||||
type: string
|
||||
description: The schedule type. The valid values are daily and weekly.
|
||||
description: The schedule type. The valid values are daily and weekly.
|
||||
weekday:
|
||||
type: integer
|
||||
format: int8
|
||||
description: Optional, only used when the type is weedly. The valid values are 1-7.
|
||||
description: 'Optional, only used when the type is weedly. The valid values are 1-7.'
|
||||
offtime:
|
||||
type: integer
|
||||
format: int64
|
||||
description: The time offset with the UTC 00:00 in seconds.
|
||||
description: 'The time offset with the UTC 00:00 in seconds.'
|
||||
RepFilter:
|
||||
type: object
|
||||
properties:
|
||||
kind:
|
||||
type: string
|
||||
description: The replication policy filter kind. The valid values are project, repository and tag.
|
||||
description: >-
|
||||
The replication policy filter kind. The valid values are project,
|
||||
repository and tag.
|
||||
pattern:
|
||||
type: string
|
||||
description: The replication policy filter pattern.
|
||||
@ -2505,7 +2547,9 @@ definitions:
|
||||
description: Reserved field.
|
||||
insecure:
|
||||
type: boolean
|
||||
description: Whether or not the certificate will be verified when Harbor tries to access the server.
|
||||
description: >-
|
||||
Whether or not the certificate will be verified when Harbor tries to
|
||||
access the server.
|
||||
creation_time:
|
||||
type: string
|
||||
description: The create time of the policy.
|
||||
@ -2529,7 +2573,9 @@ definitions:
|
||||
description: The target server password.
|
||||
insecure:
|
||||
type: boolean
|
||||
description: Whether or not the certificate will be verified when Harbor tries to access the server.
|
||||
description: >-
|
||||
Whether or not the certificate will be verified when Harbor tries to
|
||||
access the server.
|
||||
PingTarget:
|
||||
type: object
|
||||
properties:
|
||||
@ -2548,7 +2594,9 @@ definitions:
|
||||
description: The target server password.
|
||||
insecure:
|
||||
type: boolean
|
||||
description: Whether or not the certificate will be verified when Harbor tries to access the server.
|
||||
description: >-
|
||||
Whether or not the certificate will be verified when Harbor tries to
|
||||
access the server.
|
||||
PutTarget:
|
||||
type: object
|
||||
properties:
|
||||
@ -2566,7 +2614,9 @@ definitions:
|
||||
description: The target server password.
|
||||
insecure:
|
||||
type: boolean
|
||||
description: Whether or not the certificate will be verified when Harbor tries to access the server.
|
||||
description: >-
|
||||
Whether or not the certificate will be verified when Harbor tries to
|
||||
access the server.
|
||||
HasAdminRole:
|
||||
type: object
|
||||
properties:
|
||||
@ -2898,7 +2948,7 @@ definitions:
|
||||
properties:
|
||||
auth_mode:
|
||||
type: string
|
||||
description: The auth mode of current system, such as "db_auth", "ldap_auth"
|
||||
description: 'The auth mode of current system, such as "db_auth", "ldap_auth"'
|
||||
email_from:
|
||||
type: string
|
||||
description: The sender name for Email notification.
|
||||
@ -2916,10 +2966,15 @@ definitions:
|
||||
description: The username for authenticate against SMTP server.
|
||||
email_ssl:
|
||||
type: boolean
|
||||
description: When it's set to true the system will access Email server via TLS by default. If it's set to false, it still will handle "STARTTLS" from server side.
|
||||
description: >-
|
||||
When it's set to true the system will access Email server via TLS by
|
||||
default. If it's set to false, it still will handle "STARTTLS" from
|
||||
server side.
|
||||
email_insecure:
|
||||
type: boolean
|
||||
description: Whether or not the certificate will be verified when Harbor tries to access the email server.
|
||||
description: >-
|
||||
Whether or not the certificate will be verified when Harbor tries to
|
||||
access the email server.
|
||||
ldap_url:
|
||||
type: string
|
||||
description: The URL of LDAP server.
|
||||
@ -2931,10 +2986,12 @@ definitions:
|
||||
description: The filter for LDAP binding.
|
||||
ldap_scope:
|
||||
type: integer
|
||||
description: 0-LDAP_SCOPE_BASE, 1-LDAP_SCOPE_ONELEVEL, 2-LDAP_SCOPE_SUBTREE
|
||||
description: '0-LDAP_SCOPE_BASE, 1-LDAP_SCOPE_ONELEVEL, 2-LDAP_SCOPE_SUBTREE'
|
||||
ldap_uid:
|
||||
type: string
|
||||
description: The attribute which is used as identity for the LDAP binding, such as "CN" or "SAMAccountname"
|
||||
description: >-
|
||||
The attribute which is used as identity for the LDAP binding, such as
|
||||
"CN" or "SAMAccountname"
|
||||
ldap_search_dn:
|
||||
type: string
|
||||
description: The DN of the user to do the search.
|
||||
@ -2943,29 +3000,41 @@ definitions:
|
||||
description: timeout in seconds for connection to LDAP server.
|
||||
project_creation_restriction:
|
||||
type: string
|
||||
description: This attribute restricts what users have the permission to create project. It can be "everyone" or "adminonly".
|
||||
description: >-
|
||||
This attribute restricts what users have the permission to create
|
||||
project. It can be "everyone" or "adminonly".
|
||||
self_registration:
|
||||
type: boolean
|
||||
description: Whether the Harbor instance supports self-registration. If it's set to false, admin need to add user to the instance.
|
||||
description: >-
|
||||
Whether the Harbor instance supports self-registration. If it's set
|
||||
to false, admin need to add user to the instance.
|
||||
token_expiration:
|
||||
type: integer
|
||||
description: The expiration time of the token for internal Registry, in minutes.
|
||||
description: 'The expiration time of the token for internal Registry, in minutes.'
|
||||
verify_remote_cert:
|
||||
type: boolean
|
||||
description: Whether or not the certificate will be verified when Harbor tries to access a remote Harbor instance for replication.
|
||||
description: >-
|
||||
Whether or not the certificate will be verified when Harbor tries to
|
||||
access a remote Harbor instance for replication.
|
||||
scan_all_policy:
|
||||
type: object
|
||||
properties:
|
||||
type:
|
||||
type: string
|
||||
description: The type of scan all policy, currently the valid values are "none" and "daily"
|
||||
description: >-
|
||||
The type of scan all policy, currently the valid values are "none"
|
||||
and "daily"
|
||||
parameter:
|
||||
type: object
|
||||
properties:
|
||||
daily_time:
|
||||
type: integer
|
||||
description: The offest in seconds of UTC 0 o'clock, only valid when the policy type is "daily"
|
||||
description: The parameters of the policy, the values are dependant on the type of the policy.
|
||||
description: >-
|
||||
The offest in seconds of UTC 0 o'clock, only valid when the
|
||||
policy type is "daily"
|
||||
description: >-
|
||||
The parameters of the policy, the values are dependant on the type
|
||||
of the policy.
|
||||
Replication:
|
||||
type: object
|
||||
properties:
|
||||
@ -2983,7 +3052,7 @@ definitions:
|
||||
properties:
|
||||
policy_id:
|
||||
type: integer
|
||||
description: The ID of replication policy
|
||||
description: The ID of replication policy
|
||||
status:
|
||||
type: string
|
||||
description: The status of jobs. The only valid value is stop for now.
|
||||
description: The status of jobs. The only valid value is stop for now.
|
||||
|
@ -12,7 +12,7 @@ services:
|
||||
networks:
|
||||
- harbor
|
||||
registry:
|
||||
image: vmware/registry:2.6.2-photon
|
||||
image: vmware/registry-photon:__reg_version__
|
||||
container_name: registry
|
||||
restart: always
|
||||
volumes:
|
||||
@ -95,7 +95,7 @@ services:
|
||||
syslog-address: "tcp://127.0.0.1:1514"
|
||||
tag: "jobservice"
|
||||
proxy:
|
||||
image: vmware/nginx-photon:1.11.13
|
||||
image: vmware/nginx-photon:__nginx_version__
|
||||
container_name: nginx
|
||||
restart: always
|
||||
volumes:
|
||||
|
@ -265,7 +265,7 @@ else:
|
||||
storage_provider_name = rcp.get("configuration", "registry_storage_provider_name").strip()
|
||||
storage_provider_config = rcp.get("configuration", "registry_storage_provider_config").strip()
|
||||
# yaml requires 1 or more spaces between the key and value
|
||||
storage_provider_config = storage_provider_config.replace(":", ": ")
|
||||
storage_provider_config = storage_provider_config.replace(":", ": ", 1)
|
||||
|
||||
ui_secret = ''.join(random.choice(string.ascii_letters+string.digits) for i in range(16))
|
||||
jobservice_secret = ''.join(random.choice(string.ascii_letters+string.digits) for i in range(16))
|
||||
|
@ -100,7 +100,9 @@ func schedulePolicy(notification ScanPolicyNotification) error {
|
||||
OffsetTime: notification.DailyTime,
|
||||
})
|
||||
attachTask := task.NewScanAllTask()
|
||||
schedulePolicy.AttachTasks(attachTask)
|
||||
if err := schedulePolicy.AttachTasks(attachTask); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return scheduler.DefaultScheduler.Schedule(schedulePolicy)
|
||||
}
|
||||
|
@ -100,7 +100,9 @@ func TestTCPConn(addr string, timeout, interval int) error {
|
||||
time.Sleep(time.Duration(interval) * time.Second)
|
||||
continue
|
||||
}
|
||||
conn.Close()
|
||||
if err = conn.Close(); err != nil {
|
||||
log.Errorf("failed to close the connection: %v", err)
|
||||
}
|
||||
success <- 1
|
||||
break
|
||||
}
|
||||
|
@ -28,7 +28,7 @@ func NewLogger(j Job) (*log.Logger, error) {
|
||||
logFile := j.LogPath()
|
||||
d := filepath.Dir(logFile)
|
||||
if _, err := os.Stat(d); os.IsNotExist(err) {
|
||||
err := os.MkdirAll(d, 0755)
|
||||
err := os.MkdirAll(d, 0700)
|
||||
if err != nil {
|
||||
log.Errorf("Failed to create directory for log file %s, the error: %v", logFile, err)
|
||||
}
|
||||
|
@ -158,9 +158,11 @@ func (l *Auth) PostAuthenticate(u *models.User) error {
|
||||
if !Re.MatchString(u.Email) {
|
||||
log.Debugf("Not a valid email address: %v, skip to sync", u.Email)
|
||||
} else {
|
||||
dao.ChangeUserProfile(*u, "Email")
|
||||
if err = dao.ChangeUserProfile(*u, "Email"); err != nil {
|
||||
u.Email = dbUser.Email
|
||||
log.Errorf("failed to sync user email: %v", err)
|
||||
}
|
||||
}
|
||||
u.Email = dbUser.Email
|
||||
}
|
||||
|
||||
return nil
|
||||
|
@ -116,7 +116,9 @@ func main() {
|
||||
scheduler.DefaultScheduler.Start()
|
||||
|
||||
//Subscribe the policy change topic.
|
||||
notifier.Subscribe(notifier.ScanAllPolicyTopic, ¬ifier.ScanPolicyNotificationHandler{})
|
||||
if err = notifier.Subscribe(notifier.ScanAllPolicyTopic, ¬ifier.ScanPolicyNotificationHandler{}); err != nil {
|
||||
log.Errorf("failed to subscribe scan all policy change topic: %v", err)
|
||||
}
|
||||
|
||||
//Get policy configuration.
|
||||
scanAllPolicy := config.ScanAllPolicy()
|
||||
@ -129,7 +131,10 @@ func main() {
|
||||
}
|
||||
|
||||
//Send notification to handle first policy change.
|
||||
notifier.Publish(notifier.ScanAllPolicyTopic, notifier.ScanPolicyNotification{Type: scanAllPolicy.Type, DailyTime: (int64)(dailyTime)})
|
||||
if err = notifier.Publish(notifier.ScanAllPolicyTopic,
|
||||
notifier.ScanPolicyNotification{Type: scanAllPolicy.Type, DailyTime: (int64)(dailyTime)}); err != nil {
|
||||
log.Errorf("failed to publish scan all policy topic: %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
if err := core.Init(); err != nil {
|
||||
|
@ -89,6 +89,11 @@ if build_type == "ova" :
|
||||
logger.info("Harbor is not ready after 10 minutes.")
|
||||
sys.exit(-1)
|
||||
logger.info("%s is ready for test now..." % item)
|
||||
# ----- log harbor version -----
|
||||
harbor_version = harbor_util.get_harbor_version(item, 'admin', 'Harbor12345')
|
||||
logger.info("Harbor version: %s ..." % harbor_version)
|
||||
with open(os.getcwd() + '/build.properties', 'w') as the_file:
|
||||
the_file.write('harbor_version=%s' % harbor_version)
|
||||
|
||||
# ----- execute test cases -----
|
||||
try:
|
||||
|
@ -1,6 +1,33 @@
|
||||
from urllib2 import urlopen
|
||||
import ssl
|
||||
import time
|
||||
import os
|
||||
try:
|
||||
import json
|
||||
except ImportError:
|
||||
import simplejson as json
|
||||
|
||||
import requests
|
||||
from requests.packages.urllib3.exceptions import InsecureRequestWarning
|
||||
requests.packages.urllib3.disable_warnings(InsecureRequestWarning)
|
||||
|
||||
def request(harbor_endpoint, url, method, user, pwd, **kwargs):
|
||||
url = "https://" + harbor_endpoint + "/api" + url
|
||||
kwargs.setdefault('headers', kwargs.get('headers', {}))
|
||||
kwargs['headers']['Accept'] = 'application/json'
|
||||
if 'body' in kwargs:
|
||||
kwargs['headers']['Content-Type'] = 'application/json'
|
||||
kwargs['data'] = json.dumps(kwargs['body'])
|
||||
del kwargs['body']
|
||||
|
||||
resp = requests.request(method, url, verify=False, auth=(user, pwd), **kwargs)
|
||||
if resp.status_code >= 400:
|
||||
raise Exception("Error: %s" % resp.text)
|
||||
try:
|
||||
body = json.loads(resp.text)
|
||||
except ValueError:
|
||||
body = resp.text
|
||||
return body
|
||||
|
||||
# wait for 10 minutes as OVA needs about 7 minutes to startup harbor.
|
||||
def wait_for_harbor_ready(harbor_endpoint, timeout=600):
|
||||
@ -20,4 +47,7 @@ def wait_for_harbor_ready(harbor_endpoint, timeout=600):
|
||||
time.sleep(interval)
|
||||
continue
|
||||
timeout -= interval
|
||||
time.sleep(interval)
|
||||
time.sleep(interval)
|
||||
|
||||
def get_harbor_version(harbor_endpoint, harbor_user, harbor_pwd):
|
||||
return request(harbor_endpoint, '/systeminfo', 'get', harbor_user, harbor_pwd)['harbor_version']
|
||||
|