Merge remote-tracking branch 'origin/master' into add_chart_doc

This commit is contained in:
Steven Zou 2018-08-13 14:12:43 +08:00
commit a9d86d5bb6
52 changed files with 604 additions and 561 deletions

View File

@ -22,7 +22,7 @@ pipeline:
commands:
- echo ${DRONE_COMMIT_AUTHOR}
- echo $SKIP_CHECK_MEMBERSHIP
- if $SKIP_CHECK_MEMBERSHIP == true; then echo 'check-org-membership step skipped'; else /bin/bash -c '[[ ! $(curl --silent "https://api.github.com/orgs/vmware/members/${DRONE_COMMIT_AUTHOR}?access_token=$GITHUB_AUTOMATION_API_KEY") ]]'; fi
- if [ "$SKIP_CHECK_MEMBERSHIP" = "true" ]; then echo 'check-org-membership step skipped'; else /bin/bash -c '[[ ! $(curl --silent "https://api.github.com/orgs/vmware/members/${DRONE_COMMIT_AUTHOR}?access_token=$GITHUB_AUTOMATION_API_KEY") ]]'; fi
when:
status: success
@ -67,23 +67,9 @@ pipeline:
target: slack_webhook
username: drone
template: >
build https://ci-vic.vmware.com/vmware/harbor/{{ build.number }} finished with a {{ build.status }} status. Please find logs at https://storage.googleapis.com/harbor-ci-logs/integration_logs_{{ build.number }}_{{ build.commit }}.tar.gz
build https://ci-vic.vmware.com/goharbor/harbor/{{ build.number }} finished with a {{ build.status }} status. Please find logs at https://storage.googleapis.com/harbor-ci-logs/integration_logs_{{ build.number }}_{{ build.commit }}.tar.gz
when:
repo: vmware/harbor
repo: goharbor/harbor
event: [push, tag, deployment]
branch: [ master, release-*, refs/tags/* ]
status: [ failure, success ]
trigger:
image: plugins/downstream
server: https://ci-vic.vmware.com
secrets:
- downstream_token
fork: true
repositories:
- vmware/vic-product
when:
repo: vmware/harbor
event: [ push, tag ]
branch: [ master, release-*, refs/tags/* ]
status: success

View File

@ -79,7 +79,7 @@ script:
- sudo mkdir -p /harbor
- sudo mv ./VERSION /harbor/UIVERSION
- sudo service postgresql stop
- sudo make run_clarity_ut CLARITYIMAGE=vmware/harbor-clarity-ui-builder:1.6.0
- sudo make run_clarity_ut CLARITYIMAGE=goharbor/harbor-clarity-ui-builder:1.6.0
- cat ./src/ui_ng/npm-ut-test-results
- sudo ./tests/testprepare.sh
- sudo make -f make/photon/Makefile _build_db _build_registry -e VERSIONTAG=dev -e CLAIRDBVERSION=dev -e REGISTRYVERSION=v2.6.2

View File

@ -109,7 +109,7 @@ REDISVERSION=$(VERSIONTAG)
CHARTMUSEUMVERSION=v0.7.1
#clarity parameters
CLARITYIMAGE=vmware/harbor-clarity-ui-builder[:tag]
CLARITYIMAGE=goharbor/harbor-clarity-ui-builder[:tag]
CLARITYSEEDPATH=/harbor_src
CLARITYUTPATH=${CLARITYSEEDPATH}/ui_ng/lib
CLARITYBUILDSCRIPT=/entrypoint.sh
@ -184,14 +184,14 @@ DOCKERFILEPATH_COMMON=$(MAKEPATH)/common
DOCKERFILE_CLARITY=$(MAKEPATH)/dev/nodeclarity/Dockerfile
# docker image name
DOCKERIMAGENAME_ADMINSERVER=vmware/harbor-adminserver
DOCKERIMAGENAME_UI=vmware/harbor-ui
DOCKERIMAGENAME_JOBSERVICE=vmware/harbor-jobservice
DOCKERIMAGENAME_LOG=vmware/harbor-log
DOCKERIMAGENAME_DB=vmware/harbor-db
DOCKERIMAGENAME_CLARITY=vmware/harbor-clarity-ui-builder
DOCKERIMAGENAME_CHART_SERVER=vmware/chartmuseum-photon
DOCKERIMAGENAME_REGCTL=vmware/harbor-registryctl
DOCKERIMAGENAME_ADMINSERVER=goharbor/harbor-adminserver
DOCKERIMAGENAME_UI=goharbor/harbor-ui
DOCKERIMAGENAME_JOBSERVICE=goharbor/harbor-jobservice
DOCKERIMAGENAME_LOG=goharbor/harbor-log
DOCKERIMAGENAME_DB=goharbor/harbor-db
DOCKERIMAGENAME_CLARITY=goharbor/harbor-clarity-ui-builder
DOCKERIMAGENAME_CHART_SERVER=goharbor/chartmuseum-photon
DOCKERIMAGENAME_REGCTL=goharbor/harbor-registryctl
# docker-compose files
DOCKERCOMPOSEFILEPATH=$(MAKEPATH)
@ -225,8 +225,8 @@ DOCKERSAVE_PARA=$(DOCKERIMAGENAME_ADMINSERVER):$(VERSIONTAG) \
$(DOCKERIMAGENAME_DB):$(VERSIONTAG) \
$(DOCKERIMAGENAME_JOBSERVICE):$(VERSIONTAG) \
$(DOCKERIMAGENAME_REGCTL):$(VERSIONTAG) \
vmware/redis-photon:$(REDISVERSION) \
vmware/nginx-photon:$(NGINXVERSION) vmware/registry-photon:$(REGISTRYVERSION)-$(VERSIONTAG)
goharbor/redis-photon:$(REDISVERSION) \
goharbor/nginx-photon:$(NGINXVERSION) goharbor/registry-photon:$(REGISTRYVERSION)-$(VERSIONTAG)
PACKAGE_OFFLINE_PARA=-zcvf harbor-offline-installer-$(PKGVERSIONTAG).tgz \
$(HARBORPKG)/common/templates $(HARBORPKG)/$(DOCKERIMGFILE).$(VERSIONTAG).tar.gz \
@ -245,19 +245,19 @@ PACKAGE_ONLINE_PARA=-zcvf harbor-online-installer-$(PKGVERSIONTAG).tgz \
DOCKERCOMPOSE_LIST=-f $(DOCKERCOMPOSEFILEPATH)/$(DOCKERCOMPOSEFILENAME)
ifeq ($(NOTARYFLAG), true)
DOCKERSAVE_PARA+= vmware/notary-server-photon:$(NOTARYVERSION)-$(VERSIONTAG) vmware/notary-signer-photon:$(NOTARYVERSION)-$(VERSIONTAG)
DOCKERSAVE_PARA+= goharbor/notary-server-photon:$(NOTARYVERSION)-$(VERSIONTAG) goharbor/notary-signer-photon:$(NOTARYVERSION)-$(VERSIONTAG)
PACKAGE_OFFLINE_PARA+= $(HARBORPKG)/$(DOCKERCOMPOSENOTARYFILENAME)
PACKAGE_ONLINE_PARA+= $(HARBORPKG)/$(DOCKERCOMPOSENOTARYFILENAME)
DOCKERCOMPOSE_LIST+= -f $(DOCKERCOMPOSEFILEPATH)/$(DOCKERCOMPOSENOTARYFILENAME)
endif
ifeq ($(CLAIRFLAG), true)
DOCKERSAVE_PARA+= vmware/clair-photon:$(CLAIRVERSION)-$(VERSIONTAG)
DOCKERSAVE_PARA+= goharbor/clair-photon:$(CLAIRVERSION)-$(VERSIONTAG)
PACKAGE_OFFLINE_PARA+= $(HARBORPKG)/$(DOCKERCOMPOSECLAIRFILENAME)
PACKAGE_ONLINE_PARA+= $(HARBORPKG)/$(DOCKERCOMPOSECLAIRFILENAME)
DOCKERCOMPOSE_LIST+= -f $(DOCKERCOMPOSEFILEPATH)/$(DOCKERCOMPOSECLAIRFILENAME)
endif
ifeq ($(MIGRATORFLAG), true)
DOCKERSAVE_PARA+= vmware/harbor-migrator:$(MIGRATORVERSION)
DOCKERSAVE_PARA+= goharbor/harbor-migrator:$(MIGRATORVERSION)
endif
# append chartmuseum parameters if set
ifeq ($(CHARTFLAG), true)
@ -362,9 +362,9 @@ package_online: modify_composefile
@echo "packing online package ..."
@cp -r make $(HARBORPKG)
@if [ -n "$(REGISTRYSERVER)" ] ; then \
$(SEDCMD) -i 's/image\: vmware/image\: $(REGISTRYSERVER)\/$(REGISTRYPROJECTNAME)/' \
$(SEDCMD) -i 's/image\: goharbor/image\: $(REGISTRYSERVER)\/$(REGISTRYPROJECTNAME)/' \
$(HARBORPKG)/docker-compose.yml ; \
$(SEDCMD) -i 's/image\: vmware/image\: $(REGISTRYSERVER)\/$(REGISTRYPROJECTNAME)/' \
$(SEDCMD) -i 's/image\: goharbor/image\: $(REGISTRYSERVER)\/$(REGISTRYPROJECTNAME)/' \
$(HARBORPKG)/ha/docker-compose.yml ; \
fi
@cp LICENSE $(HARBORPKG)/LICENSE
@ -413,6 +413,16 @@ run_clarity_ut:
@echo "run clarity ut ..."
@$(DOCKERCMD) run --rm -v $(UINGPATH):$(CLARITYSEEDPATH) -v $(BUILDPATH)/tests:$(CLARITYSEEDPATH)/tests $(CLARITYIMAGE) $(SHELL) $(CLARITYSEEDPATH)/tests/run-clarity-ut.sh
gosec:
#go get github.com/securego/gosec/cmd/gosec
#go get github.com/dghubble/sling
@echo "run secure go scan ..."
@if [ "$(GOSECRESULTS)" != "" ] ; then \
$(GOPATH)/bin/gosec -fmt=json -out=$(GOSECRESULTS) -quiet ./... | true ; \
else \
$(GOPATH)/bin/gosec -fmt=json -out=harbor_gas_output.json -quiet ./... | true ; \
fi
pushimage:
@echo "pushing harbor images ..."
@$(DOCKERTAG) $(DOCKERIMAGENAME_ADMINSERVER):$(VERSIONTAG) $(REGISTRYSERVER)$(DOCKERIMAGENAME_ADMINSERVER):$(VERSIONTAG)

View File

@ -1,7 +1,8 @@
# Harbor
[![Build Status](https://travis-ci.org/vmware/harbor.svg?branch=master)](https://travis-ci.org/vmware/harbor)
[![Coverage Status](https://coveralls.io/repos/github/vmware/harbor/badge.svg?branch=master)](https://coveralls.io/github/vmware/harbor?branch=master)
[![Build Status](https://travis-ci.org/goharbor/harbor.svg?branch=master)](https://travis-ci.org/goharbor/harbor)
[![Coverage Status](https://coveralls.io/repos/github/goharbor/harbor/badge.svg?branch=master)](https://coveralls.io/github/goharbor/harbor?branch=master)
[![Go Report Card](https://goreportcard.com/badge/github.com/goharbor/harbor)](https://goreportcard.com/report/github.com/goharbor/harbor)
**Note**: The `master` branch may be in an *unstable or even broken state* during development.
Please use [releases](https://github.com/vmware/harbor/releases) instead of the `master` branch in order to get stable binaries.

View File

@ -2,19 +2,14 @@
## Introduction
This [Helm](https://github.com/kubernetes/helm) chart installs [Harbor](http://vmware.github.io/harbor/) in a Kubernetes cluster. Currently this chart supports Harbor v1.4.0 release. Welcome to [contribute](CONTRIBUTING.md) to Helm Chart for Harbor.
This [Helm](https://github.com/kubernetes/helm) chart installs [Harbor](http://vmware.github.io/harbor/) in a Kubernetes cluster. Welcome to [contribute](CONTRIBUTING.md) to Helm Chart for Harbor.
## Prerequisites
- Kubernetes cluster 1.8+ with Beta APIs enabled
- Kubernetes Ingress Controller is enabled
- kubectl CLI 1.8+
- Helm CLI 2.8.0+
## Known Issues
- This chart doesn't work with Kubernetes security update release 1.8.9+ and 1.9.4+. Refer to [issue 4496](https://github.com/vmware/harbor/issues/4496).
## Setup a Kubernetes cluster
You can use any tools to setup a K8s cluster.
@ -40,55 +35,15 @@ Download external dependent charts required by Harbor chart.
```bash
helm dependency update
```
### Secure Registry Mode
By default this chart will generate a root CA and SSL certificate for your Harbor.
You can also use your own CA signed certificate:
open values.yaml, set the value of 'externalDomain' to your Harbor FQDN, and
set value of 'tlsCrt', 'tlsKey', 'caCrt'. The common name of the certificate must match your Harbor FQDN.
Install the Harbor helm chart with a release name `my-release`:
```bash
helm install . --debug --name my-release --set externalDomain=harbor.my.domain
helm install --debug --name my-release --set externalDomain=harbor.my.domain,externalPort=443 .
```
**Make sure** `harbor.my.domain` resolves to the K8s Ingress Controller IP on the machines where you run docker or access Harbor UI.
**Note:** Make sure `harbor.my.domain` can be resolved to the K8s Ingress Controller IP on the machines where you run docker or access Harbor UI.
You can add `harbor.my.domain` and IP mapping in the DNS server, or in /etc/hosts, or use the FQDN `harbor.<IP>.xip.io`.
Follow the `NOTES` section in the command output to get Harbor admin password and **add Harbor root CA into docker trusted certificates**.
If you are using an external service like [cert-manager](https://github.com/jetstack/cert-manager) for generating the TLS certificates,
you will want to disable the certificate generation by helm by setting the value `generateCertificates` to _false_. Then the ingress' annotations will be scanned
by _cert-manager_ and the appropriate secret will get created and updated by the service.
If using acme's certificates, do not forget to add the following annotation to
your ingress.
```yaml
ingress:
annotations:
kubernetes.io/tls-acme: "true"
```
The command deploys Harbor on the Kubernetes cluster in the default configuration.
The [configuration](#configuration) section lists the parameters that can be configured in values.yaml or via '--set' params during installation.
> **Tip**: List all releases using `helm list`
### Insecure Registry Mode
If setting Harbor Registry as insecure-registries for docker,
you don't need to generate Root CA and SSL certificate for the Harbor ingress controller.
Install the Harbor helm chart with a release name `my-release`:
```bash
helm install . --debug --name my-release --set externalDomain=harbor.my.domain,insecureRegistry=true
```
**Make sure** `harbor.my.domain` resolves to the K8s Ingress Controller IP on the machines where you run docker or access Harbor UI.
You can add `harbor.my.domain` and IP mapping in the DNS server, or in /etc/hosts, or use the FQDN `harbor.<IP>.xip.io`.
Then add `"insecure-registries": ["harbor.my.domain"]` in the docker daemon config file and restart docker service.
The command deploys Harbor on the Kubernetes cluster with the default configuration.
The [configuration](#configuration) section lists the parameters that can be configured in values.yaml or via '--set' flag during installation.
## Uninstalling the Chart
@ -107,38 +62,39 @@ The following tables lists the configurable parameters of the Harbor chart and t
| Parameter | Description | Default |
| ----------------------- | ---------------------------------- | ----------------------- |
| **Harbor** |
| `harborImageTag` | The tag for Harbor docker images | `v1.4.0` |
| `persistence.enabled` | Persistent data | `true` |
| `externalProtocol` | The protocol Harbor serves with | `https` |
| `externalDomain` | Harbor will run on (https://`externalDomain`/). Recommend using K8s Ingress Controller FQDN as `externalDomain`, or make sure this FQDN resolves to the K8s Ingress Controller IP. | `harbor.my.domain` |
| `insecureRegistry` | If set to true, you don't need to set tlsCrt/tlsKey/caCrt, but must add Harbor FQDN as insecure-registries for your docker client. | `false` |
| `generateCertificates` | Set to false if TLS certificate will be managed by an external service | `true` |
| `tlsCrt` | TLS certificate to use for Harbor's https endpoint. Its CN must match `externalDomain`. | auto-generated |
| `tlsKey` | TLS key to use for Harbor's https endpoint | auto-generated |
| `caCrt` | CA Cert for self signed TLS cert | auto-generated |
| `persistence.enabled` | enable persistent data storage | `false` |
| `secretKey` | The secret key used for encryption. Must be a string of 16 chars. | `not-a-secure-key` |
| `externalPort` | The external port Harbor serves on. Configure it with the port of Ingress controller if it is enabled | `32700` |
| `harborAdminPassword` | The password of system admin | `Harbor12345` |
| `authenticationMode` | The authentication mode: `db_auth` for local database, `ldap_auth` for LDAP | `db_auth` |
| `selfRegistration` | Allows users to register by themselves, otherwise only system administrators can add users | `on` |
| `email.host` | The hostname of email server | `smtp.mydomain.com` |
| `email.port` | The port of email server | `25` |
| `email.username` | The username of email server | `sample_admin@mydomain.com` |
| `email.password` | The password for email server | `password` |
| `email.ssl` | Whether use TLS | `false` |
| `email.insecure` | Whether the connection with email server is insecure | `false` |
| `email.from` | The from address shows when send email| `admin <sample_admin@mydomain.com>` |
| `email.identity` | | |
| `ldap.url` | LDAP server URL for `ldap_auth` authentication | `ldaps://ldapserver` |
| `ldap.searchDN` | LDAP search DN | |
| `ldap.searchPassword` | LDAP search password | |
| `ldap.baseDN` | LDAP base DN | |
| `ldap.filter` | LDAP filter | `(objectClass=person)` |
| `ldap.uid` | LDAP UID | `uid` |
| `ldap.scope` | LDAP scope | `2` |
| `ldap.timeout` | LDAP timeout | `5` |
| `ldap.verifyCert` | Whether to verify HTTPS certificate | `true` |
| `secretkey` | The key used for encryption. Must be a string of 16 chars | `not-a-secure-key` |
| `harborImageTag` | The tag of Harbor images | `dev` |
| **Ingress** |
| `ingress.enabled` | Enable ingress objects | `true` |
| `ingress.tls.secretName` | Fill the secretName if you want to use the certificate of yourself when Harbor serves with HTTPS. A certificate will be generated automatically by the chart if leave it empty | |
| **Adminserver** |
| `adminserver.image.repository` | Repository for adminserver image | `vmware/harbor-adminserver` |
| `adminserver.image.tag` | Tag for adminserver image | `v1.4.0` |
| `adminserver.image.tag` | Tag for adminserver image | `dev` |
| `adminserver.image.pullPolicy` | Pull Policy for adminserver image | `IfNotPresent` |
| `adminserver.emailHost` | email server | `smtp.mydomain.com` |
| `adminserver.emailPort` | email port | `25` |
| `adminserver.emailUser` | email username | `sample_admin@mydomain.com` |
| `adminserver.emailSsl` | email uses SSL? | `false` |
| `adminserver.emailFrom` | send email from address | `admin <sample_admin@mydomain.com>` |
| `adminserver.emailIdentity` | | "" |
| `adminserver.key` | adminsever key | `not-a-secure-key` |
| `adminserver.emailPwd` | password for email | `not-a-secure-password` |
| `adminserver.adminPassword` | password for admin user | `Harbor12345` |
| `adminserver.authenticationMode` | authentication mode for Harbor ( `db_auth` for local database, `ldap_auth` for LDAP, etc...) [Docs](https://github.com/vmware/harbor/blob/master/docs/user_guide.md#user-account) | `db_auth` |
| `adminserver.selfRegistration` | Allows users to register by themselves, otherwise only administrators can add users | `on` |
| `adminserver.ldap.url` | LDAP server URL for `ldap_auth` authentication | `ldaps://ldapserver` |
| `adminserver.ldap.searchDN` | LDAP Search DN | `` |
| `adminserver.ldap.baseDN` | LDAP Base DN | `` |
| `adminserver.ldap.filter` | LDAP Filter | `(objectClass=person)` |
| `adminserver.ldap.uid` | LDAP UID | `uid` |
| `adminserver.ldap.scope` | LDAP Scope | `2` |
| `adminserver.ldap.timeout` | LDAP Timeout | `5` |
| `adminserver.ldap.verifyCert` | LDAP Verify HTTPS Certificate | `True` |
| `adminserver.resources` | [resources](https://kubernetes.io/docs/concepts/configuration/manage-compute-resources-container/) to allocate for container | undefined |
| `adminserver.volumes` | used to create PVCs if persistence is enabled (see instructions in values.yaml) | see values.yaml |
| `adminserver.nodeSelector` | Node labels for pod assignment | `{}` |
@ -146,9 +102,8 @@ The following tables lists the configurable parameters of the Harbor chart and t
| `adminserver.affinity` | Node/Pod affinities | `{}` |
| **Jobservice** |
| `jobservice.image.repository` | Repository for jobservice image | `vmware/harbor-jobservice` |
| `jobservice.image.tag` | Tag for jobservice image | `v1.4.0` |
| `jobservice.image.tag` | Tag for jobservice image | `dev` |
| `jobservice.image.pullPolicy` | Pull Policy for jobservice image | `IfNotPresent` |
| `jobservice.key` | jobservice key | `not-a-secure-key` |
| `jobservice.secret` | jobservice secret | `not-a-secure-secret` |
| `jobservice.resources` | [resources](https://kubernetes.io/docs/concepts/configuration/manage-compute-resources-container/) to allocate for container | undefined |
| `jobservice.nodeSelector` | Node labels for pod assignment | `{}` |
@ -156,80 +111,82 @@ The following tables lists the configurable parameters of the Harbor chart and t
| `jobservice.affinity` | Node/Pod affinities | `{}` |
| **UI** |
| `ui.image.repository` | Repository for ui image | `vmware/harbor-ui` |
| `ui.image.tag` | Tag for ui image | `v1.4.0` |
| `ui.image.tag` | Tag for ui image | `dev` |
| `ui.image.pullPolicy` | Pull Policy for ui image | `IfNotPresent` |
| `ui.key` | ui key | `not-a-secure-key` |
| `ui.secret` | ui secret | `not-a-secure-secret` |
| `ui.privateKeyPem` | ui private key | see values.yaml |
| `ui.resources` | [resources](https://kubernetes.io/docs/concepts/configuration/manage-compute-resources-container/) to allocate for container | undefined |
| `ui.nodeSelector` | Node labels for pod assignment | `{}` |
| `ui.tolerations` | Tolerations for pod assignment | `[]` |
| `ui.affinity` | Node/Pod affinities | `{}` |
| **MySQL** |
| `mysql.image.repository` | Repository for mysql image | `vmware/harbor-mysql` |
| `mysql.image.tag` | Tag for mysql image | `v1.4.0` |
| `mysql.image.pullPolicy` | Pull Policy for mysql image | `IfNotPresent` |
| `mysql.host` | MySQL Server | `~` |
| `mysql.port` | MySQL Port | `3306` |
| `mysql.user` | MySQL Username | `root` |
| `mysql.pass` | MySQL Password | `registry` |
| `mysql.database` | MySQL Database | `registry` |
| `mysql.resources` | [resources](https://kubernetes.io/docs/concepts/configuration/manage-compute-resources-container/) to allocate for container | undefined |
| `mysql.volumes` | used to create PVCs if persistence is enabled (see instructions in values.yaml) | see values.yaml |
| `mysql.nodeSelector` | Node labels for pod assignment | `{}` |
| `mysql.tolerations` | Tolerations for pod assignment | `[]` |
| `mysql.affinity` | Node/Pod affinities | `{}` |
| **Database** |
`database.type` | If external database is used, set it to `external` | `internal` |
| `database.internal.image.repository` | Repository for database image | `vmware/harbor-db` |
| `database.internal.image.tag` | Tag for database image | `dev` |
| `database.internal.image.pullPolicy` | Pull Policy for database image | `IfNotPresent` |
| `database.internal.password` | The password for database | `changeit` |
| `database.resources` | [resources](https://kubernetes.io/docs/concepts/configuration/manage-compute-resources-container/) to allocate for container | undefined |
| `database.internal.volumes` | The volume used to persistent data |
| `database.internal.nodeSelector` | Node labels for pod assignment | `{}` |
| `database.internal.tolerations` | Tolerations for pod assignment | `[]` |
| `database.internal.affinity` | Node/Pod affinities | `{}` |
| `database.external.host` | The hostname of external database | `192.168.0.1` |
| `database.external.port` | The port of external database | `5432` |
| `database.external.username` | The username of external database | `user` |
| `database.external.password` | The password of external database | `password` |
| `database.external.coreDatabase` | The database used by core service | `registry` |
| `database.external.clairDatabase` | The database used by clair | `clair` |
| `database.external.notaryServerDatabase` | The database used by Notary server | `notary_server` |
| `database.external.notarySignerDatabase` | The database used by Notary signer | `notary_signer` |
| **Registry** |
| `registry.image.repository` | Repository for registry image | `vmware/registry-photon` |
| `registry.image.tag` | Tag for registry image | `v2.6.2-v1.4.0` |
| `registry.image.tag` | Tag for registry image | `dev` |
| `registry.image.pullPolicy` | Pull Policy for registry image | `IfNotPresent` |
| `registry.rootCrt` | registry root cert | see values.yaml |
| `registry.httpSecret` | registry secret | `not-a-secure-secret` |
| `registry.logLevel` | The log level | `info` |
| `registry.storage.type` | The storage used to store images: `filesystem`, `azure`, `gcs`, `s3`, `swift`, `oss` | `filesystem` |
| `registry.resources` | [resources](https://kubernetes.io/docs/concepts/configuration/manage-compute-resources-container/) to allocate for container | undefined |
| `registry.volumes` | used to create PVCs if persistence is enabled (see instructions in values.yaml) | see values.yaml |
| `registry.nodeSelector` | Node labels for pod assignment | `{}` |
| `registry.tolerations` | Tolerations for pod assignment | `[]` |
| `registry.affinity` | Node/Pod affinities | `{}` |
| **Chartmuseum** |
| `chartmuseum.enabled` | Enable chartmusuem to store chart | `true` |
| `chartmuseum.image.repository` | Repository for chartmuseum image | `vmware/chartmuseum-photon` |
| `chartmuseum.image.tag` | Tag for chartmuseum image | `dev` |
| `chartmuseum.image.pullPolicy` | Pull Policy for chartmuseum image | `IfNotPresent` |
| `chartmuseum.resources` | [resources](https://kubernetes.io/docs/concepts/configuration/manage-compute-resources-container/) to allocate for container | undefined |
| `chartmuseum.volumes` | used to create PVCs if persistence is enabled (see instructions in values.yaml) | see values.yaml |
| `chartmuseum.nodeSelector` | Node labels for pod assignment | `{}` |
| `chartmuseum.tolerations` | Tolerations for pod assignment | `[]` |
| `chartmuseum.affinity` | Node/Pod affinities | `{}` |
| **Clair** |
| `clair.enabled` | Enable Clair? | `true` |
| `clair.image.repository` | Repository for clair image | `vmware/clair-photon` |
| `clair.image.tag` | Tag for clair image | `v2.0.1-v1.4.0`
| `clair.image.tag` | Tag for clair image | `dev`
| `clair.resources` | [resources](https://kubernetes.io/docs/concepts/configuration/manage-compute-resources-container/) to allocate for container | undefined
| `clair.nodeSelector` | Node labels for pod assignment | `{}` |
| `clair.tolerations` | Tolerations for pod assignment | `[]` |
| `clair.affinity` | Node/Pod affinities | `{}` |
| `postgresql` | Overrides for postgresql chart [values.yaml](https://github.com/kubernetes/charts/blob/f2938a46e3ae8e2512ede1142465004094c3c333/stable/postgresql/values.yaml) | see values.yaml
| **Redis** |
| `redis.usePassword` | Whether use password | `false` |
| `redis.password` | The password for Redis | `changeit` |
| `redis.cluster.enabled` | Enable Redis cluster | `false` |
| `redis.master.persistence.enabled` | Persistent data | `false` |
| `redis.external.enabled` | If an external Redis is used, set it to `true` | `false` |
| `redis.external.host` | The hostname of external Redis | `192.168.0.2` |
| `redis.external.port` | The port of external Redis | `6379` |
| `redis.external.databaseIndex` | The database index of external Redis | `0` |
| `redis.external.usePassword` | Whether use password for external Redis | `false` |
| `redis.external.password` | The password of external Redis | `changeit` |
| **Notary** |
| `notary.enabled` | Enable Notary? | `true` |
| `notary.server.image.repository` | Repository for notary server image | `vmware/notary-server-photon` |
| `notary.server.image.tag` | Tag for notary server image | `v0.5.1-v1.4.0`
| `notary.server.image.tag` | Tag for notary server image | `dev`
| `notary.signer.image.repository` | Repository for notary signer image | `vmware/notary-signer-photon` |
| `notary.signer.image.tag` | Tag for notary signer image | `v0.5.1-v1.4.0`
| `notary.db.image.repository` | Repository for notary database image | `vmware/mariadb-photon` |
| `notary.db.image.tag` | Tag for notary database image | `v1.4.0`
| `notary.db.password` | The password of users for notary database | Specify your own password |
| `notary.signer.image.tag` | Tag for notary signer image | `dev`
| `notary.nodeSelector` | Node labels for pod assignment | `{}` |
| `notary.tolerations` | Tolerations for pod assignment | `[]` |
| `notary.affinity` | Node/Pod affinities | `{}` |
| **Ingress** |
| `ingress.enabled` | Enable ingress objects. | `true` |
Specify each parameter using the `--set key=value[,key=value]` argument to `helm install`. For example:
```bash
helm install . --name my-release --set externalDomain=harbor.<IP>.xip.io
```
Alternatively, a YAML file that specifies the values for the parameters can be provided while installing the chart. For example,
```bash
helm install . --name my-release -f /path/to/values.yaml
```
> **Tip**: You can use the default [values.yaml](values.yaml)
## Persistence
Harbor stores the data and configurations in emptyDir volumes. You can change the values.yaml to enable persistence and use a PersistentVolumeClaim instead.
> *"An emptyDir volume is first created when a Pod is assigned to a Node, and exists as long as that Pod is running on that node. When a Pod is removed from a node for any reason, the data in the emptyDir is deleted forever."*
TBD

View File

@ -52,7 +52,7 @@ harborImageTag: &harbor_image_tag dev
adminserver:
image:
repository: vmware/harbor-adminserver
repository: goharbor/harbor-adminserver
tag: *harbor_image_tag
pullPolicy: IfNotPresent
volumes:
@ -70,7 +70,7 @@ adminserver:
jobservice:
image:
repository: vmware/harbor-jobservice
repository: goharbor/harbor-jobservice
tag: *harbor_image_tag
pullPolicy: IfNotPresent
secret: not-a-secure-secret
@ -85,7 +85,7 @@ jobservice:
ui:
image:
repository: vmware/harbor-ui
repository: goharbor/harbor-ui
tag: *harbor_image_tag
pullPolicy: IfNotPresent
secret: not-a-secure-secret
@ -104,7 +104,7 @@ database:
type: internal
internal:
image:
repository: vmware/harbor-db
repository: goharbor/harbor-db
tag: *harbor_image_tag
pullPolicy: IfNotPresent
# the superuser password of database
@ -133,7 +133,7 @@ database:
registry:
image:
repository: vmware/registry-photon
repository: goharbor/registry-photon
tag: dev
pullPolicy: IfNotPresent
httpSecret: not-a-secure-secret
@ -217,7 +217,7 @@ registry:
chartmuseum:
enabled: true
image:
repository: vmware/chartmuseum-photon
repository: goharbor/chartmuseum-photon
tag: dev
pullPolicy: IfNotPresent
volumes:
@ -236,7 +236,7 @@ chartmuseum:
clair:
enabled: true
image:
repository: vmware/clair-photon
repository: goharbor/clair-photon
tag: dev
pullPolicy: IfNotPresent
volumes:
@ -277,12 +277,12 @@ notary:
enabled: true
server:
image:
repository: vmware/notary-server-photon
repository: goharbor/notary-server-photon
tag: dev
pullPolicy: IfNotPresent
signer:
image:
repository: vmware/notary-signer-photon
repository: goharbor/notary-signer-photon
tag: dev
pullPolicy: IfNotPresent
env:

View File

@ -18,7 +18,6 @@ worker_pool:
#Additional config if use 'redis' backend
redis_pool:
#redis://[arbitrary_username:password@]ipaddress:port/database_index
#or ipaddress:port[,weight,password,database_index]
redis_url: $redis_url
namespace: "harbor_job_service_namespace"
#Logger for job

View File

@ -13,8 +13,9 @@ storage:
delete:
enabled: true
redis:
addr: $redis_url
db: 1
addr: $redis_host:$redis_port
password: $redis_password
db: $redis_db_index_reg
http:
addr: :5000
secret: placeholder

View File

@ -13,8 +13,9 @@ storage:
delete:
enabled: true
redis:
addr: $redis_url
db: 1
addr: $redis_host:$redis_port
password: $redis_password
db: $redis_db_index_reg
http:
addr: :5000
secret: placeholder

View File

@ -5,6 +5,6 @@ JOBSERVICE_SECRET=$jobservice_secret
GODEBUG=netdns=cgo
ADMINSERVER_URL=$adminserver_url
UAA_CA_ROOT=/etc/ui/certificates/uaa_ca.pem
_REDIS_URL=$redis_url
_REDIS_URL=$redis_host:$redis_port,100,$redis_password
SYNC_REGISTRY=false
CHART_CACHE_DRIVER=$chart_cache_driver

View File

@ -12,7 +12,7 @@ services:
- redis
chartmuseum:
container_name: chartmuseum
image: vmware/chartmuseum-photon:__chartmuseum_version__
image: goharbor/chartmuseum-photon:__chartmuseum_version__
restart: always
networks:
- harbor-chartmuseum

View File

@ -20,7 +20,7 @@ services:
networks:
- harbor-clair
container_name: clair
image: vmware/clair-photon:__clair_version__
image: goharbor/clair-photon:__clair_version__
restart: always
cpu_quota: 50000
depends_on:

View File

@ -12,7 +12,7 @@ services:
aliases:
- harbor-db
notary-server:
image: vmware/notary-server-photon:__notary_version__
image: goharbor/notary-server-photon:__notary_version__
container_name: notary-server
restart: always
networks:
@ -31,7 +31,7 @@ services:
syslog-address: "tcp://127.0.0.1:1514"
tag: "notary-server"
notary-signer:
image: vmware/notary-signer-photon:__notary_version__
image: goharbor/notary-signer-photon:__notary_version__
container_name: notary-signer
restart: always
networks:

View File

@ -1,7 +1,7 @@
version: '2'
services:
log:
image: vmware/harbor-log:__version__
image: goharbor/harbor-log:__version__
container_name: harbor-log
restart: always
volumes:
@ -12,7 +12,7 @@ services:
networks:
- harbor
registry:
image: vmware/registry-photon:__reg_version__
image: goharbor/registry-photon:__reg_version__
container_name: registry
restart: always
volumes:
@ -30,7 +30,7 @@ services:
syslog-address: "tcp://127.0.0.1:1514"
tag: "registry"
registryctl:
image: vmware/harbor-registryctl:__version__
image: goharbor/harbor-registryctl:__version__
container_name: registryctl
env_file:
- ./common/config/registryctl/env
@ -51,7 +51,7 @@ services:
syslog-address: "tcp://127.0.0.1:1514"
tag: "registryctl"
postgresql:
image: vmware/harbor-db:__version__
image: goharbor/harbor-db:__version__
container_name: harbor-db
restart: always
volumes:
@ -68,7 +68,7 @@ services:
syslog-address: "tcp://127.0.0.1:1514"
tag: "postgresql"
adminserver:
image: vmware/harbor-adminserver:__version__
image: goharbor/harbor-adminserver:__version__
container_name: harbor-adminserver
env_file:
- ./common/config/adminserver/env
@ -87,7 +87,7 @@ services:
syslog-address: "tcp://127.0.0.1:1514"
tag: "adminserver"
ui:
image: vmware/harbor-ui:__version__
image: goharbor/harbor-ui:__version__
container_name: harbor-ui
env_file:
- ./common/config/ui/env
@ -111,7 +111,7 @@ services:
syslog-address: "tcp://127.0.0.1:1514"
tag: "ui"
jobservice:
image: vmware/harbor-jobservice:__version__
image: goharbor/harbor-jobservice:__version__
container_name: harbor-jobservice
env_file:
- ./common/config/jobservice/env
@ -131,7 +131,7 @@ services:
syslog-address: "tcp://127.0.0.1:1514"
tag: "jobservice"
redis:
image: vmware/redis-photon:__redis_version__
image: goharbor/redis-photon:__redis_version__
container_name: redis
restart: always
volumes:
@ -146,7 +146,7 @@ services:
syslog-address: "tcp://127.0.0.1:1514"
tag: "redis"
proxy:
image: vmware/nginx-photon:__nginx_version__
image: goharbor/nginx-photon:__nginx_version__
container_name: nginx
restart: always
volumes:

View File

@ -15,7 +15,7 @@ services:
networks:
- harbor-clair
container_name: clair
image: vmware/clair-photon:__clair_version__
image: goharbor/clair-photon:__clair_version__
restart: always
cpu_quota: 150000
depends_on:

View File

@ -1,7 +1,7 @@
version: '2'
services:
log:
image: vmware/harbor-log:__version__
image: goharbor/harbor-log:__version__
container_name: harbor-log
restart: always
volumes:
@ -12,7 +12,7 @@ services:
networks:
- harbor
registry:
image: vmware/registry-photon:__reg_version__
image: goharbor/registry-photon:__reg_version__
container_name: registry
restart: always
volumes:
@ -32,7 +32,7 @@ services:
syslog-address: "tcp://127.0.0.1:1514"
tag: "registry"
adminserver:
image: vmware/harbor-adminserver:__version__
image: goharbor/harbor-adminserver:__version__
container_name: harbor-adminserver
env_file:
- ./common/config/adminserver/env
@ -51,7 +51,7 @@ services:
syslog-address: "tcp://127.0.0.1:1514"
tag: "adminserver"
ui:
image: vmware/harbor-ui:__version__
image: goharbor/harbor-ui:__version__
container_name: harbor-ui
env_file:
- ./common/config/ui/env
@ -75,7 +75,7 @@ services:
syslog-address: "tcp://127.0.0.1:1514"
tag: "ui"
jobservice:
image: vmware/harbor-jobservice:__version__
image: goharbor/harbor-jobservice:__version__
container_name: harbor-jobservice
env_file:
- ./common/config/jobservice/env
@ -95,7 +95,7 @@ services:
syslog-address: "tcp://127.0.0.1:1514"
tag: "jobservice"
proxy:
image: vmware/nginx-photon:__nginx_version__
image: goharbor/nginx-photon:__nginx_version__
container_name: nginx
restart: always
volumes:

View File

@ -140,9 +140,23 @@ db_user = postgres
##### End of Harbor DB configuration#######
#The redis server address. Only needed in HA installation.
#address:port[,weight,password,db_index]
redis_url = redis:6379
##########Redis server configuration.############
#Redis connection address
redis_host = redis
#Redis connection port
redis_port = 6379
#Redis connection password
redis_password =
#Redis connection db index
#db_index 1,2,3 is for registry, jobservice and chartmuseum.
#db_index 0 is for UI, it's unchangeable
redis_db_index = 1,2,3
##########Redis server configuration.############
##########Clair DB configuration############

View File

@ -51,7 +51,8 @@ set +o noglob
usage=$'Please set hostname and other necessary attributes in harbor.cfg first. DO NOT use localhost or 127.0.0.1 for hostname, because Harbor needs to be accessed by external clients.
Please set --with-notary if needs enable Notary in Harbor, and set ui_url_protocol/ssl_cert/ssl_cert_key in harbor.cfg bacause notary must run under https.
Please set --with-clair if needs enable Clair in Harbor'
Please set --with-clair if needs enable Clair in Harbor
Please set --with-chartmuseum if needs enable Chartmuseum in Harbor'
item=0
# notary is not enabled by default
@ -235,5 +236,5 @@ echo ""
success $"----Harbor has been installed and started successfully.----
Now you should be able to visit the admin portal at ${protocol}://${hostname}.
For more details, please visit https://github.com/vmware/harbor .
For more details, please visit https://github.com/goharbor/harbor .
"

View File

@ -37,57 +37,57 @@ DOCKERFILEPATH=$(MAKEPATH)/photon
DOCKERFILEPATH_ADMINSERVER=$(DOCKERFILEPATH)/adminserver
DOCKERFILENAME_ADMINSERVER=Dockerfile
DOCKERIMAGENAME_ADMINSERVER=vmware/harbor-adminserver
DOCKERIMAGENAME_ADMINSERVER=goharbor/harbor-adminserver
DOCKERFILEPATH_UI=$(DOCKERFILEPATH)/ui
DOCKERFILENAME_UI=Dockerfile
DOCKERIMAGENAME_UI=vmware/harbor-ui
DOCKERIMAGENAME_UI=goharbor/harbor-ui
DOCKERFILEPATH_JOBSERVICE=$(DOCKERFILEPATH)/jobservice
DOCKERFILENAME_JOBSERVICE=Dockerfile
DOCKERIMAGENAME_JOBSERVICE=vmware/harbor-jobservice
DOCKERIMAGENAME_JOBSERVICE=goharbor/harbor-jobservice
DOCKERFILEPATH_LOG=$(DOCKERFILEPATH)/log
DOCKERFILENAME_LOG=Dockerfile
DOCKERIMAGENAME_LOG=vmware/harbor-log
DOCKERIMAGENAME_LOG=goharbor/harbor-log
DOCKERFILEPATH_DB=$(DOCKERFILEPATH)/db
DOCKERFILENAME_DB=Dockerfile
DOCKERIMAGENAME_DB=vmware/harbor-db
DOCKERIMAGENAME_DB=goharbor/harbor-db
DOCKERFILEPATH_POSTGRESQL=$(DOCKERFILEPATH)/postgresql
DOCKERFILENAME_POSTGRESQL=Dockerfile
DOCKERIMAGENAME_POSTGRESQL=vmware/postgresql-photon
DOCKERIMAGENAME_POSTGRESQL=goharbor/postgresql-photon
DOCKERFILEPATH_CLAIR=$(DOCKERFILEPATH)/clair
DOCKERFILENAME_CLAIR=Dockerfile
DOCKERIMAGENAME_CLAIR=vmware/clair-photon
DOCKERIMAGENAME_CLAIR=goharbor/clair-photon
DOCKERFILEPATH_NGINX=$(DOCKERFILEPATH)/nginx
DOCKERFILENAME_NGINX=Dockerfile
DOCKERIMAGENAME_NGINX=vmware/nginx-photon
DOCKERIMAGENAME_NGINX=goharbor/nginx-photon
DOCKERFILEPATH_REG=$(DOCKERFILEPATH)/registry
DOCKERFILENAME_REG=Dockerfile
DOCKERIMAGENAME_REG=vmware/registry-photon
DOCKERIMAGENAME_REG=goharbor/registry-photon
DOCKERFILEPATH_REGISTRYCTL=$(DOCKERFILEPATH)/registryctl
DOCKERFILENAME_REGISTRYCTL=Dockerfile
DOCKERIMAGENAME_REGISTRYCTL=vmware/harbor-registryctl
DOCKERIMAGENAME_REGISTRYCTL=goharbor/harbor-registryctl
DOCKERFILEPATH_NOTARY=$(DOCKERFILEPATH)/notary
DOCKERFILENAME_NOTARYSIGNER=signer.Dockerfile
DOCKERIMAGENAME_NOTARYSIGNER=vmware/notary-signer-photon
DOCKERIMAGENAME_NOTARYSIGNER=goharbor/notary-signer-photon
DOCKERFILENAME_NOTARYSERVER=server.Dockerfile
DOCKERIMAGENAME_NOTARYSERVER=vmware/notary-server-photon
DOCKERIMAGENAME_NOTARYSERVER=goharbor/notary-server-photon
DOCKERFILEPATH_REDIS=$(DOCKERFILEPATH)/redis
DOCKERFILENAME_REDIS=Dockerfile
DOCKERIMAGENAME_REDIS=vmware/redis-photon
DOCKERIMAGENAME_REDIS=goharbor/redis-photon
DOCKERFILEPATH_MIGRATOR=$(TOOLSPATH)/migration
DOCKERFILENAME_MIGRATOR=Dockerfile
DOCKERIMAGENAME_MIGRATOR=vmware/harbor-migrator
DOCKERIMAGENAME_MIGRATOR=goharbor/harbor-migrator
# for chart server (chartmuseum)
DOCKERFILEPATH_CHART_SERVER=$(DOCKERFILEPATH)/chartserver

View File

@ -2,7 +2,7 @@ FROM photon:1.0
MAINTAINER wangyan@vmware.com
RUN tdnf distro-sync -y || echo \
RUN tdnf distro-sync -y \
&& tdnf erase vim -y \
&& tdnf install sudo -y >> /dev/null\
&& tdnf clean all \

View File

@ -21,7 +21,8 @@ if sys.version_info[:3][0] == 3:
DATA_VOL = "/data"
def validate(conf, args):
def validate(conf, args):
if args.ha_mode:
db_host = rcp.get("configuration", "db_host")
if db_host == "mysql":
@ -32,9 +33,6 @@ def validate(conf, args):
msg = 'Is the Harbor Docker Registry configured to use shared storage (e.g. NFS, Ceph etc.)? [yes/no]:'
if raw_input(msg).lower() != "yes":
raise Exception("Error: In HA mode, shared storage configuration for Docker Registry in harbor.cfg is required. Refer to HA installation guide for details.")
redis_url = rcp.get("configuration", "redis_url")
if redis_url is None or len(redis_url) < 1:
raise Exception("Error: In HA mode, redis_url in harbor.cfg needs to point to a Redis cluster.")
if args.notary_mode:
raise Exception("Error: HA mode doesn't support Notary currently")
if args.clair_mode:
@ -80,6 +78,18 @@ def validate(conf, args):
if storage_provider_config == "":
raise Exception("Error: no provider configurations are provided for provider %s" % storage_provider_name)
redis_host = rcp.get("configuration", "redis_host")
if redis_host is None or len(redis_host) < 1:
raise Exception("Error: redis_host in harbor.cfg needs to point to an endpoint of Redis server or cluster.")
redis_port = rcp.get("configuration", "redis_port")
if len(redis_port) < 1:
raise Exception("Error: redis_port in harbor.cfg needs to point to the port of Redis server or cluster.")
redis_db_index = rcp.get("configuration", "redis_db_index").strip()
if len(redis_db_index.split(",")) != 3:
raise Exception("Error invalid value for redis_db_index: %s. please set it as 1,2,3" % redis_db_index)
#To meet security requirement
#By default it will change file mode to 0600, and make the owner of the file to 10000:10000
def mark_file(path, mode=0o600, uid=10000, gid=10000):
@ -282,10 +292,22 @@ secret_key = get_secret_key(secretkey_path)
log_rotate_count = rcp.get("configuration", "log_rotate_count")
log_rotate_size = rcp.get("configuration", "log_rotate_size")
if rcp.has_option("configuration", "redis_url"):
redis_url = rcp.get("configuration", "redis_url")
redis_host = rcp.get("configuration", "redis_host")
redis_port = rcp.get("configuration", "redis_port")
redis_password = rcp.get("configuration", "redis_password")
redis_db_index = rcp.get("configuration", "redis_db_index")
db_indexs = redis_db_index.split(',')
redis_db_index_reg = db_indexs[0]
redis_db_index_js = db_indexs[1]
redis_db_index_chart = db_indexs[2]
#redis://[arbitrary_username:password@]ipaddress:port/database_index
redis_url_js = ''
if len(redis_password) > 0:
redis_url_js = "redis://anonymous:%s@%s:%s/%s" % (redis_password, redis_host, redis_port, redis_db_index_js)
else:
redis_url = ""
redis_url_js = "redis://%s:%s/%s" % (redis_host, redis_port, redis_db_index_js)
if rcp.has_option("configuration", "skip_reload_env_pattern"):
skip_reload_env_pattern = rcp.get("configuration", "skip_reload_env_pattern")
@ -430,14 +452,16 @@ render(os.path.join(templates_dir, "adminserver", "env"),
# set cache for chart repo server
# default set 'memory' mode, if redis is configured then set to 'redis'
chart_cache_driver = "memory"
if len(redis_url) > 0:
if len(redis_host) > 0:
chart_cache_driver = "redis"
render(os.path.join(templates_dir, "ui", "env"),
ui_conf_env,
ui_secret=ui_secret,
jobservice_secret=jobservice_secret,
redis_url = redis_url,
redis_host=redis_host,
redis_port=redis_port,
redis_password=redis_password,
adminserver_url = adminserver_url,
chart_cache_driver = chart_cache_driver
)
@ -459,14 +483,20 @@ render(os.path.join(templates_dir, "registry", registry_config_file_ha),
storage_provider_info=storage_provider_info,
public_url=public_url,
ui_url=ui_url,
redis_url=redis_url)
redis_host=redis_host,
redis_port=redis_port,
redis_password=redis_password,
redis_db_index_reg=redis_db_index_reg)
render(os.path.join(templates_dir, "registry", registry_config_file),
registry_conf,
storage_provider_info=storage_provider_info,
public_url=public_url,
ui_url=ui_url,
redis_url=redis_url)
redis_host=redis_host,
redis_port=redis_port,
redis_password=redis_password,
redis_db_index_reg=redis_db_index_reg)
render(os.path.join(templates_dir, "db", "env"),
db_conf_env,
@ -481,8 +511,8 @@ render(os.path.join(templates_dir, "jobservice", "env"),
render(os.path.join(templates_dir, "jobservice", "config.yml"),
jobservice_conf,
max_job_workers=max_job_workers,
redis_url=redis_url)
redis_url=redis_url_js)
render(os.path.join(templates_dir, "log", "logrotate.conf"),
log_rotate_config,
log_rotate_count=log_rotate_count,
@ -580,8 +610,8 @@ if args.notary_mode:
temp_cert_dir = os.path.join(base_dir, "cert_tmp")
if not os.path.exists(temp_cert_dir):
os.makedirs(temp_cert_dir)
ca_subj = "/C=US/ST=California/L=Palo Alto/O=VMware, Inc./OU=Harbor/CN=Self-signed by VMware, Inc."
cert_subj = "/C=US/ST=California/L=Palo Alto/O=VMware, Inc./OU=Harbor/CN=notarysigner"
ca_subj = "/C=US/ST=California/L=Palo Alto/O=GoHarbor/OU=Harbor/CN=Self-signed by GoHarbor"
cert_subj = "/C=US/ST=California/L=Palo Alto/O=GoHarbor/OU=Harbor/CN=notarysigner"
signer_ca_cert = os.path.join(temp_cert_dir, "notary-signer-ca.crt")
signer_ca_key = os.path.join(temp_cert_dir, "notary-signer-ca.key")
signer_cert_path = os.path.join(temp_cert_dir, "notary-signer.crt")
@ -669,23 +699,10 @@ if args.chart_mode:
os.makedirs(chartm_config_dir)
# process redis info
cache_store = ""
cache_redis_password = ""
cache_redis_addr = ""
cache_redis_db_index = 0
if redis_url and redis_url.strip():
cache_store = "redis"
segments = redis_url.split(',', 3)
for index, r_cfg in enumerate(segments):
# the addr:port
if index == 0:
cache_redis_addr = r_cfg
# the password if existing
elif index == 2:
cache_redis_password = r_cfg
# the database index if existing
elif index == 3:
cache_redis_db_index = r_cfg
cache_store = "redis"
cache_redis_password = redis_password
cache_redis_addr = redis_host+":"+redis_port
cache_redis_db_index = redis_db_index_chart
# process storage info
#default using local file system

View File

@ -203,7 +203,7 @@ func TestAuthenticateWithoutAdmin(t *testing.T) {
var person models.AuthModel
var authHelper *Auth
person.Principal = "user001"
person.Password = "zhu88jie"
person.Password = "Test1@34"
user, err := authHelper.Authenticate(person)
if err != nil {
t.Errorf("unexpected ldap authenticate fail: %v", err)

View File

@ -21,11 +21,11 @@ import {
EventEmitter,
Output
} from "@angular/core";
import {Filter, ReplicationRule, Endpoint, Label} from "../service/interface";
import { Filter, ReplicationRule, Endpoint, Label } from "../service/interface";
import { Subject } from "rxjs/Subject";
import { Subscription } from "rxjs/Subscription";
import { FormArray, FormBuilder, FormGroup, Validators } from "@angular/forms";
import {clone, compareValue, isEmptyObject, toPromise} from "../utils";
import { clone, compareValue, isEmptyObject, toPromise } from "../utils";
import { InlineAlertComponent } from "../inline-alert/inline-alert.component";
import { ReplicationService } from "../service/replication.service";
import { ErrorHandler } from "../error-handler/error-handler";
@ -33,7 +33,7 @@ import { TranslateService } from "@ngx-translate/core";
import { EndpointService } from "../service/endpoint.service";
import { ProjectService } from "../service/project.service";
import { Project } from "../project-policy-config/project";
import {LabelState} from "../tag/tag.component";
import { LabelState } from "../tag/tag.component";
const ONE_HOUR_SECONDS = 3600;
const ONE_DAY_SECONDS: number = 24 * ONE_HOUR_SECONDS;
@ -165,19 +165,19 @@ export class CreateEditRuleComponent implements OnInit, OnDestroy {
if (this.isRuleNameValid) {
this.inNameChecking = true;
toPromise<ReplicationRule[]>(
this.repService.getReplicationRules(0, ruleName)
this.repService.getReplicationRules(0, ruleName)
)
.then(response => {
if (response.some(rule => rule.name === ruleName)) {
this.ruleNameTooltip = "TOOLTIP.RULE_USER_EXISTING";
this.isRuleNameValid = false;
}
this.inNameChecking = false;
})
.catch(() => {
this.inNameChecking = false;
});
}else {
.then(response => {
if (response.some(rule => rule.name === ruleName)) {
this.ruleNameTooltip = "TOOLTIP.RULE_USER_EXISTING";
this.isRuleNameValid = false;
}
this.inNameChecking = false;
})
.catch(() => {
this.inNameChecking = false;
});
} else {
this.ruleNameTooltip = "REPLICATION.NAME_TOOLTIP";
}
}
@ -336,11 +336,11 @@ export class CreateEditRuleComponent implements OnInit, OnDestroy {
// delete api return label info, replace with label count
if (delLabel || count) {
let len = filterLabels.length;
for (let i = 0 ; i < len; i ++) {
for (let i = 0; i < len; i++) {
let lab = filterLabels.find(data => data.kind === this.filterSelect[2]);
if (lab) {filterLabels.splice(filterLabels.indexOf(lab), 1); }
}
filterLabels.push({kind: 'label', value: count + ' labels'});
if (lab) { filterLabels.splice(filterLabels.indexOf(lab), 1); }
}
filterLabels.push({ kind: 'label', value: count + ' labels' });
this.labelInputVal = count.toString();
}
}
@ -386,7 +386,7 @@ export class CreateEditRuleComponent implements OnInit, OnDestroy {
let name: string = $event.target.name;
let value: string = $event.target["value"];
const controlArray = <FormArray> this.ruleForm.get('filters');
const controlArray = <FormArray>this.ruleForm.get('filters');
this.filterListData.forEach((data, index) => {
if (index === +id) {
data.name = $event.target.name = value;
@ -425,7 +425,7 @@ export class CreateEditRuleComponent implements OnInit, OnDestroy {
this.filterListData.forEach((data, index) => {
if (index === indexId) {
data.isOpen = true;
}else {
} else {
data.isOpen = false;
}
});
@ -487,7 +487,7 @@ export class CreateEditRuleComponent implements OnInit, OnDestroy {
}
addNewFilter(): void {
const controlArray = <FormArray> this.ruleForm.get('filters');
const controlArray = <FormArray>this.ruleForm.get('filters');
if (this.filterCount === 0) {
this.filterListData.push(
this.baseFilterData(
@ -537,7 +537,8 @@ export class CreateEditRuleComponent implements OnInit, OnDestroy {
}
const control = <FormArray>this.ruleForm.get('filters');
if (control.controls[i].get('kind').value === this.filterSelect[2]) {
this.labelInputVal = control.controls[i].get('value').value.split(' ')[0];
this.filterLabelInfo = [];
this.labelInputVal = "";
}
control.removeAt(i);
this.setFilter(control.value);
@ -610,7 +611,7 @@ export class CreateEditRuleComponent implements OnInit, OnDestroy {
selectedLabelList(selectedLabels: LabelState[], indexId: number) {
// set input value of filter label
const controlArray = <FormArray> this.ruleForm.get('filters');
const controlArray = <FormArray>this.ruleForm.get('filters');
this.filterListData.forEach((data, index) => {
if (data.name === this.filterSelect[2]) {
@ -618,7 +619,7 @@ export class CreateEditRuleComponent implements OnInit, OnDestroy {
if (labelsLength > 0) {
controlArray.controls[index].get('value').setValue(labelsLength + ' labels');
this.labelInputVal = labelsLength.toString();
}else {
} else {
controlArray.controls[index].get('value').setValue('');
}
};
@ -688,14 +689,14 @@ export class CreateEditRuleComponent implements OnInit, OnDestroy {
filters.splice(filters.indexOf(labels), 1);
let info: any[] = [];
this.filterLabelInfo.forEach(data => {
info.push({kind: 'label', value: data.id});
info.push({ kind: 'label', value: data.id });
});
filters.push.apply(filters, info);
}
}
public hasFormChange(): boolean {
return !isEmptyObject(this.getChanges());
return !isEmptyObject(this.hasChanges());
}
onSubmit() {
@ -884,55 +885,29 @@ export class CreateEditRuleComponent implements OnInit, OnDestroy {
return utcTimes;
}
getChanges(): { [key: string]: any | any[] } {
let changes: { [key: string]: any | any[] } = {};
let ruleValue: { [key: string]: any | any[] } = clone(this.ruleForm.value);
if (ruleValue.filters && ruleValue.filters.length) {
ruleValue.filters.forEach((data, index) => {
hasChanges(): boolean {
let formValue = clone(this.ruleForm.value);
let initValue = clone(this.copyUpdateForm);
let initValueCopy: any = {};
for (let key of Object.keys(formValue)) {
initValueCopy[key] = initValue[key];
}
if (formValue.filters && formValue.filters.length > 0) {
formValue.filters.forEach((data, index) => {
if (data.kind === this.filterSelect[2]) {
ruleValue.filters.splice(index, 1);
formValue.filters.splice(index, 1);
}
});
// rewrite filter label
this.filterLabelInfo.forEach(data => {
ruleValue.filters.push({kind: "label", pattern: "", value: data});
formValue.filters.push({ kind: "label", pattern: "", value: data });
});
}
if (!ruleValue || !this.copyUpdateForm) {
return changes;
if (!compareValue(formValue, initValueCopy)) {
return true;
}
for (let prop of Object.keys(ruleValue)) {
let field: any = this.copyUpdateForm[prop];
if (!compareValue(field, ruleValue[prop])) {
if (
ruleValue[prop][0] &&
ruleValue[prop][0].project_id &&
ruleValue[prop][0].project_id === field[0].project_id
) {
break;
}
if (
ruleValue[prop][0] &&
ruleValue[prop][0].id &&
ruleValue[prop][0].id === field[0].id
) {
break;
}
changes[prop] = ruleValue[prop];
// Number
if (typeof field === "number") {
changes[prop] = +changes[prop];
}
// Trim string value
if (typeof field === "string") {
changes[prop] = ("" + changes[prop]).trim();
}
}
}
return changes;
return false;
}
}

View File

@ -117,7 +117,8 @@
<td class="left">
<span class="content-icon">
<clr-icon shape="shield-check" class="is-success"></clr-icon>
</span>&nbsp;<a (click)="downloadChart()">{{'HELM_CHART.READY' | translate }}</a></td>
</span>&nbsp;<a href="javascript:void(0)" (click)="downloadChart()">{{'HELM_CHART.READY' | translate }}</a>
</td>
</ng-template>
<ng-template #unsignedContent>
<td class="left">

View File

@ -26,9 +26,9 @@ export class ChartDetailSummaryComponent implements OnInit {
@Input() readme: string;
copiedCMD = '';
addCMD = `helm repo add --ca-file <ca file> --cert-file <cert file> --key-file <key file> --username <username> --password <password> <repo name> ${this.repoURL}/chartrepo/${this.projectName}`;
installCMD = `helm install --ca-file <ca file> --cert-file <cert file> --key-file <key file> --username=<username> --password=<password> --version ${this.chartVersion} <repo name>/${this.chartName}`;
verifyCMD = `helm verify --keyring <key path> ${this.chartName}-${this.chartVersion}.tgz`;
addCMD: string;
installCMD: string;
verifyCMD: string;
constructor(
private errorHandler: ErrorHandler,
@ -36,6 +36,9 @@ export class ChartDetailSummaryComponent implements OnInit {
) {}
ngOnInit(): void {
this.addCMD = `helm repo add --ca-file <ca file> --cert-file <cert file> --key-file <key file> --username <username> --password <password> <repo name> ${this.repoURL}/chartrepo/${this.projectName}`;
this.installCMD = `helm install --ca-file <ca file> --cert-file <cert file> --key-file <key file> --username=<username> --password=<password> --version ${this.chartVersion} <repo name>/${this.chartName}`;
this.verifyCMD = `helm verify --keyring <key path> ${this.chartName}-${this.chartVersion}.tgz`;
}
isCopied(cmd: string) {

View File

@ -28,7 +28,8 @@
<clr-icon shape="upload" size="16"></clr-icon>&nbsp;{{'HELM_CHART.UPLOAD' | translate}}
</button>
</clr-dg-action-bar>
<clr-dg-column [clrDgField]="'name'">{{'HELM_CHART.NAME' | translate}}</clr-dg-column>
<clr-dg-column >{{'HELM_CHART.NAME' | translate}}</clr-dg-column>
<clr-dg-column >{{'HELM_CHART.STATUS' | translate}}</clr-dg-column>
<clr-dg-column>{{'HELM_CHART.CHARTVERSIONS' | translate}}</clr-dg-column>
<clr-dg-column>{{'HELM_CHART.CREATED' | translate}}</clr-dg-column>
<clr-dg-placeholder>{{'HELM_CHART.PLACEHOLDER' | translate }}</clr-dg-placeholder>
@ -39,6 +40,7 @@
</span>
<a href="javascript:void(0)" (click)="onChartClick(chart)">{{ chart.name }}</a>
</clr-dg-cell>
<clr-dg-cell>{{ getStatusString(chart) | translate }}</clr-dg-cell>
<clr-dg-cell>{{ chart.total_versions }}</clr-dg-cell>
<clr-dg-cell>{{ chart.created | date }}</clr-dg-cell>
</clr-dg-row>
@ -51,7 +53,7 @@
</div>
</div>
<div *ngIf="isCardView" class="row card-container">
<div *ngFor="let item of charts;" class="col-lg-2 col-md-5 col-sm-5 col-xs-6">
<div *ngFor="let item of charts;" class="col-xl-2 col-lg-3 col-md-4 col-sm-6 col-xs-12">
<a let i=index; class="card clickable" (click)="onChartClick(item)">
<div class="card-header">
<div class="card-icon">
@ -60,10 +62,18 @@
<div class="card-title">{{item.name}}</div>
</div>
<div class="card-footer">
<div class="form-group">
<span class="version-text">{{item.total_versions}}</span>
<label *ngIf="item.total_versions !== 1">{{'HELM_CHART.CHARTVERSIONS' | translate}}</label>
<label *ngIf="item.total_versions === 1">{{'HELM_CHART.VERSION' | translate}}</label>
<div class="row flex-items-xs-between">
<div class="col-xs-6">
<span class="version-text">{{item.total_versions}}</span>
<label *ngIf="item.total_versions !== 1">{{'HELM_CHART.CHARTVERSIONS' | translate}}</label>
<label *ngIf="item.total_versions === 1">{{'HELM_CHART.VERSION' | translate}}</label>
</div>
<div class="col-xs-6">
<span class="label"
[class.label-danger]="item.deprecated"
[class.label-success]="!item.deprecated"
>{{getStatusString(item) | translate}}</span>
</div>
</div>
</div>
</a>

View File

@ -178,4 +178,12 @@ export class HelmChartComponent implements OnInit {
getDefaultIcon(chart: HelmChartItem) {
chart.icon = this.chartDefaultIcon;
}
getStatusString(chart: HelmChartItem) {
if (chart.deprecated) {
return "HELM_CHART.DEPRECATED";
} else {
return "HELM_CHART.ACTIVE";
}
}
}

View File

@ -50,8 +50,10 @@
(click)="openVersionDeleteModal(selectedRows)">
<clr-icon shape="times" size="16"></clr-icon>&nbsp;{{'BUTTON.DELETE' | translate}}</button>
</clr-dg-action-bar>
<clr-dg-column [clrDgField]="'name'">{{'HELM_CHART.VERSION' | translate}}</clr-dg-column>
<clr-dg-column>{{'HELM_CHART.VERSION' | translate}}</clr-dg-column>
<clr-dg-column>{{'HELM_CHART.STATUS' | translate }}</clr-dg-column>
<clr-dg-column>{{'HELM_CHART.ENGINE' | translate }}</clr-dg-column>
<clr-dg-column>{{'HELM_CHART.MAINTAINERS' | translate }}</clr-dg-column>
<clr-dg-column>{{'HELM_CHART.CREATED' | translate }}</clr-dg-column>
<clr-dg-placeholder>{{'HELM_CHART.NO_VERSION_PLACEHOLDER' | translate }}</clr-dg-placeholder>
@ -62,6 +64,7 @@
</span>
<a href="javascript:void(0)" (click)="onVersionClick(v)">{{ v.version }}</a>
</clr-dg-cell>
<clr-dg-cell>{{ getStatusString(v) | translate }}</clr-dg-cell>
<clr-dg-cell>{{ v.engine }}</clr-dg-cell>
<clr-dg-cell>{{ getMaintainerString(v.maintainers) }}</clr-dg-cell>
<clr-dg-cell>{{ v.created | date}}</clr-dg-cell>
@ -87,6 +90,10 @@
</div>
</div>
<div class="card-block">
<div class="form-group">
<label class="card-label">{{'HELM_CHART.STATUS' | translate}}</label>
<div>{{getStatusString(item) | translate}}</div>
</div>
<div class="form-group">
<label class="card-label">{{'HELM_CHART.ENGINE' | translate}}</label>
<div>{{item.engine}}</div>
@ -103,7 +110,7 @@
<div class="card-footer">
<clr-dropdown [clrCloseMenuOnItemClick]="false">
<button type="button" class="btn btn-link" (click)="versionDownload($event, item)">{{'HELM_CHART.DOWNLOAD' | translate}}</button>
<button type="button" class="btn btn-link" (click)="openVersionDeleteModal([item])">{{'BUTTON.DELETE' | translate}}</button>
<button type="button" class="btn btn-link" (click)="deleteVersionCard($event, item)">{{'BUTTON.DELETE' | translate}}</button>
</clr-dropdown>
</div>
</a>

View File

@ -172,7 +172,10 @@ export class ChartVersionComponent implements OnInit {
});
}
versionDownload(item?: HelmChartVersion) {
versionDownload(evt: Event, item?: HelmChartVersion) {
if (evt) {
evt.stopPropagation();
}
let selectedVersion: HelmChartVersion;
if (item) {
@ -268,6 +271,10 @@ export class ChartVersionComponent implements OnInit {
}
}
deleteVersionCard(env: Event, version: HelmChartVersion) {
env.stopPropagation();
this.openVersionDeleteModal([version]);
}
openVersionDeleteModal(versions: HelmChartVersion[]) {
let versionNames = versions.map(v => v.name).join(",");
this.translateService.get("HELM_CHART.DELETE_CHART_VERSION").subscribe(key => {
@ -304,8 +311,15 @@ export class ChartVersionComponent implements OnInit {
}
}
getDefaultIcon(v: HelmChartVersion) {
v.icon = this.chartDefaultIcon;
}
getStatusString(chartVersion: HelmChartVersion) {
if (chartVersion.deprecated) {
return "HELM_CHART.DEPRECATED";
} else {
return "HELM_CHART.ACTIVE";
}
}
}

View File

@ -307,7 +307,7 @@ export interface HelmChartItem {
status?: string;
pulls?: number;
maintainer?: string;
deprecated?: boolean;
}
export interface HelmChartVersion {
@ -324,6 +324,7 @@ export interface HelmChartVersion {
urls: string[];
created: string;
digest: string;
deprecated?: boolean;
}
export interface HelmChartDetail {

View File

@ -3482,40 +3482,6 @@
"integrity": "sha1-wcS5vuPglyXdsQa3XB4wH+LxiyY=",
"dev": true
},
"fileset": {
"version": "0.2.1",
"resolved": "https://registry.npmjs.org/fileset/-/fileset-0.2.1.tgz",
"integrity": "sha1-WI74lzxmI7KnbfRlEFaWuWqsgGc=",
"dev": true,
"requires": {
"glob": "5.x",
"minimatch": "2.x"
},
"dependencies": {
"glob": {
"version": "5.0.15",
"resolved": "https://registry.npmjs.org/glob/-/glob-5.0.15.tgz",
"integrity": "sha1-G8k2ueAvSmA/zCIuz3Yz0wuLk7E=",
"dev": true,
"requires": {
"inflight": "^1.0.4",
"inherits": "2",
"minimatch": "2 || 3",
"once": "^1.3.0",
"path-is-absolute": "^1.0.0"
}
},
"minimatch": {
"version": "2.0.10",
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-2.0.10.tgz",
"integrity": "sha1-jQh8OcazjAAbl/ynzm0OHoCvusc=",
"dev": true,
"requires": {
"brace-expansion": "^1.0.0"
}
}
}
},
"fill-range": {
"version": "2.2.4",
"resolved": "https://registry.npmjs.org/fill-range/-/fill-range-2.2.4.tgz",
@ -4879,13 +4845,15 @@
"version": "1.0.5",
"resolved": "https://registry.npmjs.org/har-schema/-/har-schema-1.0.5.tgz",
"integrity": "sha1-0mMTX0MwfALGAq/I/pWXDAFRNp4=",
"dev": true
"dev": true,
"optional": true
},
"har-validator": {
"version": "4.2.1",
"resolved": "https://registry.npmjs.org/har-validator/-/har-validator-4.2.1.tgz",
"integrity": "sha1-M0gdDxu/9gDdID11gSpqX7oALio=",
"dev": true,
"optional": true,
"requires": {
"ajv": "^4.9.1",
"har-schema": "^1.0.5"
@ -4896,6 +4864,7 @@
"resolved": "https://registry.npmjs.org/ajv/-/ajv-4.11.8.tgz",
"integrity": "sha1-gv+wKynmYq5TvcIK8VlHcGc5xTY=",
"dev": true,
"optional": true,
"requires": {
"co": "^4.6.0",
"json-stable-stringify": "^1.0.1"
@ -6284,13 +6253,13 @@
}
},
"karma-remap-istanbul": {
"version": "0.2.2",
"resolved": "https://registry.npmjs.org/karma-remap-istanbul/-/karma-remap-istanbul-0.2.2.tgz",
"integrity": "sha1-HN9shaVcayDpxxScCoxVUzA42dk=",
"version": "0.6.0",
"resolved": "https://registry.npmjs.org/karma-remap-istanbul/-/karma-remap-istanbul-0.6.0.tgz",
"integrity": "sha1-l/O3cAZSVPm0ck8tm+SjouG69vw=",
"dev": true,
"requires": {
"istanbul": "^0.4.3",
"remap-istanbul": "^0.6.4"
"remap-istanbul": "^0.9.0"
}
},
"karma-source-map-support": {
@ -6388,6 +6357,39 @@
"promise": "^7.1.1",
"request": "2.81.0",
"source-map": "^0.5.3"
},
"dependencies": {
"request": {
"version": "2.81.0",
"resolved": "https://registry.npmjs.org/request/-/request-2.81.0.tgz",
"integrity": "sha1-xpKJRqDgbF+Nb4qTM0af/aRimKA=",
"dev": true,
"optional": true,
"requires": {
"aws-sign2": "~0.6.0",
"aws4": "^1.2.1",
"caseless": "~0.12.0",
"combined-stream": "~1.0.5",
"extend": "~3.0.0",
"forever-agent": "~0.6.1",
"form-data": "~2.1.1",
"har-validator": "~4.2.1",
"hawk": "~3.1.3",
"http-signature": "~1.1.0",
"is-typedarray": "~1.0.0",
"isstream": "~0.1.2",
"json-stringify-safe": "~5.0.1",
"mime-types": "~2.1.7",
"oauth-sign": "~0.8.1",
"performance-now": "^0.2.0",
"qs": "~6.4.0",
"safe-buffer": "^5.0.1",
"stringstream": "~0.0.4",
"tough-cookie": "~2.3.0",
"tunnel-agent": "^0.6.0",
"uuid": "^3.0.0"
}
}
}
},
"less-loader": {
@ -8012,7 +8014,8 @@
"version": "0.2.0",
"resolved": "https://registry.npmjs.org/performance-now/-/performance-now-0.2.0.tgz",
"integrity": "sha1-M+8wxcd9TqIcWlOGnZG1bY8lVeU=",
"dev": true
"dev": true,
"optional": true
},
"pify": {
"version": "3.0.0",
@ -8444,7 +8447,8 @@
"version": "6.4.0",
"resolved": "https://registry.npmjs.org/qs/-/qs-6.4.0.tgz",
"integrity": "sha1-E+JtKK1rD/qpExLNO/cI7TUecjM=",
"dev": true
"dev": true,
"optional": true
},
"querystring": {
"version": "0.2.0",
@ -8826,79 +8830,19 @@
"dev": true
},
"remap-istanbul": {
"version": "0.6.4",
"resolved": "https://registry.npmjs.org/remap-istanbul/-/remap-istanbul-0.6.4.tgz",
"integrity": "sha1-rFUe/xqmQVBLTzGNAwPdph47tpU=",
"version": "0.9.6",
"resolved": "https://registry.npmjs.org/remap-istanbul/-/remap-istanbul-0.9.6.tgz",
"integrity": "sha512-l0WDBsVjaTzP8m3glERJO6bjlAFUahcgfcgvcX+owZw7dKeDLT3CVRpS7UO4L9LfGcMiNsqk223HopwVxlh8Hg==",
"dev": true,
"requires": {
"amdefine": "1.0.0",
"amdefine": "^1.0.0",
"gulp-util": "3.0.7",
"istanbul": "0.4.3",
"source-map": ">=0.5.6",
"istanbul": "0.4.5",
"minimatch": "^3.0.3",
"source-map": "^0.6.1",
"through2": "2.0.1"
},
"dependencies": {
"abbrev": {
"version": "1.0.9",
"resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.0.9.tgz",
"integrity": "sha1-kbR5JYinc4wl813W9jdSovh3YTU=",
"dev": true
},
"amdefine": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/amdefine/-/amdefine-1.0.0.tgz",
"integrity": "sha1-/RdHRwDLXMnCtwnwvp0jzjwZjDM=",
"dev": true
},
"async": {
"version": "1.5.2",
"resolved": "https://registry.npmjs.org/async/-/async-1.5.2.tgz",
"integrity": "sha1-7GphrlZIDAw8skHJVhjiCJL5Zyo=",
"dev": true
},
"esprima": {
"version": "2.7.3",
"resolved": "https://registry.npmjs.org/esprima/-/esprima-2.7.3.tgz",
"integrity": "sha1-luO3DVd59q1JzQMmc9HDEnZ7pYE=",
"dev": true
},
"has-flag": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/has-flag/-/has-flag-1.0.0.tgz",
"integrity": "sha1-nZ55MWXOAXoA8AQYxD+UKnsdEfo=",
"dev": true
},
"istanbul": {
"version": "0.4.3",
"resolved": "https://registry.npmjs.org/istanbul/-/istanbul-0.4.3.tgz",
"integrity": "sha1-W3FO4K5JOsXvIEuZ84crzu9z1To=",
"dev": true,
"requires": {
"abbrev": "1.0.x",
"async": "1.x",
"escodegen": "1.8.x",
"esprima": "2.7.x",
"fileset": "0.2.x",
"handlebars": "^4.0.1",
"js-yaml": "3.x",
"mkdirp": "0.5.x",
"nopt": "3.x",
"once": "1.x",
"resolve": "1.1.x",
"supports-color": "^3.1.0",
"which": "^1.1.1",
"wordwrap": "^1.0.0"
}
},
"nopt": {
"version": "3.0.6",
"resolved": "https://registry.npmjs.org/nopt/-/nopt-3.0.6.tgz",
"integrity": "sha1-xkZdvwirzU2zWTF/eaxopkayj/k=",
"dev": true,
"requires": {
"abbrev": "1"
}
},
"process-nextick-args": {
"version": "1.0.7",
"resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-1.0.7.tgz",
@ -8919,10 +8863,10 @@
"util-deprecate": "~1.0.1"
}
},
"resolve": {
"version": "1.1.7",
"resolved": "https://registry.npmjs.org/resolve/-/resolve-1.1.7.tgz",
"integrity": "sha1-IDEU2CrSxe2ejgQRs5ModeiJ6Xs=",
"source-map": {
"version": "0.6.1",
"resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
"integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
"dev": true
},
"string_decoder": {
@ -8931,15 +8875,6 @@
"integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=",
"dev": true
},
"supports-color": {
"version": "3.2.3",
"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-3.2.3.tgz",
"integrity": "sha1-ZawFBLOVQXHYpklGsq48u4pfVPY=",
"dev": true,
"requires": {
"has-flag": "^1.0.0"
}
},
"through2": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/through2/-/through2-2.0.1.tgz",
@ -8949,12 +8884,6 @@
"readable-stream": "~2.0.0",
"xtend": "~4.0.0"
}
},
"wordwrap": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-1.0.0.tgz",
"integrity": "sha1-J1hIEIkUVqQXHI0CJkQa3pDLyus=",
"dev": true
}
}
},
@ -9013,33 +8942,107 @@
"dev": true
},
"request": {
"version": "2.81.0",
"resolved": "https://registry.npmjs.org/request/-/request-2.81.0.tgz",
"integrity": "sha1-xpKJRqDgbF+Nb4qTM0af/aRimKA=",
"version": "2.87.0",
"resolved": "https://registry.npmjs.org/request/-/request-2.87.0.tgz",
"integrity": "sha512-fcogkm7Az5bsS6Sl0sibkbhcKsnyon/jV1kF3ajGmF0c8HrttdKTPRT9hieOaQHA5HEq6r8OyWOo/o781C1tNw==",
"dev": true,
"requires": {
"aws-sign2": "~0.6.0",
"aws4": "^1.2.1",
"aws-sign2": "~0.7.0",
"aws4": "^1.6.0",
"caseless": "~0.12.0",
"combined-stream": "~1.0.5",
"extend": "~3.0.0",
"extend": "~3.0.1",
"forever-agent": "~0.6.1",
"form-data": "~2.1.1",
"har-validator": "~4.2.1",
"hawk": "~3.1.3",
"http-signature": "~1.1.0",
"form-data": "~2.3.1",
"har-validator": "~5.0.3",
"http-signature": "~1.2.0",
"is-typedarray": "~1.0.0",
"isstream": "~0.1.2",
"json-stringify-safe": "~5.0.1",
"mime-types": "~2.1.7",
"oauth-sign": "~0.8.1",
"performance-now": "^0.2.0",
"qs": "~6.4.0",
"safe-buffer": "^5.0.1",
"stringstream": "~0.0.4",
"tough-cookie": "~2.3.0",
"mime-types": "~2.1.17",
"oauth-sign": "~0.8.2",
"performance-now": "^2.1.0",
"qs": "~6.5.1",
"safe-buffer": "^5.1.1",
"tough-cookie": "~2.3.3",
"tunnel-agent": "^0.6.0",
"uuid": "^3.0.0"
"uuid": "^3.1.0"
},
"dependencies": {
"ajv": {
"version": "5.5.2",
"resolved": "https://registry.npmjs.org/ajv/-/ajv-5.5.2.tgz",
"integrity": "sha1-c7Xuyj+rZT49P5Qis0GtQiBdyWU=",
"dev": true,
"requires": {
"co": "^4.6.0",
"fast-deep-equal": "^1.0.0",
"fast-json-stable-stringify": "^2.0.0",
"json-schema-traverse": "^0.3.0"
}
},
"assert-plus": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz",
"integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=",
"dev": true
},
"aws-sign2": {
"version": "0.7.0",
"resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz",
"integrity": "sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg=",
"dev": true
},
"form-data": {
"version": "2.3.2",
"resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.2.tgz",
"integrity": "sha1-SXBJi+YEwgwAXU9cI67NIda0kJk=",
"dev": true,
"requires": {
"asynckit": "^0.4.0",
"combined-stream": "1.0.6",
"mime-types": "^2.1.12"
}
},
"har-schema": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz",
"integrity": "sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI=",
"dev": true
},
"har-validator": {
"version": "5.0.3",
"resolved": "https://registry.npmjs.org/har-validator/-/har-validator-5.0.3.tgz",
"integrity": "sha1-ukAsJmGU8VlW7xXg/PJCmT9qff0=",
"dev": true,
"requires": {
"ajv": "^5.1.0",
"har-schema": "^2.0.0"
}
},
"http-signature": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz",
"integrity": "sha1-muzZJRFHcvPZW2WmCruPfBj7rOE=",
"dev": true,
"requires": {
"assert-plus": "^1.0.0",
"jsprim": "^1.2.2",
"sshpk": "^1.7.0"
}
},
"performance-now": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz",
"integrity": "sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns=",
"dev": true
},
"qs": {
"version": "6.5.2",
"resolved": "https://registry.npmjs.org/qs/-/qs-6.5.2.tgz",
"integrity": "sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA==",
"dev": true
}
}
},
"require-directory": {

View File

@ -58,7 +58,7 @@
"karma-cli": "^1.0.1",
"karma-jasmine": "~1.1.0",
"karma-mocha-reporter": "^2.2.4",
"karma-remap-istanbul": "^0.2.1",
"karma-remap-istanbul": "^0.6.0",
"ng-packagr": "^1.7.0",
"protractor": "4.0.9",
"rollup": "^0.41.6",

View File

@ -1,6 +1,6 @@
<div class="login-wrapper login-wrapper-override" [ngStyle]="{'background-image': customLoginBgImg? 'url(static/images/' + customLoginBgImg + ')': ''}">
<form #signInForm="ngForm" class="login">
<label class="title"> {{customAppTitle? customAppTitle:(appTitle | translate)}}<span class="trademark tm-font">&#8482;</span>
<label class="title"> {{customAppTitle? customAppTitle:(appTitle | translate)}}
</label>
<div class="login-group">
<label for="username" aria-haspopup="true" role="tooltip" class="tooltip tooltip-validation tooltip-md tooltip-top-left">
@ -33,7 +33,7 @@
<a href="javascript:void(0)" class="signup" (click)="signUp()" *ngIf="selfSignUp">{{ 'BUTTON.SIGN_UP_LINK' | translate }}</a>
</div>
<div>
<a href="https://github.com/vmware/harbor" target="_blank" class="more-info-link">{{ 'BUTTON.MORE_INFO' | translate }}</a>
<a href="https://github.com/goharbor/harbor" target="_blank" class="more-info-link">{{ 'BUTTON.MORE_INFO' | translate }}</a>
</div>
</form>
<div id="pop_repo" class="popular-repo-wrapper">

View File

@ -1,7 +1,7 @@
<clr-header class="header-5 header" [ngStyle]='{"background-color": customStyle?.headerBgColor?customStyle?.headerBgColor:"#004a70" }'>
<div class="branding">
<a href="javascript:void(0)" class="nav-link" (click)="homeAction()">
<clr-icon shape="vm-bug" *ngIf="!customStyle?.headerLogo"></clr-icon>
<!-- <clr-icon shape="vm-bug" *ngIf="!customStyle?.headerLogo"></clr-icon> -->
<img [attr.src]="'static/images/'+customStyle?.headerLogo" *ngIf="customStyle?.headerLogo" style="width: 36px;height: 36px; object-fit: fill;">
<span class="title">{{customProjectName?.projectName? customProjectName?.projectName:(appTitle | translate)}}</span>
</a>

View File

@ -19,7 +19,7 @@
</p>
</div>
<div class="card-footer my-card-footer">
<a href="http://vmware.github.io/harbor/" target="_blank" class="btn btn-sm btn-link">Learn More</a>
<a href="https://goharbor.io" target="_blank" class="btn btn-sm btn-link">Learn More</a>
</div>
</div>
</div>

View File

@ -1,24 +1,22 @@
<clr-modal [(clrModalOpen)]="opened" [clrModalClosable]="false" [clrModalStaticBackdrop]="false">
<h3 class="modal-title margin-left-override">{{customName?.companyName? customName?.companyName : 'vmware'}}</h3>
<div class="modal-body margin-left-override">
<div>
<h2>{{customName?.projectName? customName?.projectName : ('APP_TITLE.HARBOR' | translate)}}</h2>
<div class="modal-body dialog-body">
<div class="harbor-logo-black">
<img [src]="'/static/images/harbor-black-logo.png'" onError="this.src='images/harbor-black-logo.png'">
</div>
<div style="height: 12px;"></div>
<div>
<span class="p5 about-version">{{'ABOUT.VERSION' | translate}} {{version}}</span>
</div>
<div style="height: 12px;"></div>
<div *ngIf="!customIntroduction">
<p class="p5">{{'ABOUT.COPYRIGHT' | translate}} <a href="http://www.vmware.com/go/patents" target="_blank" class="about-text-link">http://www.vmware.com/go/patents</a> {{'ABOUT.COPYRIGHT_SUFIX' | translate}}</p>
<p class="p5">{{'ABOUT.TRADEMARK' | translate}}</p>
<p class="p5">
<a href="https://raw.githubusercontent.com/vmware/harbor/master/LICENSE" target="_blank">{{'ABOUT.OPEN_SOURCE_LICENSE' | translate}}</a>
</p>
<div style="height: 24px;"></div>
</div>
<div *ngIf="customIntroduction">
<p class="p5">{{customIntroduction}}</p>
<div class="content">
<div>{{customName?.projectName? customName?.projectName : ('APP_TITLE.HARBOR' | translate)}}</div>
<div>
<span class="p5 about-version">{{'ABOUT.VERSION' | translate}} {{version}}</span>
</div>
<div *ngIf="!customIntroduction">
<p class="p5">{{'ABOUT.COPYRIGHT' | translate}}</p>
<p class="p5">
<a href="https://raw.githubusercontent.com/goharbor/harbor/master/LICENSE" target="_blank">{{'ABOUT.OPEN_SOURCE_LICENSE' | translate}}</a>
</p>
</div>
<div *ngIf="customIntroduction">
<p class="p5">{{customIntroduction}}</p>
</div>
</div>
</div>
<div class="modal-footer margin-left-override">

View File

@ -1,7 +1,3 @@
.margin-left-override {
margin-left: 24px !important;
}
.about-version {
font-size: 14px;
color: #565656;
@ -11,4 +7,12 @@
.about-build {
font-size: 14px;
color: #565656;
}
.dialog-body {
display:flex;
}
.content {
margin:0 10px 10px 10px;
}

View File

@ -1,6 +1,6 @@
{
"APP_TITLE": {
"VMW_HARBOR": "VMware Harbor",
"VMW_HARBOR": "Harbor",
"HARBOR": "Harbor",
"VIC": "vSphere Integrated Containers",
"MGMT": "Management",
@ -521,7 +521,8 @@
"COMMAND": "Commands",
"PROV_FILE": "Prov File",
"READY": "Ready",
"NOT_READY": "Not Ready"
"NOT_READY": "Not Ready",
"STATUS": "Status"
},
"ALERT": {
"FORM_CHANGE_CONFIRMATION": "Some changes are not saved yet. Do you want to cancel?"
@ -646,7 +647,7 @@
"ABOUT": {
"VERSION": "Version",
"BUILD": "Build",
"COPYRIGHT": "Copyright 1998-2018 VMware, Inc. All rights reserved. This product is protected by U.S. and international property laws. VMware products are covered by one or more patents listed at",
"COPYRIGHT": "Project Harbor is an an open source trusted cloud native registry project that stores, signs, and scans content. Harbor extends the open source Docker Distribution by adding the functionalities usually required by users such as security, identity and management. Harbor supports advanced features such as user management, access control, activity monitoring, and replication between instances. Having a registry closer to the build and run environment can also improve image transfer efficiency.",
"COPYRIGHT_SUFIX": ".",
"TRADEMARK": "VMware is a registered trademark or trademark of VMware, Inc. in the United States and other jurisdictions. All other marks and names mentioned herein may be trademark of their respective companies.",
"END_USER_LICENSE": "End User License Agreement",

View File

@ -1,6 +1,6 @@
{
"APP_TITLE": {
"VMW_HARBOR": "VMware Harbor",
"VMW_HARBOR": "Harbor",
"HARBOR": "Harbor",
"VIC": "Contenedores Integrados vSphere",
"MGMT": "Administración",
@ -520,7 +520,8 @@
"COMMAND": "Commands",
"PROV_FILE": "Prov File",
"READY": "Ready",
"NOT_READY": "Not Ready"
"NOT_READY": "Not Ready",
"STATUS": "Status"
},
"ALERT": {
"FORM_CHANGE_CONFIRMATION": "Algunos cambios no se han guardado aún. ¿Quiere cancelar?"
@ -644,7 +645,7 @@
"ABOUT": {
"VERSION": "Versión",
"BUILD": "Construir",
"COPYRIGHT": "Copyright 1998-2018 VMware, Inc. Todos los derechos reservados. Este producto está protegido por E.U. y las leyes de propiedad internacionales. Los productos de VMware estan cubiertos por una o más patentes listadas en",
"COPYRIGHT": "Project Harbor is an an open source trusted cloud native registry project that stores, signs, and scans content. Harbor extends the open source Docker Distribution by adding the functionalities usually required by users such as security, identity and management. Harbor supports advanced features such as user management, access control, activity monitoring, and replication between instances. Having a registry closer to the build and run environment can also improve image transfer efficiency.",
"COPYRIGHT_SUFIX": ".",
"TRADEMARK": "VMware es una marca registrada o marca de VMware, Inc. en los Estados Unidos y otras jurisdicciones. Todas las demás marcas y nombres mencionados son marcas de sus respectivas compañías.",
"END_USER_LICENSE": "Contrato de Usuario Final (EULA)",

View File

@ -1,6 +1,6 @@
{
"APP_TITLE": {
"VMW_HARBOR": "VMware Harbor",
"VMW_HARBOR": "Harbor",
"HARBOR": "Harbor",
"VIC": "vSphere Integrated Containers",
"MGMT": "Management",
@ -495,7 +495,8 @@
"COMMAND": "Commands",
"PROV_FILE": "Prov File",
"READY": "Ready",
"NOT_READY": "Not Ready"
"NOT_READY": "Not Ready",
"STATUS": "Status"
},
"ALERT": {
"FORM_CHANGE_CONFIRMATION": "Certaines modifications ne sont pas encore enregistrées. Voulez-vous annuler ?"
@ -608,7 +609,7 @@
"ABOUT": {
"VERSION": "Version",
"BUILD": "Build",
"COPYRIGHT": "Copyright 1998-2017 VMware, Inc. Tous droits réservés. Ce produit est protégé par les lois américaines et internationales sur la propriété intellectuelle. Les produits VMware sont couverts par un ou plusieurs brevets répertoriés à l'adresse suivante",
"COPYRIGHT": "Project Harbor is an an open source trusted cloud native registry project that stores, signs, and scans content. Harbor extends the open source Docker Distribution by adding the functionalities usually required by users such as security, identity and management. Harbor supports advanced features such as user management, access control, activity monitoring, and replication between instances. Having a registry closer to the build and run environment can also improve image transfer efficiency.",
"COPYRIGHT_SUFIX": ".",
"TRADEMARK": "VMware est une marque déposée ou une marque déposée de VMware, Inc. aux États-Unis et dans d'autres juridictions. Toutes les autres marques et noms mentionnés dans le présent document peuvent être des marques de commerce de leurs sociétés respectives.",
"END_USER_LICENSE": "Contrat de licence utilisateur final",

View File

@ -1,6 +1,6 @@
{
"APP_TITLE": {
"VMW_HARBOR": "VMware Harbor",
"VMW_HARBOR": "Harbor",
"HARBOR": "Harbor",
"VIC": "vSphere Integrated Containers",
"MGMT": "Management",
@ -520,7 +520,8 @@
"COMMAND": "命令",
"PROV_FILE": "Prov 文件",
"READY": "就绪",
"NOT_READY": "未就绪"
"NOT_READY": "未就绪",
"STATUS": "状态"
},
"ALERT": {
"FORM_CHANGE_CONFIRMATION": "表单内容改变,确认是否取消?"
@ -644,7 +645,7 @@
"ABOUT": {
"VERSION": "版本",
"BUILD": "构建",
"COPYRIGHT": "版权所有 © 1998-2018 VMware, Inc. 保留所有权利。此产品受美国及其他国家/地区的版权和知识产权以及国际条约保护。VMware产品受",
"COPYRIGHT": "Harbor是一个用于存储和分发Docker镜像的企业级Registry服务器通过添加一些企业必需的功能特性例如安全、标识和管理等扩展了开源Docker Distribution。作为一个企业级私有Registry服务器Harbor提供了更好的性能和安全。提升用户使用Registry构建和运行环境传输镜像的效率。",
"COPYRIGHT_SUFIX": "上列出的一项或多项专利保护。",
"TRADEMARK": "VMware徽标及设计都是VMware, Inc.在美国和/或其他法律辖区的注册商标或者商标。此处提到的其他所有商标和名称分别是其各自公司的商标。",
"END_USER_LICENSE": "终端用户许可协议",

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.0 KiB

View File

@ -119,7 +119,7 @@ class TestAssignRoleToLdapGroup(unittest.TestCase):
self.assertTrue(self.queryUserLogs(username="admin_user", password="zhu88jie")>0, "admin user can see logs")
self.assertTrue(self.queryUserLogs(username="dev_user", password="zhu88jie")>0, "dev user can see logs")
self.assertTrue(self.queryUserLogs(username="guest_user", password="zhu88jie")>0, "guest user can see logs")
self.assertTrue(self.queryUserLogs(username="user001", password="zhu88jie")==0, "user001 can not see any logs")
self.assertTrue(self.queryUserLogs(username="test", password="123456")==0, "test user can not see any logs")
pass

View File

@ -1,7 +1,7 @@
version: '2'
services:
registry:
image: vmware/registry-photon:__reg_version__
image: goharbor/registry-photon:__reg_version__
restart: always
volumes:
- /data/registry:/storage
@ -13,7 +13,7 @@ services:
command:
["serve", "/etc/registry/config.yml"]
postgres:
image: vmware/harbor-db:__version__
image: goharbor/harbor-db:__version__
restart: always
volumes:
- /data/database:/var/lib/postgresql/data:z
@ -35,7 +35,7 @@ services:
ports:
- 8888:8080
redis:
image: vmware/redis-photon:4.0
image: goharbor/redis-photon:4.0
restart: always
volumes:
- /data/redis:/data

View File

@ -18,7 +18,7 @@ gsutil version -l
set +x
## -------------------------------------------- Pre-condition --------------------------------------------
if [[ $DRONE_REPO != "vmware/harbor" ]]; then
if [[ $DRONE_REPO != "goharbor/harbor" ]]; then
echo "Only run tests again Harbor Repo."
exit 1
fi
@ -70,7 +70,7 @@ container_ip=`ip addr s eth0 |grep "inet "|awk '{print $2}' |awk -F "/" '{print
echo $container_ip
## --------------------------------------------- Init Version -----------------------------------------------
buildinfo=$(drone build info vmware/harbor $DRONE_BUILD_NUMBER)
buildinfo=$(drone build info goharbor/harbor $DRONE_BUILD_NUMBER)
echo $buildinfo
git_commit=$(git rev-parse --short=8 HEAD)
@ -122,7 +122,7 @@ function publishImage {
docker images
docker login -u $DOCKER_HUB_USERNAME -p $DOCKER_HUB_PASSWORD
# rename the images with tag "dev" and push to Docker Hub
docker images | sed -n "s|\(vmware/[-._a-z0-9]*\)\s*\(.*$Harbor_Assets_Version\).*|docker tag \1:\2 \1:dev;docker push \1:dev|p" | bash
docker images | sed -n "s|\(goharbor/[-._a-z0-9]*\)\s*\(.*$Harbor_Assets_Version\).*|docker tag \1:\2 \1:dev;docker push \1:dev|p" | bash
echo "Images are published successfully"
docker images
}
@ -211,9 +211,19 @@ if [ $upload_latest_build == true ] && [ $upload_bundle_success == true ] && [ $
uploader $latest_build_file $harbor_target_bucket
fi
## ------------------------------------------------ Tear Down ---------------------------------------------------
## --------------------------------------------- Upload securego results ------------------------------------------
if [ $DRONE_BUILD_EVENT == "push" ] && [ $rc -eq 0 ]; then
go get github.com/securego/gosec/cmd/gosec
go get github.com/dghubble/sling
make gosec -e GOSECRESULTS=harbor-gosec-results-latest.json
echo $git_commit > ./harbor-gosec-results-latest-version
uploader harbor-gosec-results-latest.json $harbor_target_bucket
uploader harbor-gosec-results-latest-version $harbor_target_bucket
fi
## ------------------------------------------------ Tear Down -----------------------------------------------------
if [ -f "$keyfile" ]; then
rm -f $keyfile
fi
exit $rc
exit $rc

View File

@ -226,7 +226,7 @@ objectclass: person
sn: user001
uid: user001
uidnumber: 5005
userpassword: {MD5}wb68DeX0CyENafzUADNn9A==
userpassword: {MD5}jMx5MaPXabPyX7F0SoFxYQ==
dn: cn=user002,ou=people,dc=example,dc=com
cn: user002
@ -244,7 +244,7 @@ objectclass: person
sn: user002
uid: user002
uidnumber: 5006
userpassword: {MD5}wb68DeX0CyENafzUADNn9A==
userpassword: {MD5}jMx5MaPXabPyX7F0SoFxYQ==
dn: cn=user003,ou=people,dc=example,dc=com
cn: user003
@ -262,7 +262,7 @@ objectclass: person
sn: user003
uid: user003
uidnumber: 5007
userpassword: {MD5}wb68DeX0CyENafzUADNn9A==
userpassword: {MD5}jMx5MaPXabPyX7F0SoFxYQ==
dn: cn=user004,ou=people,dc=example,dc=com
cn: user004
@ -280,7 +280,7 @@ objectclass: person
sn: user004
uid: user004
uidnumber: 5008
userpassword: {MD5}wb68DeX0CyENafzUADNn9A==
userpassword: {MD5}jMx5MaPXabPyX7F0SoFxYQ==
dn: cn=user005,ou=people,dc=example,dc=com
cn: user005
@ -298,7 +298,7 @@ objectclass: person
sn: user005
uid: user005
uidnumber: 5009
userpassword: {MD5}wb68DeX0CyENafzUADNn9A==
userpassword: {MD5}jMx5MaPXabPyX7F0SoFxYQ==
dn: cn=user006,ou=people,dc=example,dc=com
cn: user006
@ -316,7 +316,7 @@ objectclass: person
sn: user006
uid: user006
uidnumber: 5010
userpassword: {MD5}wb68DeX0CyENafzUADNn9A==
userpassword: {MD5}jMx5MaPXabPyX7F0SoFxYQ==
dn: cn=user007,ou=people,dc=example,dc=com
cn: user007
@ -334,7 +334,7 @@ objectclass: person
sn: user007
uid: user007
uidnumber: 5011
userpassword: {MD5}wb68DeX0CyENafzUADNn9A==
userpassword: {MD5}jMx5MaPXabPyX7F0SoFxYQ==
dn: cn=user008,ou=people,dc=example,dc=com
cn: user008
@ -352,7 +352,7 @@ objectclass: person
sn: user008
uid: user008
uidnumber: 5012
userpassword: {MD5}wb68DeX0CyENafzUADNn9A==
userpassword: {MD5}jMx5MaPXabPyX7F0SoFxYQ==
dn: cn=user009,ou=people,dc=example,dc=com
cn: user009
@ -370,7 +370,7 @@ objectclass: person
sn: user009
uid: user009
uidnumber: 5013
userpassword: {MD5}wb68DeX0CyENafzUADNn9A==
userpassword: {MD5}jMx5MaPXabPyX7F0SoFxYQ==
dn: cn=user010,ou=people,dc=example,dc=com
cn: user010
@ -388,7 +388,7 @@ objectclass: person
sn: user010
uid: user010
uidnumber: 5014
userpassword: {MD5}wb68DeX0CyENafzUADNn9A==
userpassword: {MD5}jMx5MaPXabPyX7F0SoFxYQ==
dn: cn=user011,ou=people,dc=example,dc=com
cn: user011
@ -406,7 +406,7 @@ objectclass: person
sn: user011
uid: user011
uidnumber: 5015
userpassword: {MD5}wb68DeX0CyENafzUADNn9A==
userpassword: {MD5}jMx5MaPXabPyX7F0SoFxYQ==
dn: cn=user012,ou=people,dc=example,dc=com
cn: user012
@ -424,7 +424,7 @@ objectclass: person
sn: user012
uid: user012
uidnumber: 5016
userpassword: {MD5}wb68DeX0CyENafzUADNn9A==
userpassword: {MD5}jMx5MaPXabPyX7F0SoFxYQ==
dn: cn=user013,ou=people,dc=example,dc=com
cn: user013
@ -442,7 +442,7 @@ objectclass: person
sn: user013
uid: user013
uidnumber: 5017
userpassword: {MD5}wb68DeX0CyENafzUADNn9A==
userpassword: {MD5}jMx5MaPXabPyX7F0SoFxYQ==
dn: cn=user014,ou=people,dc=example,dc=com
cn: user014
@ -460,7 +460,7 @@ objectclass: person
sn: user014
uid: user014
uidnumber: 5018
userpassword: {MD5}wb68DeX0CyENafzUADNn9A==
userpassword: {MD5}jMx5MaPXabPyX7F0SoFxYQ==
dn: cn=user015,ou=people,dc=example,dc=com
cn: user015
@ -478,7 +478,7 @@ objectclass: person
sn: user015
uid: user015
uidnumber: 5019
userpassword: {MD5}wb68DeX0CyENafzUADNn9A==
userpassword: {MD5}jMx5MaPXabPyX7F0SoFxYQ==
dn: cn=user016,ou=people,dc=example,dc=com
cn: user016
@ -496,7 +496,7 @@ objectclass: person
sn: user016
uid: user016
uidnumber: 5020
userpassword: {MD5}wb68DeX0CyENafzUADNn9A==
userpassword: {MD5}jMx5MaPXabPyX7F0SoFxYQ==
dn: cn=user017,ou=people,dc=example,dc=com
cn: user017
@ -514,7 +514,7 @@ objectclass: person
sn: user017
uid: user017
uidnumber: 5021
userpassword: {MD5}wb68DeX0CyENafzUADNn9A==
userpassword: {MD5}jMx5MaPXabPyX7F0SoFxYQ==
dn: cn=user018,ou=people,dc=example,dc=com
cn: user018
@ -532,7 +532,7 @@ objectclass: person
sn: user018
uid: user018
uidnumber: 5022
userpassword: {MD5}wb68DeX0CyENafzUADNn9A==
userpassword: {MD5}jMx5MaPXabPyX7F0SoFxYQ==
dn: cn=user019,ou=people,dc=example,dc=com
cn: user019
@ -550,7 +550,7 @@ objectclass: person
sn: user019
uid: user019
uidnumber: 5023
userpassword: {MD5}wb68DeX0CyENafzUADNn9A==
userpassword: {MD5}jMx5MaPXabPyX7F0SoFxYQ==
dn: cn=user020,ou=people,dc=example,dc=com
cn: user020
@ -568,7 +568,7 @@ objectclass: person
sn: user020
uid: user020
uidnumber: 5024
userpassword: {MD5}wb68DeX0CyENafzUADNn9A==
userpassword: {MD5}jMx5MaPXabPyX7F0SoFxYQ==
dn: cn=user021,ou=people,dc=example,dc=com
cn: user021
@ -586,7 +586,7 @@ objectclass: person
sn: user021
uid: user021
uidnumber: 5025
userpassword: {MD5}wb68DeX0CyENafzUADNn9A==
userpassword: {MD5}jMx5MaPXabPyX7F0SoFxYQ==
dn: cn=user022,ou=people,dc=example,dc=com
cn: user022
@ -604,7 +604,7 @@ objectclass: person
sn: user022
uid: user022
uidnumber: 5026
userpassword: {MD5}wb68DeX0CyENafzUADNn9A==
userpassword: {MD5}jMx5MaPXabPyX7F0SoFxYQ==
dn: cn=user023,ou=people,dc=example,dc=com
cn: user023
@ -622,7 +622,7 @@ objectclass: person
sn: user023
uid: user023
uidnumber: 5027
userpassword: {MD5}wb68DeX0CyENafzUADNn9A==
userpassword: {MD5}jMx5MaPXabPyX7F0SoFxYQ==
dn: cn=user024,ou=people,dc=example,dc=com
cn: user024
@ -640,7 +640,7 @@ objectclass: person
sn: user024
uid: user024
uidnumber: 5028
userpassword: {MD5}wb68DeX0CyENafzUADNn9A==
userpassword: {MD5}jMx5MaPXabPyX7F0SoFxYQ==
dn: cn=user025,ou=people,dc=example,dc=com
cn: user025
@ -658,7 +658,7 @@ objectclass: person
sn: user025
uid: user025
uidnumber: 5029
userpassword: {MD5}wb68DeX0CyENafzUADNn9A==
userpassword: {MD5}jMx5MaPXabPyX7F0SoFxYQ==
dn: cn=user026,ou=people,dc=example,dc=com
cn: user026
@ -676,7 +676,7 @@ objectclass: person
sn: user026
uid: user026
uidnumber: 5030
userpassword: {MD5}wb68DeX0CyENafzUADNn9A==
userpassword: {MD5}jMx5MaPXabPyX7F0SoFxYQ==
dn: cn=guest_user,ou=people,dc=example,dc=com
cn: guest_user

View File

@ -26,6 +26,7 @@ Sign In Harbor
Sleep 5
${title}= Get Title
Log To Console ${title}
Run Keyword If "${title}" != "Harbor" Capture Screenshot And Source ELSE Log The title is Harbor
Should Be Equal ${title} Harbor
Sleep 2
Input Text login_username ${user}
@ -36,6 +37,10 @@ Sign In Harbor
Log To Console ${user}
Wait Until Page Contains ${user}
Capture Screenshot And Source
Capture Page Screenshot
Log Source
Sign Up Should Not Display
Page Should Not Contain Element xpath=${sign_up_button_xpath}

View File

@ -55,7 +55,7 @@ Down Harbor
Should Be Equal As Integers ${rc} 0
Package Harbor Offline
[Arguments] ${golang_image}=golang:${GOLANG_VERSION} ${clarity_image}=vmware/harbor-clarity-ui-builder:${CLAIR_BUILDER} ${with_notary}=true ${with_clair}=true ${with_migrator}=true ${with_chartmuseum}=true
[Arguments] ${golang_image}=golang:${GOLANG_VERSION} ${clarity_image}=goharbor/harbor-clarity-ui-builder:${CLAIR_BUILDER} ${with_notary}=true ${with_clair}=true ${with_migrator}=true ${with_chartmuseum}=true
Log To Console \nStart Docker Daemon
Start Docker Daemon Locally
Log To Console \n\nmake package_offline VERSIONTAG=%{Harbor_Assets_Version} PKGVERSIONTAG=%{Harbor_Package_Version} UIVERSIONTAG=%{Harbor_UI_Version} GOBUILDIMAGE=${golang_image} COMPILETAG=compile_golangimage CLARITYIMAGE=${clarity_image} NOTARYFLAG=${with_notary} CLAIRFLAG=${with_clair} MIGRATORFLAG=${with_migrator} CHARTFLAG=${with_chartmuseum} HTTPPROXY=
@ -65,7 +65,7 @@ Package Harbor Offline
Should Be Equal As Integers ${rc} 0
Package Harbor Online
[Arguments] ${golang_image}=golang:${GOLANG_VERSION} ${clarity_image}=vmware/harbor-clarity-ui-builder:${CLAIR_BUILDER} ${with_notary}=true ${with_clair}=true ${with_migrator}=true ${with_chartmuseum}=true
[Arguments] ${golang_image}=golang:${GOLANG_VERSION} ${clarity_image}=goharbor/harbor-clarity-ui-builder:${CLAIR_BUILDER} ${with_notary}=true ${with_clair}=true ${with_migrator}=true ${with_chartmuseum}=true
Log To Console \nStart Docker Daemon
Start Docker Daemon Locally
Log To Console \nmake package_online VERSIONTAG=%{Harbor_Assets_Version} PKGVERSIONTAG=%{Harbor_Package_Version} UIVERSIONTAG=%{Harbor_UI_Version} GOBUILDIMAGE=${golang_image} COMPILETAG=compile_golangimage CLARITYIMAGE=${clarity_image} NOTARYFLAG=${with_notary} CLAIRFLAG=${with_clair} MIGRATORFLAG=${with_migrator} CHARTFLAG=${with_chartmuseum} HTTPPROXY=
@ -150,7 +150,7 @@ Prepare Cert
Should Be Equal As Integers ${rc} 0
Compile and Up Harbor With Source Code
[Arguments] ${golang_image}=golang:${GOLANG_VERSION} ${clarity_image}=vmware/harbor-clarity-ui-builder:${CLAIR_BUILDER} ${with_notary}=true ${with_clair}=true ${with_chartmuseum}=true
[Arguments] ${golang_image}=golang:${GOLANG_VERSION} ${clarity_image}=goharbor/harbor-clarity-ui-builder:${CLAIR_BUILDER} ${with_notary}=true ${with_clair}=true ${with_chartmuseum}=true
${rc} ${output}= Run And Return Rc And Output docker pull ${clarity_image}
Log ${output}
Should Be Equal As Integers ${rc} 0

View File

@ -9,7 +9,7 @@ ${HARBOR_ADMIN} admin
*** Test Cases ***
Test Case - Upgrade Verify
${data}= Load Json From File ${CURDIR}${/}testdata.json
${data}= Load Json From File ${CURDIR}${/}data.json
Run Keyword Verify User ${data}
Run Keyword Verify Project ${data}
Run Keyword Verify Member Exist ${data}

View File

@ -3,7 +3,7 @@ FROM photon:1.0
ENV PGDATA /var/lib/postgresql/data
## have both mysql and pgsql installed.
RUN tdnf distro-sync -y || echo \
RUN tdnf distro-sync -y \
&& tdnf install -y sed shadow procps-ng gawk gzip sudo net-tools >> /dev/null\
&& groupadd -r -g 10000 mysql && useradd --no-log-init -r -g 10000 -u 10000 mysql \
&& tdnf install -y mariadb-server mariadb mariadb-devel python2 python2-devel python-pip gcc \

View File

@ -19,7 +19,6 @@ keys = [
'db_password',
'db_port',
'db_user',
'redis_url',
'clair_db_host',
'clair_db_password',
'clair_db_port',

View File

@ -140,8 +140,6 @@ db_user = $db_user
##### End of Harbor DB configuration#######
#The redis server address. Only needed in HA installation.
redis_url = $redis_url
##########Clair DB configuration############
@ -166,6 +164,22 @@ clair_updaters_interval = 12
##########End of Clair DB configuration############
##########Redis server configuration.############
#Redis connection address
redis_host = redis
#Redis connection port
redis_port = 6379
#Redis connection password
redis_password =
#Redis connection db index
#db_index 1,2,3 is for registry, jobservice and chartmuseum.
#db_index 0 is for UI, it's unchangeable
redis_db_index = 1,2,3
##########Redis server configuration.############
#The following attributes only need to be set when auth mode is uaa_auth
uaa_endpoint = $uaa_endpoint
uaa_clientid = $uaa_clientid