Merge remote-tracking branch 'upstream/master' into batchDelection

This commit is contained in:
pfh 2018-01-29 16:41:47 +08:00
commit dca8459a13
29 changed files with 317 additions and 49 deletions

View File

@ -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
View 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.

Binary file not shown.

Before

Width:  |  Height:  |  Size: 42 KiB

After

Width:  |  Height:  |  Size: 78 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 24 KiB

After

Width:  |  Height:  |  Size: 70 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 23 KiB

After

Width:  |  Height:  |  Size: 70 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 45 KiB

After

Width:  |  Height:  |  Size: 40 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 36 KiB

After

Width:  |  Height:  |  Size: 25 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 36 KiB

After

Width:  |  Height:  |  Size: 25 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 20 KiB

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 13 KiB

After

Width:  |  Height:  |  Size: 9.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 14 KiB

After

Width:  |  Height:  |  Size: 9.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 36 KiB

After

Width:  |  Height:  |  Size: 26 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 38 KiB

After

Width:  |  Height:  |  Size: 26 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 74 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 114 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 116 KiB

View File

@ -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
View 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.

View File

@ -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:

View File

@ -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.

View File

@ -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:

View File

@ -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))

View File

@ -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)
}

View File

@ -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
}

View File

@ -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)
}

View File

@ -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

View File

@ -116,7 +116,9 @@ func main() {
scheduler.DefaultScheduler.Start()
//Subscribe the policy change topic.
notifier.Subscribe(notifier.ScanAllPolicyTopic, &notifier.ScanPolicyNotificationHandler{})
if err = notifier.Subscribe(notifier.ScanAllPolicyTopic, &notifier.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 {

View File

@ -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:

View File

@ -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']