Merge remote-tracking branch 'origin/master' into fix/gitlab

This commit is contained in:
lxShaDoWxl 2020-05-24 16:05:32 +06:00
commit 05f78a561a
151 changed files with 1317 additions and 610 deletions

View File

@ -148,6 +148,7 @@ jobs:
cd src/github.com/goharbor/harbor
env
df -h
docker system prune -a -f
bash ./tests/showtime.sh ./tests/ci/api_common_install.sh $IP DB
- name: script
run: |

View File

@ -70,6 +70,7 @@ jobs:
df -h
- name: upload test result to gs
run: |
gsutil cp report.html gs://harbor-conformance-test/report.html
cd src/github.com/goharbor/harbor
gsutil cp ./distribution-spec/conformance/report.html gs://harbor-conformance-test/report.html
gsutil acl ch -u AllUsers:R gs://harbor-conformance-test/report.html
if: always()

View File

@ -2,14 +2,23 @@
## Welcome
Welcome to Harbor! This guide provides information on filing issues and guidelines for open source contributors. **Please leave comments / suggestions if you find something is missing or incorrect.**
Harbor is developed in the open, and is constantly being improved by our **users, contributors, and maintainers**.
It is because of you that we can bring great software to the community.
Contributors are encouraged to collaborate using the following resources in addition to the GitHub [issue tacker](https://github.com/goharbor/harbor/issues):
This guide provides information on filing issues and guidelines for open source contributors. **Please leave comments / suggestions if you find something is missing or incorrect.**
**Twitter:** [@project_harbor](https://twitter.com/project_harbor)
**User Group:** Join Harbor user email group: [harbor-users@googlegroups.com](https://groups.google.com/forum/#!forum/harbor-users) to get update of Harbor's news, features, releases, or to provide suggestion and feedback. To subscribe, send an email to [harbor-users+subscribe@googlegroups.com](mailto:harbor-users+subscribe@googlegroups.com) .
**Developer Group:** Join Harbor developer group: [harbor-dev@googlegroups.com](https://groups.google.com/forum/#!forum/harbor-dev) for discussion on Harbor development and contribution. To subscribe, send an email to [harbor-dev+subscribe@googlegroups.com](mailto:harbor-dev+subscribe@googlegroups.com).
**Slack:** Join Harbor's community for discussion and ask questions: [Cloud Native Computing Foundation](https://slack.cncf.io/), channel: #harbor and #harbor-dev
Contributors are encouraged to collaborate using the following resources in addition to the GitHub [issue tracker](https://github.com/goharbor/harbor/issues):
* [Bi-weekly public community meetings][community-meetings]
* Catch up with [past meetings on YouTube][past-meetings]
* Chat with us on the CNCF Slack ([get an invite here][cncf-slack] )
* [#harbor][users-slack] for end-user discussions
* [#harbor-dev][dev-slack] for development of Harbor
* Want long-form communication instead of Slack? We have two distributions lists:
* [harbor-users][users-dl] for end-user discussions
* [harbor-dev][dev-dl] for development of Harbor
Follow us on Twitter at [@project_harbor][twitter]
## Getting Started
@ -34,7 +43,7 @@ git fetch $USER
```
**NOTES:** Note that GOPATH can be any directory, the example above uses $HOME/go. Change $USER above to your own GitHub username.
To build the project, please refer the [build](docs/compile_guide.md) guideline.
To build the project, please refer the [build](docs/build-customize-contribute/compile-guide.md) guideline.
### Repository Structure
@ -243,7 +252,7 @@ Run UI library test cases:
npm run test
```
To build code, please refer to [build](docs/compile_guide.md) guideline.
To build the code, please refer to [build](docs/build-customize-contribute/compile-guide.md) guideline.
### Keep sync with upstream
@ -334,3 +343,12 @@ Documents are written with Markdown text. See [Writing on GitHub](https://help.g
## Design new features
You can propose new designs for existing Harbor features. You can also design entirely new features, Please submit a proposal in GitHub.(https://github.com/goharbor/community/tree/master/proposals). Harbor maintainers will review this proposal as soon as possible. This is necessary to ensure the overall architecture is consistent and to avoid duplicated work in the roadmap.
[community-meetings]: https://github.com/goharbor/community/blob/master/MEETING_SCHEDULE.md
[past-meetings]: https://www.youtube.com/playlist?list=PLgInP-D86bCwTC0DYAa1pgupsQIAWPomv
[users-slack]: https://cloud-native.slack.com/archives/CC1E09J6S
[dev-slack]: https://cloud-native.slack.com/archives/CC1E0J0MC
[cncf-slack]: https://slack.cncf.io
[users-dl]: https://lists.cncf.io/g/harbor-users
[dev-dl]: https://lists.cncf.io/g/harbor-dev
[twitter]: http://twitter.com/project_harbor

View File

@ -6,10 +6,10 @@
[![CII Best Practices](https://bestpractices.coreinfrastructure.org/projects/2095/badge)](https://bestpractices.coreinfrastructure.org/projects/2095)
[![Codacy Badge](https://api.codacy.com/project/badge/Grade/c8d726c9cfd047ffaf681449d673f246)](https://www.codacy.com/app/goharbor/harbor?utm_source=github.com&utm_medium=referral&utm_content=goharbor/harbor&utm_campaign=Badge_Grade)
[![Nightly Status](https://us-central1-eminent-nation-87317.cloudfunctions.net/harbor-nightly-result)](https://www.googleapis.com/storage/v1/b/harbor-nightly/o)
[![Conformance Status](https://github.com/goharbor/harbor/workflows/conformance_test/badge.svg)](https://github.com/goharbor/harbor/actions?query=workflow%3Aconformance_test)
![CONFORMANCE_TEST](https://github.com/goharbor/harbor/workflows/CONFORMANCE_TEST/badge.svg)
</br>
|![notification](docs/img/bell-outline-badged.svg)Community Meeting|
|![notification](docs/img/readme/bell-outline-badged.svg)Community Meeting|
|------------------|
|The Harbor Project holds bi-weekly community calls in two different timezones. To join the community calls or to watch previous meeting notes and recordings, please visit the [meeting schedule](https://github.com/goharbor/community/blob/master/MEETING_SCHEDULE.md).|
@ -18,7 +18,7 @@
**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 a stable set of binaries.
<img alt="Harbor" src="docs/img/harbor_logo.png">
<img alt="Harbor" src="docs/img/readme/harbor_logo.png">
Harbor is 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. Having a registry closer to the build and run environment can improve the image transfer efficiency. Harbor supports replication of images between registries, and also offers advanced security features such as user management, access control and activity auditing.
@ -34,24 +34,21 @@ Harbor is hosted by the [Cloud Native Computing Foundation](https://cncf.io) (CN
* **LDAP/AD support**: Harbor integrates with existing enterprise LDAP/AD for user authentication and management, and supports importing LDAP groups into Harbor that can then be given permissions to specific projects.
* **OIDC support**: Harbor leverages OpenID Connect (OIDC) to verify the identity of users authenticated by an external authorization server or identity provider. Single sign-on can be enabled to log into the Harbor portal.
* **Image deletion & garbage collection**: System admin can run garbage collection jobs so that images(dangling manifests and unreferenced blobs) can be deleted and their space can be freed up periodically.
* **Notary**: Support signing container images using Docker Content Trust (leveraing Notary) for guaranteeing authenticity and provenance. In additon, policies that prevent unsigned images from being deployed can also be activated.
* **Notary**: Support signing container images using Docker Content Trust (leveraging Notary) for guaranteeing authenticity and provenance. In additon, policies that prevent unsigned images from being deployed can also be activated.
* **Graphical user portal**: User can easily browse, search repositories and manage projects.
* **Auditing**: All the operations to the repositories are tracked through logs.
* **RESTful API**: RESTful APIs are provided to facilitate administrative operations, and are easy to use for integration with external systems. An embedded Swagger UI is available for exploring and testing the API.
* **Easy deployment**: Harbor can be deployed via Docker compose as well Helm Chart. A Harbor Operator was added recently as well - https://goharbor.io/docs/1.10/build-customize-contribute/e2e_api_python_based_scripting_guide/
## Architecture
For learning the architecture design of Harbor, check the document [Architecture Overview of Harbor](https://github.com/goharbor/harbor/wiki/Architecture-Overview-of-Harbor).
## API
* [Harbor RESTful API](https://editor.swagger.io/?url=https://raw.githubusercontent.com/goharbor/harbor/master/api/v2.0/swagger.yaml): The APIs for most administrative operations of Harbor and can be used to perform integrations with Harbor programmatically.
- Spec validation status: <img src="http://validator.swagger.io/validator?url=https://raw.githubusercontent.com/goharbor/harbor/master/api/harbor/swagger.yaml">
## Compatibility
The [compatibility list](./docs/harbor_compatibility_list.md) document provides compatibility information for the Harbor components.
- [Replication adapters](./docs/harbor_compatibility_list.md#Replication-Adapters)
- [OIDC adapters](./docs/harbor_compatibility_list.md#OIDC-Adapters)
- [Scanner adapters](./docs/harbor_compatibility_list.md#Scanner-Adapters)
* Harbor RESTful API: The APIs for most administrative operations of Harbor and can be used to perform integrations with Harbor programmatically.
* Part 1: [New or changed APIs](https://editor.swagger.io/?url=https://raw.githubusercontent.com/goharbor/harbor/master/api/v2.0/swagger.yaml)
* Part 2: [Legacy APIs](https://editor.swagger.io/?url=https://raw.githubusercontent.com/goharbor/harbor/master/api/v2.0/legacy_swagger.yaml)
## Install & Run
@ -59,12 +56,24 @@ The [compatibility list](./docs/harbor_compatibility_list.md) document provides
**On a Linux host:** docker 17.06.0-ce+ and docker-compose 1.18.0+ .
Download binaries of **[Harbor release ](https://github.com/vmware/harbor/releases)** and follow **[Installation & Configuration Guide](docs/installation_guide.md)** to install Harbor.
Download binaries of **[Harbor release ](https://github.com/vmware/harbor/releases)** and follow **[Installation & Configuration Guide](docs/README.md)** to install Harbor.
If you want to deploy Harbor on Kubernetes, please use the **[Harbor chart](https://github.com/goharbor/harbor-helm)**.
Refer to **[User Guide](docs/user_guide.md)** for more details on how to use Harbor.
## OCI Distribution Conformance Tests
Check the OCI distribution conformance tests [report](https://storage.googleapis.com/harbor-conformance-test/report.html) of Harbor.
## Compatibility
The [compatibility list](./docs/install-config/harbor-compatibility-list.md) document provides compatibility information for the Harbor components.
* [Replication adapters](./docs/install-config/harbor-compatibility-list.md#Replication-Adapters)
* [OIDC adapters](./docs/install-config/harbor-compatibility-list.md#OIDC-Adapters)
* [Scanner adapters](./docs/install-config/harbor-compatibility-list.md#Scanner-Adapters)
## Community
* **Twitter:** [@project_harbor](https://twitter.com/project_harbor)
@ -72,14 +81,6 @@ Refer to **[User Guide](docs/user_guide.md)** for more details on how to use Har
* **Developer Group:** Join Harbor developer group: [harbor-dev@lists.cncf.io](https://lists.cncf.io/g/harbor-dev) for discussion on Harbor development and contribution.
* **Slack:** Join Harbor's community for discussion and ask questions: [Cloud Native Computing Foundation](https://slack.cncf.io/), channel: [#harbor](https://cloud-native.slack.com/messages/harbor/) and [#harbor-dev](https://cloud-native.slack.com/messages/harbor-dev/)
## Additional Tools
Tools layered on top of Harbor and contributed by community.
* **[Harbor.Tagd](https://github.com/HylandSoftware/Harbor.Tagd)**
- Automates the process of cleaning up old tags from your Harbor container registries.
- Lead by [@nlowe](https://github.com/nlowe) from HylandSoftware.
## Demos
* **[Live Demo](https://demo.goharbor.io)** - A demo environment with the latest Harbor stable build installed. For additional information please refer to [this page](docs/demo_server.md).
@ -103,7 +104,6 @@ positively or negatively.
For further details please see our complete [security release process](SECURITY.md).
## License
Harbor is available under the [Apache 2 license](LICENSE).

View File

@ -1 +1 @@
v2.0.0
v2.1.0

View File

@ -16,7 +16,7 @@ You can get this IP address using:
$ docker-machine ip harbor.mydomain.com
```
Make sure to change the `hostname` in `Deploy/harbor.yml` to `harbor.mydomain.com`, configure everything else according to the [Harbor Installation Guide](../docs/installation_guide.md) and run `prepare`.
Copy `Deploy/harbor.yml.tmp` to `Deploy/harbor.yml` and make sure to change the `hostname` in `Deploy/harbor.yml` to `harbor.mydomain.com`, configure everything else according to the [Harbor Installation Guide](../docs/installation_guide.md) and run `prepare`.
Now, activate the created Docker Machine instance:

Binary file not shown.

BIN
docs/1.10/.README.md.swp Normal file

Binary file not shown.

View File

@ -1,8 +1,8 @@
---
title: Harbor 1.10 Documentation
title: Harbor 2.0 Documentation
---
Welcome to the Harbor 1.10.x documentation. This documentation includes all of the information that you need to install, configure, and use Harbor.
Welcome to the Harbor 2.0.x documentation. This documentation includes all of the information that you need to install, configure, and use Harbor.
## Harbor Installation and Configuration
@ -22,6 +22,6 @@ This section describes how developers can build from Harbor source code, customi
## Access the Documentation Source Files
The source files for this documentation set are located in the [Harbor repository on Github](https://github.com/goharbor/harbor/blob/master/docs/1.10/).
The source files for this documentation set are located in the [Harbor repository on Github](https://github.com/goharbor/harbor/tree/release-2.0.0/docs).
For versions of the docs before 1.10.x, go to the [`docs` folder in the Github repository](https://github.com/goharbor/harbor/tree/master/docs) and select the appropriate `release-1.xx.x` branch.
For versions of the docs before 2.0.x, go to the [`docs` folder in the Github repository](https://github.com/goharbor/harbor/tree/master/docs) and select the appropriate `release-1.xx.x` branch.

View File

@ -3,7 +3,7 @@ title: Configure Project Quotas
weight: 25
---
To exercise control over resource use, as a Harbor system administrator you can set quotas on projects. You can limit the number of tags that a project can contain and limit the amount of storage capacity that a project can consume. You can set default quotas that apply to all projects globally.
To exercise control over resource use, as a Harbor system administrator you can set quotas on projects. You can limit the amount of storage capacity that a project can consume. You can set default quotas that apply to all projects globally.
{{< note >}}
Default quotas apply to projects that are created after you set or change the default quota. The default quota is not applied to projects that already existed before you set it.
@ -11,7 +11,7 @@ Default quotas apply to projects that are created after you set or change the de
You can also set quotas on individual projects. If you set a global default quota and you set different quotas on individual projects, the per-project quotas are applied.
By default, all projects have unlimited quotas for both tags and storage use.
By default, all projects have unlimited quotas for storage use.
1. Select the **Project Quotas** view.
@ -20,14 +20,12 @@ By default, all projects have unlimited quotas for both tags and storage use.
![Project quotas](../../img/project-quota2.png)
1. For **Default artifact count**, enter the maximum number of tags that any project can contain at a given time, or enter `-1` to set the default to unlimited.
1. For **Default storage consumption**, enter the maximum quantity of storage that any project can consume, selecting `MB`, `GB`, or `TB` from the drop-down menu, or enter `-1` to set the default to unlimited.
![Project quotas](../../img/project-quota3.png)
1. Click **OK**.
1. To set quotas on an individual project, click the 3 vertical dots next to a project and select **Edit**.
1. To set quotas on an individual project, select the project and then click **Edit**.
![Project quotas](../../img/project-quota4.png)
1. For **Default artifact count**, enter the maximum number of tags that this individual project can contain, or enter `-1` to set the default to unlimited.
1. For **Default storage consumption**, enter the maximum quantity of storage that this individual project can consume, selecting `MB`, `GB`, or `TB` from the drop-down menu.
After you set quotas, you can see how much of their quotas each project has consumed.
@ -36,18 +34,16 @@ After you set quotas, you can see how much of their quotas each project has cons
### How Harbor Calculates Resource Usage
When setting project quotas, it is useful to know how Harbor calculates tag numbers and storage use, especially in relation to image pushing, retagging, and garbage collection.
When setting project quotas, it is useful to know how Harbor calculates storage use, especially in relation to image pushing, retagging, and garbage collection.
- Harbor computes image size when blobs and manifests are pushed from the Docker client.
- Harbor computes tag counts when manifests are pushed from the Docker client.
{{< note >}}
When users push an image, the manifest is pushed last, after all of the associated blobs have been pushed successfully to the registry. If several images are pushed concurrently and if there is an insufficient number of tags left in the quota for all of them, images are accepted in the order that their manifests arrive. Consequently, an attempt to push an image might not be immediately rejected for exceeding the quota. This is because there was availability in the tag quota when the push was initiated, but by the time the manifest arrived the quota had been exhausted.
{{< /note >}}
- Shared blobs are only computed once per project. In Docker, blob sharing is defined globally. In Harbor, blob sharing is defined at the project level. As a consequence, overall storage usage can be greater than the actual disk capacity.
- Retagging images reserves and releases resources:
- If you retag an image within a project, the tag count increases by one, but storage usage does not change because there are no new blobs or manifests.
- If you retag an image from one project to another, the tag count and storage usage both increase.
- If you retag an image within a project, the storage usage does not change because there are no new blobs or manifests.
- If you retag an image from one project to another, the storage usage will increase.
- During garbage collection, Harbor frees the storage used by untagged blobs in the project.
- If the tag count reaches the limit, image blobs can be pushed into a project and storage usage is updated accordingly. You can consider these blobs to be untagged blobs. They can be removed by garbage collection, and the storage that they consume is returned after garbage colletion.
- Helm chart size is not calculated. Only tag counts are calculated.
- Helm chart size is not calculated.

View File

@ -11,30 +11,26 @@ A replication endpoint must exist before you create a replication rule. To creat
![Add a replication rule](../../../img/replication-rule1.png)
1. Click **New Replication Rule**.
1. Provide a name and description for the replication rule.
1. Select **Push-based** or **Pull-based** replication, depending on whether you want to replicate images to or from the remote registry.
1. Select **Push-based** or **Pull-based** replication, depending on whether you want to replicate artifacts to or from the remote registry.
![Replication mode](../../../img/replication-rule2.png)
1. For **Source resource filter**, identify the images to replicate.
1. For **Source resource filter**, identify the artifacts to replicate.
![Replication filters](../../../img/replication-rule3.png)
* **Name**: Replicate resources with a given name by entering an image name or fragment.
* **Name**: Replicate resources with a given name by entering an artifact name or fragment.
* **Tag**: Replicate resources with a given tag by entering a tag name or fragment.
* **Label**: Replicate resources with a given label by using the drop-down menu to select from the available labels.
* **Resource**: Replicate images, charts, or both.
* **Resource**: Replicate artifacts, charts, or both.
The name filter and tag filters support the following patterns:
* **\***: Matches any sequence of non-separator characters `/`.
* **\*\***: Matches any sequence of characters, including path separators `/`.
* **?**: Matches any single non-separator character `/`.
* **{alt1,...}**: Matches a sequence of characters if one of the comma-separated alternatives matches. are as follows:
* **\***: Matches any sequence of non-separator characters `/`.
* **\*\***: Matches any sequence of characters, including path separators `/`.
* **\*\***: Matches any sequence of characters, including path separators `/`. Note that the doublestar must appear as a path component by itself. A pattern such as /path\*\* is invalid and will be treated the same as /path*, but /path\*/\*\* should achieve the desired result.
* **?**: Matches any single non-separator character `/`.
* **{alt1,...}**: Matches a sequence of characters if one of the comma-separated alternatives matches.
**NOTE:** You must add `library` if you want to replicate the official images of Docker Hub. For example, `library/hello-world` matches the official hello-world images.
**NOTE:** You must add `library` if you want to replicate the official artifacts of Docker Hub. For example, `library/hello-world` matches the official hello-world artifacts.
Pattern | String(Match or not)
---------- | -------
@ -48,13 +44,17 @@ A replication endpoint must exist before you create a replication rule. To creat
If you do not enter a namespace, resources are placed in the same namespace as in the source registry.
![Destination and namespaces](../../../img/replication-rule4.png)
**NOTE:** Because of major API changes in the v2.0 release to support [OCI](https://github.com/opencontainers/distribution-spec).
You **can not** replicate from harbor 1.x to 2.0, and you **can not** replicate artifacts with **manifest list** from 2.0 to 1.x.
1. Use the Trigger Mode drop-down menu to select how and when to run the rule.
* **Manual**: Replicate the resources manually when needed. **Note**: Deletion operations are not replicated.
* **Scheduled**: Replicate the resources periodically by defining a cron job. **Note**: Deletion operations are not replicated.
* **Event Based**: When a new resource is pushed to the project, or an image is retagged, it is replicated to the remote registry immediately. If you select the **Delete remote resources when locally deleted**, if you delete an image, it is automatically deleted from the replication target.
* **Event Based**: When a new resource is pushed to the project, or an artifact is retagged, it is replicated to the remote registry immediately. If you select the **Delete remote resources when locally deleted**, if you delete an artifact, it is automatically deleted from the replication target.
{{< note >}}
You can filter images for replication based on the labels that are applied to the images. However, changing a label on an image does not trigger replication. Event-based replication is limited to pushing, retagging, and deleting images.
You can filter artifacts for replication based on the labels that are applied to the artifacts. However, changing a label on an artifact does not trigger replication. Event-based replication is limited to pushing, retagging, and deleting artifacts.
{{< /note >}}
![Trigger mode](../../../img/replication-rule5.png)

View File

@ -13,6 +13,7 @@ When you delete images from Harbor, space is not automatically freed up. You mus
![Garbage collection](../../img/garbage-collection.png)
1. To delete untagged artifacts, select the check box **Delete Untagged Artifacts**.
1. To run garbage collection immediately, click **GC Now**.
When you run garbage collection, Harbor goes into read-only mode. All modifications to the registry are prohibited.
@ -32,6 +33,8 @@ To avoid triggering the garbage collection process too frequently, the availabil
* **Daily**: Run garbage collection at midnight every day.
* **Weekly**: Run garbage collection at midnight every Saturday.
* **Custom**: Run garbage collection according to a `cron` job.
1. To delete untagged artifacts, select the check box **Delete Untagged Artifacts**.
1. Click **Save**.
1. Select the **History** tab to view records of the 10 most recent garbage collection runs.

View File

@ -3,12 +3,12 @@ title: Upgrade Harbor and Migrate Data
weight: 45
---
This guide covers upgrade and migration to version 1.10.0. This guide only covers migration from v1.8.x and later to the current version. If you are upgrading from an earlier version, refer to the migration guide in the `release-1.8.0` branch to upgrade to v1.8.x first, then follow this guide to perform the migration to this version.
This guide covers upgrade and migration to version 2.0.0. This guide only covers migration from v1.9.x and later to the current version. If you are upgrading from an earlier version, refer to the migration guide in the `release-1.9.0` branch to upgrade to v1.9.x first, then follow this guide to perform the migration to this version.
If you are upgrading a Harbor instance that you deployed with Helm, see [Upgrading Harbor Deployed with Helm](helm-upgrade.md).
When upgrading an existing Harbor instance to a newer version, you might need to migrate the data in your database and the settings in `harbor.cfg`.
Since the migration might alter the database schema and the settings of `harbor.cfg`, you should **always** back up your data before any migration.
When upgrading an existing Harbor instance to a newer version, you might need to migrate the settings in `harbor.yml`.
Since the migration might alter the database schema and the settings of `harbor.yml`, you should **always** back up your data before any migration.
## Notes
@ -40,30 +40,30 @@ Since the migration might alter the database schema and the settings of `harbor.
```
1. Get the latest Harbor release package from [https://github.com/goharbor/harbor/releases](https://github.com/goharbor/harbor/releases).
1. Before upgrading Harbor, perform migration.
1. Before upgrading Harbor, perform migration.
The migration tool is in harbor-prepare tools delivered as a docker image. You can pull the image from docker hub. in the following command:
The migration tool is delivered as a docker image. You can pull the image from docker hub. Replace [tag] with the new Harbor version, for example v1.10.0, in the following command:
```sh
docker pull goharbor/harbor-migrator:[tag]
docker pull goharbor/prepare:[tag]
```
Alternatively, if you are using an offline installer package, you can load it from the image tarball that is included in the offline installer package. Replace [tag] with the new Harbor version, for example v1.10.0, in the following command:
```sh
tar zxf <offline package>
docker image load -i harbor/harbor.[version].tar.gz
```
1. Upgrade the `harbor.yml` file.
1. Copy the `harbor.yml.tmp` to `harbor.yml` and upgrade it.
```sh
docker run -it --rm -v ${harbor_yml}:/harbor-migration/harbor-cfg/harbor.yml goharbor/harbor-migrator:[tag] --cfg up
docker run -it --rm -v /:/hostfs goharbor/prepare:[tag] migrate -i ${path to harbor.yml}
```
**NOTE:** The schema upgrade and data migration of the database is performed by core when Harbor starts. If the migration fails, check the core log to debug.
1. In the `./harbor` directory, run the `./install.sh` script to install the new Harbor instance.
3. In the `./harbor` directory, run the `./install.sh` script to install the new Harbor instance.
To install Harbor with components such as Notary, Clair, and chartmuseum, see [Run the Installer Script](../../install-config/run-installer-script.md) for more information.

View File

@ -3,16 +3,30 @@ title: Vulnerability Scanning
weight: 35
---
Harbor provides static analysis of vulnerabilities in images through the open source [Clair](https://github.com/coreos/clair) project.
Harbor provides static analysis of vulnerabilities in images through the open source projects [Trivy](https://github.com/aquasecurity/trivy) and [Clair](https://github.com/coreos/clair). To be able to use Trivy, Clair or both you must have enabled Trivy, Clair or both when you installed your Harbor instance (by appending installation options `--with-trivy`, `--with-clair` or both).
{{< important >}}
Clair is an optional component. To be able to use Clair you must have enabled Clair when you installed your Harbor instance.
Currently, Harbor supports only one system default scanner. The following principles will be applied to determine the system default scanner among the default installed scanners.
For a brand new installation:
If no scanner is installed, no system default scanner will be set then;
If only one scanner (either Trivy or Clair) is installed, the installed one will become the system default scanner automatically;
If both Trivy and Clair are installed, Trivy will be the system default scanner then.
For upgrades:
If the upgrading path is from the version that is >=V1.10 to current version (V2.0) and there was an existing system default scanner “ABC” is set in the previous version, that scanner "ABC" will be kept as system default scanner;
Otherwise, Harbor will do the similar operation to the above brand new installation case.
{{< /important >}}
You can also connect Harbor to your own instance of Clair or to additional vulnerability scanners by using an interrogation service. You configure additional scanners in the Harbor interface, after you have installed Harbor. For the list of additional scanners that are currently supported, see the [Harbor Compatibility List](../../install-config/harbor-compatibility-list.md#scanner-adapters).
You can also connect Harbor to your own instance of Trivy/Clair or to other additional vulnerability scanners through Harbor's embedded interrogation service. These scanners can be configured in the Harbor UI at any time after installation. For the list of additional scanners that are currently supported, see the [Harbor Compatibility List](../../install-config/harbor-compatibility-list.md#scanner-adapters).
It might be necessary to connect Harbor to other scanners for corporate compliance reasons, or because your organization already uses a particular scanner. Different scanners also use different vulnerability databases, capture different CVE sets, and apply different severity thresholds. By connecting Harbor to more than one vulnerability scanner, you broaden the scope of your protection against vulnerabilities.
For information about installing Harbor with Clair, see the [Run the Installer Script](../../install-config/run-installer-script.md).
For information about installing Harbor with Clair, see the [Run the Installer Script](../../install-config/run-installer-script.md).
You can manually initiate scanning on a particular image, or on all images in Harbor. Additionally, you can also set a policy to automatically scan all of the images at specific intervals.

View File

@ -0,0 +1,10 @@
---
title: Deployment security
weight: 31
---
Starting in version 2.0, Harbor has added capabilities to check for supported artifact types in the pluggable scanners. It will use the **consumes_mime_types** metadata of the scanner to decide whether a requested artifact is supported by this scanner. For example, helm charts cannot be scanned for vulnerabilities by any of the supported scanners like Clair or Aqua Trivy.
Harbor v2.0 now supports OCI image index, which is a higher-level manifest which points to specific image manifests, ideal for one or more platform. Scanning for OCI image index is also supported, with the scan result of the index being an aggregation of the scan results of the artifacts referenced within.
Harbor has deployment security which can prevent artifacts from being pulled if vulnerabilities are discovered. For pulling indexes, deployment security will skip this policy checking for the index artifact itself and will only apply policy checking on the referenced artifacts and at the individual artifact level and not on the index as a whole. This means when pulling Redis for ARM for example, it only checks to see if whether Redis for ARM has vulnerabilities and not impacted by whether amd64 has CVEs. This applies to CNABs as well.

View File

@ -1,14 +1,14 @@
---
title: Scan All Images
title: Scan All Artifacts
weight: 35
---
In addition to scanning individual images in projects, you can run global scans on all of the images in a Harbor instance, across all projects.
In addition to scanning individual artifacts in projects, you can run global scans on all of the artifacts in a Harbor instance, across all projects.
1. Log in to the Harbor interface with an account that has Harbor system administrator privileges.
1. Expand **Administration**, and select **Interrogation Services**.
1. Select the **Vulnerability** tab and click **Scan Now** to scan all of the images in all projects.
1. Expand **Administration**, and select **Interrogation Services**.
1. Select the **Vulnerability** tab and click **Scan Now** to scan all of the artifacts in all projects.
![Scan all artifacts](../../../img/scan-all.png)
![Scan all images](../../../img/scan-all.png)
Scanning requires intensive resource consumption. If scanning is in progress, the **Scan Now** button is unavailable.

View File

@ -0,0 +1,70 @@
---
title: Scan Individual Artifacts
weight: 30
---
1. Log in to the Harbor interface with an account that has at least project administrator privileges.
1. Go to **Projects** and select a project.
1. Select the **Scanner** tab.
The **Scanner** tab shows the details of the scanner that is currently set as the scanner to use for this project.
![Project scanner tab](../../../img/project-scanners.png)
1. Click **Edit** to select a different scanner from the list of scanners that are connected to this Harbor instance, and click **OK**.
![Project scanner tab](../../../img/select-scanner.png)
{{< note >}}
If you have selected the **Prevent vulnerable images from running** option in the project **Configuration** tab, the prevention of pulling vulnerable artifacts is determined by the scanner that is set in the project, or by the global default scanner if no scanner is configured specifically for the project. Different scanners might apply different levels of severity to artifact vulnerabilities.
{{< /note >}}
1. Select the **Repositories** tab and select a repository.
For each artifact in the repository, the **Vulnerabilities** column displays the vulnerability scanning status and related information.
![Artifact vulnerability status](../../../img/artifact-vulnerability-status.png)
1. Select a artifact, or use the check box at the top to select all artifacts in the repository, and click the **Scan** button to run the vulnerability scan on this artifact.
![Scan an artifact](../../../img/scan-artifact.png)
**NOTE**: You can start a scan at any time, unless the status is **Queued** or **Scanning**. If the database has not been fully populated, you should not run a scan. The following statuses are displayed in the **Vulnerabilities** column:
* **Not Scanned:** The artifact has never been scanned.
* **Unsupported:** The artifact is not supported by the scanner.
* **Queued:** The scanning task is scheduled but has not run yet.
* **Scanning:** The scanning task is in progress and a progress bar is displayed.
* **View log:** The scanning task failed to complete. Click **View Log** link to view the related logs.
* **Complete:** The scanning task completed successfully.
If the process completes successfully, the result indicates the overall severity level, with the total number of vulnerabilities found for each severity level, and the number of fixable vulnerabilities.
![Scan result](../../../img/scan-result.png)
* **Red:** At least one critical vulnerability found
* **Orange:** At least one high level vulnerability found
* **Yellow:** At least one medium level vulnerability found
* **Blue:** At least one low level vulnerability found
* **Green:** No vulnerabilities found
* **Grey:** Unknown vulnerabilities
1. Hover over the number of fixable vulnerabilities to see a summary of the vulnerability report.
![Vulnerability summary](../../../img/vulnerability-summary.png)
1. Click on the artifact digest to see a detailed vulnerability report.
![Vulnerability report](../../../img/artifact-detail.png)
In addition to information about the artifact, all of the vulnerabilities found in the last scan are listed. You can order or filter the list by the different columns. You can also click **Scan** in the report page to run a scan on this artifact.
## Vulnerability scanning for OCI image index
When scanning an OCI image index, Harbor will send scan requests for each of the referenced artifact which is supported by the scanner to the scanner. If the image scanning status of any referenced image is **Scanning**, the status for the OCI image index as a whole will also be **Scanning**. The scan for the index is considered successful only if all referenced images are successfully scanned. It is considered limited successful when not all referenced images are successfully scanned but at least one of referenced image is successfully scanned, otherwise it is considered failed.
![Limited successful](../../../img/limited-successful-status.png)
When an OCI image index is successfully scanned, the summary of the vulnerability report for the OCI image index is aggregated from the individual scan results of the the artifacts referenced by the index. The vulnerability report will show both sets of statistics.

View File

@ -1,59 +0,0 @@
---
title: Scan Individual Images
weight: 30
---
1. Log in to the Harbor interface with an account that has at least project administrator privileges.
1. Go to **Projects** and select a project.
1. Select the **Scanner** tab.
The **Scanner** tab shows the details of the scanner that is currently set as the scanner to use for this project.
![Project scanner tab](../../../img/project-scanners.png)
1. Click **Edit** to select a different scanner from the list of scanners that are connected to this Harbor instance, and click **OK**.
![Project scanner tab](../../../img/select-scanner.png)
{{< note >}}
If you have selected the **Prevent vulnerable images from running** option in the project **Configuration** tab, the prevention of pulling vulnerable images is determined by the scanner that is set in the project, or by the global default scanner if no scanner is configured specifically for the project. Different scanners might apply different levels of severity to image vulnerabilities.
{{< /note >}}
1. Select the **Repositories** tab and select a repository.
For each tag in the repository, the **Vulnerabilities** column displays the vulnerability scanning status and related information.
![Tag vulnerability status](../../../img/tag-vulnerability-status.png)
1. Select a tag, or use the check box at the top to select all tags in the repository, and click the **Scan** button to run the vulnerability scan on this image.
![Scan an image](../../../img/scan-image.png)
**NOTE**: You can start a scan at any time, unless the status is **Queued** or **Scanning**. If the database has not been fully populated, you should not run a scan. The following statuses are displayed in the **Vulnerabilities** column:
* **Not Scanned:** The tag has never been scanned.
* **Queued:** The scanning task is scheduled but has not run yet.
* **Scanning:** The scanning task is in progress and a progress bar is displayed.
* **View log:** The scanning task failed to complete. Click **View Log** link to view the related logs.
* **Complete:** The scanning task completed successfully.
If the process completes successfully, the result indicates the overall severity level, with the total number of vulnerabilities found for each severity level, and the number of fixable vulnerabilities.
![Scan result](../../../img/scan-result.png)
* **Red:** At least one critical vulnerability found
* **Orange:** At least one high level vulnerability found
* **Yellow:** At least one medium level vulnerability found
* **Blue:** At least one low level vulnerability found
* **Green:** No vulnerabilities found
* **Grey:** Unknown vulnerabilities
1. Hover over the number of fixable vulnerabilities to see a summary of the vulnerability report.
![Vulnerability summary](../../../img/vulnerability-summary.png)
1. Click on the tag name to see a detailed vulnerability report.
![Vulnerability report](../../../img/tag-detail.png)
In addition to information about the tag, all of the vulnerabilities found in the last scan are listed. You can order or filter the list by the different columns. You can also click **Scan** in the report page to run a scan on this image tag.

View File

@ -29,7 +29,7 @@ git clone https://github.com/goharbor/harbor
### Configuration
Edit the file **make/harbor.yml** and make necessary configuration changes such as hostname, admin password and mail server. Refer to [Harbor Installation and Configuration](../install-config/_index.md) for more info.
Copy the file **make/harbor.yml.tmp** to **make/harbor.yml**, and make necessary configuration changes such as hostname, admin password and mail server. Refer to [Harbor Installation and Configuration](../install-config/_index.md) for more info.
```sh
cd harbor

Binary file not shown.

Before

Width:  |  Height:  |  Size: 16 KiB

After

Width:  |  Height:  |  Size: 25 KiB

BIN
docs/img/addtag1.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 19 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 118 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 47 KiB

View File

@ -0,0 +1,5 @@
<svg version="1.1" width="36" height="36" viewBox="0 0 36 36" preserveAspectRatio="xMidYMid meet" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<title>bell-outline-badged</title>
<path class="clr-i-outline--badged clr-i-outline-path-1--badged" d="M18,34.28A2.67,2.67,0,0,0,20.58,32H15.32A2.67,2.67,0,0,0,18,34.28Z"></path><path class="clr-i-outline--badged clr-i-outline-path-2--badged" d="M32.51,27.83A14.4,14.4,0,0,1,30,24.9a12.63,12.63,0,0,1-1.35-4.81V15.15a10.92,10.92,0,0,0-.16-1.79,7.44,7.44,0,0,1-2.24-.84,8.89,8.89,0,0,1,.4,2.64v4.94a14.24,14.24,0,0,0,1.65,5.85,16.17,16.17,0,0,0,2.44,3H5.13a16.17,16.17,0,0,0,2.44-3,14.24,14.24,0,0,0,1.65-5.85V15.15A8.8,8.8,0,0,1,18,6.31a8.61,8.61,0,0,1,4.76,1.44A7.49,7.49,0,0,1,22.5,6c0-.21,0-.42,0-.63a10.58,10.58,0,0,0-3.32-1V3.11a1.33,1.33,0,1,0-2.67,0V4.42A10.81,10.81,0,0,0,7.21,15.15v4.94A12.63,12.63,0,0,1,5.86,24.9a14.4,14.4,0,0,1-2.47,2.93,1,1,0,0,0-.34.75v1.36a1,1,0,0,0,1,1h27.8a1,1,0,0,0,1-1V28.58A1,1,0,0,0,32.51,27.83Z"></path><circle class="clr-i-outline--badged clr-i-outline-path-1--badged clr-i-badge" cx="30" cy="6" r="5"></circle>
<rect x="0" y="0" width="36" height="36" fill-opacity="0"/>
</svg>

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 112 KiB

BIN
docs/img/deleteimage1.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 47 KiB

BIN
docs/img/deleteimage2.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

BIN
docs/img/deletetag1.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 30 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 36 KiB

After

Width:  |  Height:  |  Size: 53 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 16 KiB

After

Width:  |  Height:  |  Size: 65 KiB

BIN
docs/img/harbor_logo.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 89 KiB

BIN
docs/img/index-detail.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 77 KiB

BIN
docs/img/index-icon.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 26 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 46 KiB

BIN
docs/img/list-artifacts.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 169 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 34 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 23 KiB

After

Width:  |  Height:  |  Size: 36 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 55 KiB

After

Width:  |  Height:  |  Size: 64 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.9 KiB

After

Width:  |  Height:  |  Size: 9.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 17 KiB

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.7 KiB

After

Width:  |  Height:  |  Size: 20 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 9.9 KiB

After

Width:  |  Height:  |  Size: 7.9 KiB

View File

@ -0,0 +1,5 @@
<svg version="1.1" width="36" height="36" viewBox="0 0 36 36" preserveAspectRatio="xMidYMid meet" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<title>bell-outline-badged</title>
<path class="clr-i-outline--badged clr-i-outline-path-1--badged" d="M18,34.28A2.67,2.67,0,0,0,20.58,32H15.32A2.67,2.67,0,0,0,18,34.28Z"></path><path class="clr-i-outline--badged clr-i-outline-path-2--badged" d="M32.51,27.83A14.4,14.4,0,0,1,30,24.9a12.63,12.63,0,0,1-1.35-4.81V15.15a10.92,10.92,0,0,0-.16-1.79,7.44,7.44,0,0,1-2.24-.84,8.89,8.89,0,0,1,.4,2.64v4.94a14.24,14.24,0,0,0,1.65,5.85,16.17,16.17,0,0,0,2.44,3H5.13a16.17,16.17,0,0,0,2.44-3,14.24,14.24,0,0,0,1.65-5.85V15.15A8.8,8.8,0,0,1,18,6.31a8.61,8.61,0,0,1,4.76,1.44A7.49,7.49,0,0,1,22.5,6c0-.21,0-.42,0-.63a10.58,10.58,0,0,0-3.32-1V3.11a1.33,1.33,0,1,0-2.67,0V4.42A10.81,10.81,0,0,0,7.21,15.15v4.94A12.63,12.63,0,0,1,5.86,24.9a14.4,14.4,0,0,1-2.47,2.93,1,1,0,0,0-.34.75v1.36a1,1,0,0,0,1,1h27.8a1,1,0,0,0,1-1V28.58A1,1,0,0,0,32.51,27.83Z"></path><circle class="clr-i-outline--badged clr-i-outline-path-1--badged clr-i-badge" cx="30" cy="6" r="5"></circle>
<rect x="0" y="0" width="36" height="36" fill-opacity="0"/>
</svg>

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 89 KiB

BIN
docs/img/retag1.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 44 KiB

BIN
docs/img/retag2.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.9 KiB

BIN
docs/img/scan-artifact.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 67 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 19 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 10 KiB

After

Width:  |  Height:  |  Size: 26 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 82 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 20 KiB

After

Width:  |  Height:  |  Size: 30 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 19 KiB

After

Width:  |  Height:  |  Size: 39 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 38 KiB

After

Width:  |  Height:  |  Size: 60 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 39 KiB

After

Width:  |  Height:  |  Size: 90 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 17 KiB

After

Width:  |  Height:  |  Size: 34 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 20 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 22 KiB

After

Width:  |  Height:  |  Size: 44 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 13 KiB

After

Width:  |  Height:  |  Size: 9.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 23 KiB

After

Width:  |  Height:  |  Size: 26 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 56 KiB

After

Width:  |  Height:  |  Size: 56 KiB

View File

@ -19,6 +19,7 @@ The standard Harbor installation process involves the following stages:
1. [Download the Harbor Installer](download-installer.md)
1. [Configure HTTPS Access to Harbor](configure-https.md)
1. [Configure the Harbor YML File](configure-yml-file.md)
1. [Configure Enabling Internal TLS](configure-internal-tls.md)
1. [Run the Installer Script](run-installer-script.md)
If installation fails, see [Troubleshooting Harbor Installation](troubleshoot-installation.md).

View File

@ -0,0 +1,48 @@
---
title: Configure Internal TLS communication between Harbor Component
weight: 30
---
By default, The internal communication between Harbor's component (harbor-core,harbor-jobservice,proxy,harbor-portal,registry,registryctl,trivy_adapter,clair_adapter,chartmuseum) use HTTP protocol which might not be secure enough for some production environment. Since Harbor v2.0, TLS can be used for this internal network. In production environments, always use HTTPS is a recommended best practice.
This functionality is introduced via the `internal_tls` in `harbor.yml` file. To enabled internal TLS, set `enabled` to `true` and set the `dir` value to the path of directory that contains the internal cert files.
All certs can be automatically generated by `prepare` tool.
```bash
docker run -v /:/hostfs goharbor/prepare:v2.0 gencert -p /path/to/internal/tls/cert
```
User also can provide their own CA to generate the other certs. Just put certificate and key of the CA on internal tls cert directory and name them as `harbor_internal_ca.key` and `harbor_internal_ca.crt`.
Besides, a user can also provide the certs for all components. However, there are some constraints for the certs:
* First, all certs must be signed by a single unique CA
* Second, the filename of the internal cert and `CN` field on cert file must follow the convention listed below'
|name|usage|CN|
|---|---|---|
|`harbor_internal_ca.key`| ca's key file for internal TLS | N/A |
|`harbor_internal_ca.crt`| ca's certificate file for internal TLS | N/A |
|`core.key`| core's key file | N/A |
|`core.crt`| core's certificate file| `core` |
|`job_service.key`| job_service's key file | N/A |
|`job_service.crt`| job_service's certificate file| `jobservice` |
|`proxy.key`| proxy's key file | N/A |
|`proxy.crt`| proxy's certificate file| `proxy` |
|`portal.key`| portal's key file | N/A |
|`portal.crt`| portal's certificate file| `portal` |
|`registry.key`| registry's key file | N/A |
|`registry.crt`| registry's certificate file| `registry` |
|`registryctl.key`| registryctl's key file | N/A |
|`registryctl.crt`| registryctl's certificate file| `registryctl` |
|`notary_server.key`| notary_server's key file | N/A |
|`notary_server.crt`| notary_server's certificate file| `notary-server` |
|`notary_signer.key`| notary_signer's key file | N/A |
|`notary_signer.crt`| notary_signer's certificate file| `notary-signer` |
|`trivy_adapter.key`| trivy_adapter.'s key file | N/A |
|`trivy_adapter.crt`| trivy_adapter.'s certificate file| `trivy-adapter` |
|`clair.key`| clair's key file | N/A |
|`clair.crt`| clair's certificate file| `clair` |
|`clair_adapter.key`| clair_adapter's key file | N/A |
|`clair_adapter.crt`| clair_adapter's certificate file| `clair-adapter` |
|`chartmuseum.key`| chartmuseum's key file | N/A |
|`chartmuseum.crt`| chartmuseum's certificate file| `chartmuseum` |

View File

@ -3,16 +3,16 @@ title: Configure the Harbor YML File
weight: 35
---
You set system level parameters for Harbor in the `harbor.yml` file that is contained in the installer package. These parameters take effect when you run the `install.sh` script to install or reconfigure Harbor.
You set system level parameters for Harbor in the `harbor.yml` file that is contained in the installer package. These parameters take effect when you run the `install.sh` script to install or reconfigure Harbor.
After the initial deployment and after you have started Harbor, you perform additional configuration in the Harbor Web Portal.
After the initial deployment and after you have started Harbor, you perform additional configuration in the Harbor Web Portal.
## Required Parameters
The table below lists the parameters that must be set when you deploy Harbor. By default, all of the required parameters are uncommented in the `harbor.yml` file. The optional parameters are commented with `#`. You do not necessarily need to change the values of the required parameters from the defaults that are provided, but these parameters must remain uncommented. At the very least, you must update the `hostname` parameter.
**IMPORTANT**: Harbor does not ship with any certificates. In versions up to and including 1.9.x, by default Harbor uses HTTP to serve registry requests. This is acceptable only in air-gapped test or development environments. In production environments, always use HTTPS. If you enable Content Trust with Notary to properly sign all images, you must use HTTPS.
**IMPORTANT**: Harbor does not ship with any certificates. In versions up to and including 1.9.x, by default Harbor uses HTTP to serve registry requests. This is acceptable only in air-gapped test or development environments. In production environments, always use HTTPS. If you enable Content Trust with Notary to properly sign all images, you must use HTTPS.
You can use certificates that are signed by a trusted third-party CA, or you can use self-signed certificates. For information about how to create a CA, and how to use a CA to sign a server certificate and a client certificate, see [Configuring Harbor with HTTPS Access](configure-https.md).
<table width="100%" border="0">
@ -60,6 +60,23 @@ You can use certificates that are signed by a trusted third-party CA, or you can
<td valign="top"><code>private_key</code></td>
<td valign="top">The path to the SSL key.</td>
</tr>
<tr>
<td valign="top"><code>internal_tls</code></td>
<td valign="top">&nbsp;</td>
<td valign="top"> Use HTTPS to communicate between harbor components</td>
</tr>
<tr>
<td valign="top">&nbsp;</td>
<td valign="top"><code>enabled</code></td>
<td valign="top">Set this flag to <code>true</code> means internal tls is enabled</td>
</tr>
<tr>
<td valign="top">&nbsp;</td>
<td valign="top"><code>certificate</code></td>
<td valign="top">The path to the directory that contains internal certs and keys</td>
</tr>
<tr>
<td valign="top"><code>harbor_admin_password</code></td>
<td valign="top">None</td>
@ -95,6 +112,31 @@ You can use certificates that are signed by a trusted third-party CA, or you can
<td valign="top"><code>updaters_interval</code></td>
<td valign="top">Set an interval for Clair updates, in hours. Set to 0 to disable the updates. The default is 12 hours.</td>
</tr>
<tr>
<td valign="top"><code>trivy</code></td>
<td valign="top">&nbsp;</td>
<td valign="top">Configure Trivy scanner.</td>
</tr>
<tr>
<td valign="top">&nbsp;</td>
<td valign="top"><code>ignore_unfixed</code></td>
<td valign="top">Set the flag to <code>true</code> to display only fixed vulnerabilities. The default value is <code>false</code></td>
</tr>
<tr>
<td valign="top">&nbsp;</td>
<td valign="top"><code>skip_update</code></td>
<td valign="top">You might want to enable this flag in test or CI/CD environments to avoid GitHub rate limiting issues. If the flag is enabled you have to manually download the `trivy.db` file and mount it in the <code>/home/scanner/.cache/trivy/db/trivy.db</code> path in container. The default value is <code>false</code></td>
</tr>
<tr>
<td valign="top">&nbsp;</td>
<td valign="top"><code>insecure</code></td>
<td valign="top">Set the flag to <code>true</code> to skip verifying registry certificate. The default value is <code>false</code></td>
</tr>
<tr>
<td valign="top">&nbsp;</td>
<td valign="top"><code>github_token</code></td>
<td valign="top">Set the GitHub access token to download Trivy DB. Trivy DB is downloaded by Trivy from the GitHub release page. Anonymous downloads from GitHub are subject to the limit of 60 requests per hour. Normally such rate limit is enough for production operations. If, for any reason, it's not enough, you could increase the rate limit to 5000 requests per hour by specifying the GitHub access token. For more details on GitHub rate limiting please consult https://developer.github.com/v3/#rate-limiting .You can create a GitHub token by following the instuctions in https://help.github.com/en/github/authenticating-to-github/creating-a-personal-access-token-for-the-command-line</td>
</tr>
<tr>
<td valign="top"><code>jobservice</code></td>
<td valign="top"><code>max_job_workers</code></td>
@ -160,7 +202,7 @@ You can use certificates that are signed by a trusted third-party CA, or you can
<td valign="top">Configure when not to use a proxy, for example, <code>127.0.0.1,localhost,core,registry</code>.</td>
</tr>
</table>
## Optional Parameters
The following table lists the additional, optional parameters that you can set to configure your Harbor deployment beyond the minimum required settings. To enable a setting, you must uncomment it in `harbor.yml` by deleting the leading `#` character.

View File

@ -43,9 +43,9 @@ This document provides compatibility information for all Harbor components.
|---|----------|-----------|-----------|------------|--------------------|
| [Clair](https://github.com/goharbor/harbor-scanner-clair) |![Clair](../../img/scanners/clair.png)| CentOS |![Y](../../img/replication-adapters/right.png)|![Y](../../img/replication-adapters/right.png)| v1.10 |
| [Anchore](https://github.com/anchore/harbor-scanner-adapter) |![Anchore](../../img/scanners/anchore.png) | Anchore |![Y](../../img/replication-adapters/right.png)| N | v1.10 |
| [Trivy](https://github.com/aquasecurity/harbor-scanner-trivy)|![Trivy](../../img/scanners/trivy.png)| Aqua |![Y](../../img/replication-adapters/right.png)| N | v1.10 |
| [CSP](https://github.com/aquasecurity/harbor-scanner-aqua) |![Aqua](../../img/scanners/aqua.png)| Aqua | N | N | v1.10 |
| [DoSec](https://github.com/dosec-cn/harbor-scanner/blob/master/README_en.md)|![DoSec](../../img/scanners/dosec.png) | DoSec | N | N | v1.10 |
| [Trivy](https://github.com/aquasecurity/harbor-scanner-trivy)|![Trivy](../../img/scanners/trivy.png)| Aqua |![Y](../../img/replication-adapters/right.png)| ![Y](../../img/replication-adapters/right.png) | v1.10 |
| [CSP](https://github.com/aquasecurity/harbor-scanner-aqua) |![Aqua](../../img/scanners/aqua.png)| Aqua | ![Y](../../img/replication-adapters/right.png) | N | v1.10 |
| [DoSec](https://github.com/dosec-cn/harbor-scanner/blob/master/README_en.md)|![DoSec](../../img/scanners/dosec.png) | DoSec | ![Y](../../img/replication-adapters/right.png) | N | v1.10 |
{{< note >}}
* `Evaluated` means that the scanner implementation has been officially tested and verified.

View File

@ -4,7 +4,7 @@ title: Run the Installer Script
weight: 35
---
Once you have configured `harbor.yml` and optionally set up a storage backend, you install and start Harbor by using the `install.sh` script. Note that it might take some time for the online installer to download all of the Harbor images from Docker hub.
Once you have configured `harbor.yml` copied from `harbor.yml.tmpl` and optionally set up a storage backend, you install and start Harbor by using the `install.sh` script. Note that it might take some time for the online installer to download all of the Harbor images from Docker hub.
You can install Harbor in different configurations:

View File

@ -9,54 +9,87 @@ The action that is taken upon receiving a notification from a Harbor project dep
### Supported Events
You can define one webhook endpoint per project. Webhook notifications provide information about events in JSON format and are delivered by `HTTP` or `HTTPS POST` to an existing webhhook endpoint URL that you provide. The following table describes the events that trigger notifications and the contents of each notification.
You can define multiple webhook endpoints per project. Harbor supports two kinds of endpoints currently, `HTTP` and `SLACK`. Webhook notifications provide information about events in JSON format and are delivered by `HTTP` or `HTTPS POST` to an existing webhhook endpoint URL or Slack address that you provide. The following table describes the events that trigger notifications and the contents of each notification.
|Event|Webhook Event Type|Contents of Notification|
|---|---|---|
|Push image to registry|`IMAGE PUSH`|Repository namespace name, repository name, resource URL, tags, manifest digest, image name, push time timestamp, username of user who pushed image|
|Pull manifest from registry|`IMAGE PULL`|Repository namespace name, repository name, manifest digest, image name, pull time timestamp, username of user who pulled image|
|Delete manifest from registry|`IMAGE DELETE`|Repository namespace name, repository name, manifest digest, image name, image size, delete time timestamp, username of user who deleted image|
|Upload Helm chart to registry|`CHART PUSH`|Repository name, chart name, chart type, chart version, chart size, tag, timestamp of push, username of user who uploaded chart|
|Download Helm chart from registry|`CHART PULL`|Repository name, chart name, chart type, chart version, chart size, tag, timestamp of push, username of user who pulled chart|
|Delete Helm chart from registry|`CHART DELETE`|Repository name, chart name, chart type, chart version, chart size, tag, timestamp of delete, username of user who deleted chart|
|Image scan completed|`IMAGE SCAN COMPLETED`|Repository namespace name, repository name, tag scanned, image name, number of critical issues, number of major issues, number of minor issues, last scan status, scan completion time timestamp, vulnerability information (CVE ID, description, link to CVE, criticality, URL for any fix), username of user who performed scan|
|Image scan failed|`IMAGE SCAN FAILED`|Repository namespace name, repository name, tag scanned, image name, error that occurred, username of user who performed scan|
|Project quota exceeded|`PROJECT QUOTA EXCEED`|Repository namespace name, repository name, tags, manifest digest, image name, push time timestamp, username of user who pushed image|
|Push artifact to registry|`PUSH_ARTIFACT`|Repository namespace name, repository name, resource URL, tags, manifest digest, artifact name, push time timestamp, username of user who pushed artifact|
|Pull artifact from registry|`PULL_ARTIFACT`|Repository namespace name, repository name, manifest digest, artifact name, pull time timestamp, username of user who pulled artifact|
|Delete artifact from registry|`DELETE_ARTIFACT`|Repository namespace name, repository name, manifest digest, artifact name, artifact size, delete time timestamp, username of user who deleted image|
|Upload Helm chart to chartMuseum|`UPLOAD_CHART`|Repository name, chart name, chart type, chart version, chart size, tag, timestamp of push, username of user who uploaded chart|
|Download Helm chart from chartMuseum|`DOWNLOAD_CHART`|Repository name, chart name, chart type, chart version, chart size, tag, timestamp of push, username of user who pulled chart|
|Delete Helm chart from chartMuseum|`DELETE_CHART`|Repository name, chart name, chart type, chart version, chart size, tag, timestamp of delete, username of user who deleted chart|
|Image scan completed|`SCANNING_COMPLETED`|Repository namespace name, repository name, tag scanned, image name, number of critical issues, number of major issues, number of minor issues, last scan status, scan completion time timestamp, vulnerability information (CVE ID, description, link to CVE, criticality, URL for any fix), username of user who performed scan|
|Image scan failed|`SCANNING_FAILED`|Repository namespace name, repository name, tag scanned, image name, error that occurred, username of user who performed scan|
|Project quota exceeded|`QUOTA_EXCEED`|Repository namespace name, repository name, tags, manifest digest, artifact name, push time timestamp, username of user who pushed artifact|
|Project quota near threshold|`QUOTA_WARNING`|Repository namespace name, repository name, tags, manifest digest, artifact name, push time timestamp, username of user who pushed artifact|
|Artifact replication finished|`REPLICATION`|Repository namespace name, repository name, tags, manifest digest, artifact name, push time timestamp, username of user who trigger the replication|
#### JSON Payload Format
#### Payload Format
The webhook notification is delivered in JSON format. The following example shows the JSON notification for a push image event:
The webhook notification is delivered in JSON format. The following example shows the JSON notification for a push artifact event when using `HTTP` kind endpoint:
```json
{
"event_type": "pushImage",
"events": [
{
"project": "prj",
"repo_name": "repo1",
"tag": "latest",
"full_name": "prj/repo1",
"trigger_time": 158322233213,
"image_id": "9e2c9d5f44efbb6ee83aecd17a120c513047d289d142ec5738c9f02f9b24ad07",
"project_type": "Private"
"type": "PUSH_ARTIFACT",
"occur_at": 1586922308,
"operator": "admin",
"event_data": {
"resources": [{
"digest": "sha256:8a9e9863dbb6e10edb5adfe917c00da84e1700fa76e7ed02476aa6e6fb8ee0d8",
"tag": "latest",
"resource_url": "hub.harbor.com/test-webhook/debian:latest"
}],
"repository": {
"date_created": 1586922308,
"name": "debian",
"namespace": "test-webhook",
"repo_full_name": "test-webhook/debian",
"repo_type": "private"
}
}
}
```
when you select the Slack type, and fill a Slack incoming webhook URL as endpoint, the message you received in Slack will be like,
```json
Harbor webhook events
event_type: PUSH_ARTIFACT
occur_at: April 15th at 11:59 AM
operator: admin
event_data:
{
"resources": [
{
"digest": "sha256:8a9e9863dbb6e10edb5adfe917c00da84e1700fa76e7ed02476aa6e6fb8ee0d8",
"tag": "latest",
"resource_url": "hub.harbor.com/test-webhook/debian:latest"
}
],
"repository": {
"date_created": 1586922308,
"name": "debian",
"namespace": "test-webhook",
"repo_full_name": "test-webhook/debian",
"repo_type": "private"
}
]
}
```
### Webhook Endpoint Recommendations
The endpoint that receives the webhook should ideally have a webhook listener that is capable of interpreting the payload and acting upon the information it contains. For example, running a shell script.
There are two kinds of endpoints. For `HTTP` the endpoint that receives the webhook should ideally have a webhook listener that is capable of interpreting the payload and acting upon the information it contains. For example, running a shell script.
And for Slack endpoint, you should follow the [guide of Slack incoming webhook](https://api.slack.com/messaging/webhooks).
### Example Use Cases
You can configure your continuous integration and development infrastructure so that it performs the following types of operations when it receives a webhook notification from Harbor.
- Image push:
- Artifact push:
- Trigger a new build immediately following a push on selected repositories or tags.
- Notify services or applications that use the image that a new image is available and pull it.
- Scan the image using Clair.
- Replicate the image to remote registries.
- Notify services or applications that use the artifact that a new artifact is available and pull it.
- Scan the artifact using Clair.
- Replicate the artifact to remote registries.
- Image scanning:
- If a vulnerability is found, rescan the image or replicate it to another registry.
- If the scan passes, deploy the image.
@ -64,24 +97,30 @@ You can configure your continuous integration and development infrastructure so
### Configure Webhooks
1. Log in to the Harbor interface with an account that has at least project administrator privileges.
1. Go to **Projects**, select a project, and select **Webhooks**.
![Webhooks option](../../../img/webhooks1.png)
1. Select notify type `HTTP`, so the webhook will be send to a HTTP endpoint.
1. Select events that you want to subscribe.
1. Enter the URL for your webhook endpoint listener.
1. If your webhook listener implements authentication, enter the authentication header.
1. To implement `HTTPS POST` instead of `HTTP POST`, select the **Verifiy Remote Certficate** check box.
![Webhook URL](../../../img/webhooks2.png)
1. Click **Test Endpoint** to make sure that Harbor can connect to the listener.
1. Click **Continue** to create the webhook.
When you have created the webhook, you see the status of the different notifications and the timestamp of the last time each notification was triggered. You can click **Disable** to disable notifications.
When you have created the webhook, you can click on the arrow at the left end to see the status of the different notifications and the timestamp of the last time each notification was triggered. You can also manage the webhook by clicking the drop list button of `ACTION...` .
{{< note >}}
You can only disable and reenable all notifications. You cannot disable and enable selected notifications.
{{< /note >}}
You can modify the webhook, you can also `Enable` or `Disable` the webhook.
![Webhook Status](../../../img/webhooks3.png)

View File

@ -17,6 +17,7 @@ You can create robot accounts to run automated operations. Robot accounts have t
1. Click **New Robot Account**.
1. Enter a name and an optional description for this robot account.
1. Set expiration time for this robot account, you can also select checkbox **Never Expired** if you want to create a never expiring robot account. If not set, the expiration time of system configuration will be used for this robot account.
1. Grant permission to the robot account to push images and to push and pull Helm charts.
Robot accounts can always pull images, so you cannot deselect this option.

View File

@ -0,0 +1,13 @@
---
title: Tagging Artifacts
weight: 75
---
Harbor v2.0 now supports OCI images and OCI image indexes (https://github.com/opencontainers/image-spec/blob/master/image-index.md). An OCI image index (or OCI index) is a higher level manifest which points to a list of image manifests, ideal for one or more platforms. Both the index itself and the images referenced within are referred to as artifacts in Harbor parlance. An OCI index could hold another OCI index and so on and so forth. For any artifact referenced by an OCI index, the referenced artifact is known as the child artifact and the OCI index referencing the artifact is known as the parent artifact. We can also say that the child artifact belongs to the parent artifact or is a part of the parent artifact.
Users can add as many tags to any artifact as they wish without impacting the artifact digest or the associated storage. For an OCI index, users can add tags to the parent as well as add tags to the individual referenced artifacts within. Tags added to the parent artifact are not automatically inherited by the children artifacts. You can tag artifacts on the Harbor web console as follows:
In the Harbor interface, click on an artifact to see its current set of tags, then click 'ADD TAG', specify the name and click 'OK'
![add artifact](../../../img/addtag1.png)

View File

@ -3,29 +3,29 @@ title: Tag Immutability Rules
weight: 85
---
By default, users can repeatedly push an image with the same tag to repositories in Harbor. This causes the previous image to effectively be overwritten with each push, in that the tag now points to a different image and the image that previously used the tag now becomes tagless. This is due to the Docker implementation, that does not enforce the mapping between an image tag and the image digest. This can be undesirable in certain cases, because the tag can no longer be trusted to identify the image version. The sha256 digest remains reliable and always points to the same build, but it is not rendered in a human-readable format.
By default, users can repeatedly push an artifact with the same tag to a repository in Harbor. This causes the tag to migrate across the artifacts and every artifact that has its tag taken away becomes tagless. This is due to Docker distribution upstream which does not enforce the mapping between an image tag and the image digest. This can be undesirable in certain cases, because the tag can no longer be trusted to identify the image version. The sha256 digest remains reliable and always points to the same build, but it is not rendered in a human-readable format.
Moreover, the Docker implementation requires that deleting a tag results in the deletion of all other tags that point to the same digest, causing unwanted image deletions.
To prevent this, Harbor allows you to configure tag immutability at the project level, so that images with certain tags cannot be pushed into Harbor if their tags match existing tags. This prevents existing images from being overwritten. Tag immutability guarantees that an immutable tagged image cannot be deleted, and cannot be altered through repushing, retagging, or replication.
To prevent this, Harbor allows you to configure tag immutability at the project level, so that artifacts with certain tags cannot be pushed into Harbor if their tags match existing tags. This prevents existing artifacts from being overwritten. Tag immutability guarantees that an immutable tagged artifact cannot be deleted, and also cannot be altered in any way such as through re-pushing, re-tagging, or replication from another target registry.
Immutability rules use `OR` logic, so if you set multiple rules and a tag is matched by any of those rules, it is marked as immutable.
## How Immutable Tags Prevent Tag Deletion
Tags that share a common digest cannot be deleted even if only a single tag is configured as immutable. For example:
Since v2.0, you can delete any tag of an artifact without deleting the artifact itself. Therefore, you can lock down a particular tag by configuring an immutability rule matching this tag which means the artifact holding the tag also cannot be overwritten or deleted. However you can still delete other tags associated with this immutable artifact. Consider the follow example:
1. In a project, set an immutable tag rule that matches the image and tag `hello-world:v1`.
1. In the Docker client, pull `hello-world:v1` and retag it to `hello-world:v2`.
1. Push `hello-world:v2` to the same project.
1. In the Harbor interface, attempt to delete `hello-world:v2`.
1. In the Docker client, push `hello-world:v1` into a project.
1. In the project, set an immutable tag rule in this project that matches the image and tag `hello-world:v1`.
1. Push `hello-world:v1` to the project.
1. In your local env, retag `hello-world:v1` to `hello-world:v2`.
1. Push `hello-world:v2` to the project.
1. In the Harbor interface, attempt to delete tag `v1` and `v2` of `hello-world` sequentially.
In this case, you cannot delete `hello-world:v2` because it shares the sha256 digest with `hello-world:v1`, and `hello-world:v1` is an immutable tag.
In this case, you cannot delete tag `v1` as it's an immutable tag and you cannot delete the artifact `hello-world` holding this tag. But you can delete tag `v2` even it shares the sha256 digest with `v1`.
## Create a Tag Immutability Rule
1. Log in to the Harbor interface with an account that has at least project administrator privileges.
1. Go to **Projects**, select a project, and select **Tag Immutability**.
1. Go to **Projects**, select a project, select policy, and select **Tag Immutability**.
![Add an immutability rule](../../../img/tag-immutability.png)

View File

@ -3,7 +3,7 @@ title: Create Tag Retention Rules
weight: 80
---
A repository can rapidly accumulate a large number of image tags, many of which might not be required after a given time or once they have been superseded by a subsequent image build. These excess tags can obviously consume large quantities of storage capacity. As a Harbor system administrator, you can define rules that govern how many tags of a given repository to retain, or for how long to retain certain tags.
A repository can rapidly accumulate a large number of artifacts, many of which might not be required after a given time or once they have been superseded by a subsequent artifact build. These excess artifacts can obviously consume large quantities of storage capacity. As a Harbor system administrator, you can define rules that govern how many artifacts of a given repository to retain, or for how long to retain certain artifacts.
## How Tag Retention Rules Work
@ -13,60 +13,70 @@ A tag retention rule has 3 filters that are applied sequentially, as described i
|Order|Filter|Description|
|---|---|---|
|First|Repository or repositories|Identify the repository or repositories on which to apply the rule. You can identify repositories that either have a certain name or name fragment, or that do not have that name or name fragment. Wild cards (for example `*repo`, `repo*`, and `**`) are permitted. The repository filter is applied first to mark the repositories to which to apply the retention rule. The identified repositories are earmarked for further matching based on the tag criteria. No action is taken on the nonspecified repositories at this stage.|
|First|Repository or repositories|Identity the tags on which to apply the rule. You can identify repositories that either have a certain name or name fragment, or that do not have that name or name fragment. Wild cards (for example `*repo`, `repo*`, and `**`) are permitted. The repository filter is applied first to mark the repositories to which to apply the retention rule. The identified repositories are earmarked for further matching based on the tag criteria. No action is taken on the nonspecified repositories at this stage.|
|Second|Quantity to retain|Set which tags to retain either by specifying a maximum number of tags, or by specifying a maximum period for which to retain tags.|
|Third|Tags to retain|Identify the tag or tags on which to apply the rule. You can identify tags that either have a certain name or name fragment, or that do not have that name or name fragment. Wild cards (for example `*tag`, `tag*`, and `**`) are permitted.|
|Third|Tags to retain|Identify the tag or tags on which to apply the rule. You can identify tags that either have a certain name or name fragment, or that do not have that name or name fragment. Wild cards (for example `*tag`, `tag*`, and `**`) are permitted. Use the checkbox to select whether untagged artifacts should be captured as part of the set of artifacts eligible for tag retention.|
For information about how the `**` wildcard is applied, see https://github.com/bmatcuk/doublestar#patterns.
### Example 1
- You have 5 repositories in a project, repositories A to E.
- Repository A has 100 image tags, all of which have been pulled in the last week.
- Repositories B to E each have 6 images, none of which have been pulled in the last month.
- Repository A has 102 artifacts with 2 untagged, all of which have been pulled in the last week.
- Repositories B to E each have 7 artifacts with 1 untagged artifact, none of which have been pulled in the last month.
- You set the repository filter to `**`, meaning that all repositories in the project are included.
- You set the retention policy to retain the 10 most recently pulled images in each repository.
- You set the tag filter to `**`, meaning that all tags in the repository are included.
- You set the retention policy to retain the 10 most recently pulled artifacts in each repository.
- You set the tag filter to `**`, keep "untagged artifacts" unchecked, meaning that all artifacts with at least one tag in the repository are included.
In this example the rule retains the 10 most recently pulled images in repository A, and all 6 of the images in each of the 4 repositories B to E. So, a total of 34 image tags are retained in the project. In other words, the rule does not treat all of the images in repositories A to E as a single pool from which to choose the 10 most recent images. So, even if the 11th to 100th tags in repository A have been pulled more recently than any of the tags in repositories B to E, all of the tags in repositories B to E are retained, because each of those repositories has fewer than 10 tags.
In this example the rule retains the 10 most recently pulled tagged artifacts in repository A, and the 6 of the artifacts in each of the 4 repositories B to E. So, a total of 34 artifacts are retained in the project.
In other words, the rule does not treat all of the artifacts in repositories A to E as a single pool from which to choose the 10 most recent artifacts.
So, even if the 11th to 100th tags in repository A have been pulled more recently than any of the tags in repositories B to E, all of the tagged artifacts in repositories B to E are retained, because each of those repositories has fewer than 10 tags, and all untagged artifacts are deleted.
### Example 2
This example uses the same project and repositories as example 1, but sets the retention policy to retain the images in each repository that have been pulled in the last 7 days.
This example uses the same project and repositories as example 1, but sets the retention policy to retain the artifacts in each repository that have been pulled in the last 7 days.
In this case, all of the images in repository A are retained because they have been pulled in the last 7 days. None of the images in repositories B to E are retained, because none of them has been pulled in the last week. In this example, 100 images are retained, as opposed to 34 images in example 1.
In this case, all of the 100 tagged artifacts in repository A are retained because they have been pulled in the last 7 days. None of the artifacts in repositories B to E are retained, because none of them has been pulled in the last week. In this example, 100 artifacts are retained, as opposed to 34 artifacts in example 1.
And all untagged artifacts are deleted.
### Example 3
This example uses the same project and repositories as example 2, but checked "untagged artifacts", then all artifacts in repository A are retained.
In this case, all of the 103 artifacts in repository A are retained because they have been pulled in the last 7 days. None of the artifacts in repositories B to E are retained, because none of them has been pulled in the last week. In this example, 103 artifacts are retained, as opposed to 100 artifacts in example 2.
And all untagged artifacts are retained.
### Tag Retention Rules and Native Docker Tag Deletion
**WARNING**: Due to native Docker tag deletion behavior, there is an issue with the current retention policy implementation. If you have multiple tags that refer to the same SHA digest, and if a subset of these tags are marked for deletion by a configured retention policy, all of the remaining tags would also be deleted. This violates the retention policy, so in this case all of the tags are retained. This issue will be addressed in a future update release, so that tag retention policies can delete tags without deleting the digest and other shared tags.
**Note**: If an artifact has several tags, and only a partial set of tags are matched via the retention policy, then the artifact and all its tags will be retained. In other words, retention is matched at the tag level but retention / deletion is carried out at the artifact level, with retention fully preserving the artifact including all of its tags.
For example, you have following tags, listed according to their push time, and all of them refer to the same SHA digest:
- `harbor-1.8`, pushed 8/14/2019 12:00am
- `harbor-1.8`, pushed 8/14/2019 01:00am
- `harbor-release`, pushed 8/14/2019 03:00am
- `harbor-nightly`, pushed 8/14/2019 06:00am
- `harbor-latest`, pushed 8/14/2019 09:00am
You configure a retention policy to retain the two latest tags that match `harbor-*`, so that `harbor-rc` and `harbor-latest` are deleted. However, since all tags refer to the same SHA digest, this policy would also delete the tags `harbor-1.8` and `harbor-release`, so all tags are retained.
You configure a retention policy to retain the two latest tags that match `harbor-*`, so that `harbor-rc` and `harbor-latest` are retained. However, since all tags refer to the same SHA digest, this policy would also retain the tags `harbor-1.8` and `harbor-release`, so all tags are retained.
## Combining Rules on a Repository
You can define up to 15 rules per project. You can apply multiple rules to a repository or set of repositories. When you apply multiple rules to a repository, they are applied with `OR` logic rather than with `AND` logic. In this way, there is no prioritization of application of the rules on a given repository. Rules run concurrently in the background, and the resulting sets from each rule are combined at the end of the run.
### Example 3
### Example 4
This example uses the same project and repositories as examples 1 and 2, but sets two rules:
- Rule 1: Retain all of the images in each repository that have been pulled in the last 7 days.
- Rule 2: Retain a maximum number of 10 images in each repository.
- Rule 1: Retain all of the artifacts in each repository that have been pulled in the last 7 days.
- Rule 2: Retain a maximum number of 10 artifacts in each repository.
For repository A, rule 1 retains all of the images because they have all been pulled in the last week. Rule 2 retains the 10 most recently pulled images. So, since the two rules are applied with an `OR` relationship, all 100 images are retained in repository A.
For repository A, rule 1 retains all of the 100 tagged artifacts because they have all been pulled in the last week. Rule 2 retains the 10 most recently pulled artifacts. So, since the two rules are applied with an `OR` relationship, all 100 artifacts are retained in repository A.
For repositories B-E, rule 1 will retain 0 images as no images are pulled in the last week. Rule 2 will retain all 6 images because 6 < 10. So, since the two rules are applied with an `OR` relationship, for repositories B-E, each repository will keep all 6 images.
For repositories B-E, rule 1 will retain 0 artifacts as no artifacts are pulled in the last week. Rule 2 will retain all 6 artifacts because 6 < 10. So, since the two rules are applied with an `OR` relationship, for repositories B-E, each repository will keep all 6 artifacts.
In this example, all of the images are retained.
In this example, all of the artifacts are retained.
### Example 4
### Example 5
This example uses a different repository to the previous examples.
@ -80,8 +90,8 @@ This example uses a different repository to the previous examples.
|`4.4-your_repo-prod`|`4.4-your_repo-rc`|`4.4-your_repo-release`|
- You define three tag retention rules on this repository:
- Retain the 10 most recently pushed image tags that start with `2`.
- Retain the 10 most recently pushed image tags that end with `-prod`.
- Retain the 10 most recently pushed artifacts that start with `2`.
- Retain the 10 most recently pushed artifacts that end with `-prod`.
- Retain all tags that do not include `2.1-your_repo-prod`.
In this example, the rules are applied to the following 7 tags:
@ -94,6 +104,8 @@ In this example, the rules are applied to the following 7 tags:
- `3.1-your_repo-prod`
- `4.4-your_repo-prod`
Because there are no untagged artifacts, checking the checkbox makes no difference.
## How Tag Retention Rules Interact with Project Quotas
The Harbor system administrator can set a maximum on the number of tags that a project can contain and the amount of storage that it can consume. For information about project quotas, see [Configure Project Quotas](../../administration/configure-project-quotas/_index.md).
@ -103,7 +115,7 @@ If you set a quota on a project, this quota cannot be exceeded. The quota is app
## Configure Tag Retention Rules
1. Log in to the Harbor interface with an account that has at least project administrator privileges.
1. Go to **Projects**, select a project, and select **Tag Retention**.
1. Go to **Projects**, select a project, select **Policy**, and select **Tag Retention**.
![Tag options](../../../img/tag-retention1.png)
1. Click **Add Rule** to add a rule.
@ -119,16 +131,16 @@ If you set a quota on a project, this quota cannot be exceeded. The quota is app
- `**` to apply the rule to all of the repositories in the project.
If you selected **matching**, the rule is applied to the repositories you identified. If you selected **excluding**, the rule is applied to all of the repositories in the project except for the ones that you identified.
1. In the **By image count or number of days** drop-down menu, define how many tags to retain or the period to retain tags.
1. In the **By artifact count or number of days** drop-down menu, define how many tags to retain or the period to retain tags.
![Select retention criteria](../../../img/tag-retention3.png)
|Option|Description|
|---|---|
|**retain the most recently pushed # images**|Enter the maximum number of images to retain, keeping the ones that have been pushed most recently. There is no maximum age for an image.|
|**retain the most recently pulled # images**|Enter the maximum number of images to retain, keeping only the ones that have been pulled recently. There is no maximum age for an image.|
|**retain the images pushed within the last # days**|Enter the number of days to retain images, keeping only the ones that have been pushed during this period. There is no maximum number of images.|
|**retain the images pulled within the last # days**|Enter the number of days to retain images, keeping only the ones that have been pulled during this period. There is no maximum number of images.|
|**retain always**|Always retain the images identified by this rule.|
|**retain the most recently pushed # artifacts**|Enter the maximum number of artifacts to retain, keeping the ones that have been pushed most recently. There is no maximum age for an artifact.|
|**retain the most recently pulled # artifacts**|Enter the maximum number of artifacts to retain, keeping only the ones that have been pulled recently. There is no maximum age for an artifact.|
|**retain the artifacts pushed within the last # days**|Enter the number of days to retain artifacts, keeping only the ones that have been pushed during this period. There is no maximum number of artifacts.|
|**retain the artifacts pulled within the last # days**|Enter the number of days to retain artifacts, keeping only the ones that have been pulled during this period. There is no maximum number of artifacts.|
|**retain always**|Always retain the artifacts identified by this rule.|
1. In the **Tags** drop-down menu, select **matching** or **excluding**.
1. In the **Tags** text box, identify the tags on which to apply the rule.

View File

@ -0,0 +1,50 @@
---
title: Deleting Artifacts
weight: 75
---
Harbor v2.0 now supports OCI images and OCI image indexes (https://github.com/opencontainers/image-spec/blob/master/image-index.md). An OCI image index (or OCI index) is a higher level manifest which points to a list of image manifests, ideal for one or more platforms. Both the index itself and the images referenced within are referred to as artifacts in Harbor parlance. An OCI index could hold another OCI index and so on and so forth. For any artifact referenced by an OCI index, the referenced artifact is known as the child artifact and the OCI index referencing the artifact is known as the parent artifact. We can also say that the child artifact belongs to the parent artifact or is a part of the parent artifact.
An example of an OCI image index
```
{
"schemaVersion": 2,
"manifests": [
{
"mediaType": "application/vnd.oci.image.manifest.v1+json",
"size": 7143,
"digest": "sha256:e692418e4cbaf90ca69d05a66403747baa33ee08806650b51fab815ad7fc331f",
"platform": {
"architecture": "ppc64le",
"os": "linux"
}
},
{
"mediaType": "application/vnd.oci.image.manifest.v1+json",
"size": 7682,
"digest": "sha256:5b0bcabd1ed22e9fb1310cf6c2dec7cdef19f0ad69efa1f392e94a4333501270",
"platform": {
"architecture": "amd64",
"os": "linux"
}
}
],
"annotations": {
"com.example.key1": "value1",
"com.example.key2": "value2"
}
}
```
**Deleting Artifact**:
When an artifact is not referenced by any OCI index, you can delete the artifact freely which will delete its manifest and all associated tags.
When an artifact is referenced by an OCI index, you cannot delete it. In order to delete this artifact, you must first delete all OCI indexes referencing this artifact first, remembering that an artifact can be referenced by multiple parents artifacts pushed onto Harbor by different users. So when deleting an OCI index holding 9 children artifacts not referenced by any other index and 1 child artifact referenced by another index, only 9 out of 10 children artifacts will be deleted.
To delete any artifact in the Harbor interface, click on the artifact and select 'Delete' and confirm.
![delete image1](../../../img/deleteimage1.png)
![delete image2](../../../img/deleteimage2.png)

View File

@ -0,0 +1,14 @@
---
title: Detagging Artifacts
weight: 75
---
Harbor v2.0 now supports OCI images and OCI image indexes (https://github.com/opencontainers/image-spec/blob/master/image-index.md). An OCI image index (or OCI index) is a higher level manifest which points to a list of image manifests, ideal for one or more platforms. Both the index itself and the images referenced within are referred to as artifacts in Harbor parlance. An OCI index could hold another OCI index and so on and so forth. For any artifact referenced by an OCI index, the referenced artifact is known as the child artifact and the OCI index referencing the artifact is known as the parent artifact. We can also say that the child artifact belongs to the parent artifact or is a part of the parent artifact.
Users can delete any existing tag from an artifact without deleting the artifact digest and all other existing tags. For an OCI index, users can delete tags from the parent as well as from the referenced artifacts within. Tags removed from the parent artifact are not automatically removed from children artifacts. For example, you can tag artifacts as follows:
In the Harbor interface, click on an artifact to see its current set of tags, then select the tag you wish to delete and click 'REMOVE TAG', and then click 'OK'
![delete tag](../../../img/deletetag1.png)
You can remove all tags from an artifact without deleting the artifact manifest itself. The artifact is still visible on the web console with nothing listed under 'Tags '

View File

@ -5,7 +5,9 @@ weight: 95
[Helm](https://helm.sh) is a package manager for [Kubernetes](https://kubernetes.io). Helm uses a packaging format called [charts](https://docs.helm.sh/developing_charts). Since version 1.6.0 Harbor is now a composite cloud-native registry which supports both container image management and Helm charts management. Access to Helm charts in Harbor is controlled by [role-based access controls (RBAC)](https://en.wikipedia.org/wiki/Role-based_access_control) and is restricted by projects.
## Manage Helm Charts via the Harbor Interface
There are two places to manage helm charts. First one is in the ChartMuseum which is provided by Harbor from version 1.6.0. The second one is in the OCI-compatible registry which is provided by Harbor from version 2.0.0. This means you can now manage Helm charts alongside your container images through the same set of projects and repositories.
## Manage Helm Charts with the ChartMuseum in Harbor Interface
### List charts
@ -74,9 +76,9 @@ Clicking the chart version number link will open the chart version details view.
Clicking the `DOWNLOAD` button on the top right will start the downloading process.
## Working with the Helm CLI
## Working with ChartMuseum via the Helm CLI
As a helm chart repository, Harbor can work smoothly with Helm CLI. About how to install Helm CLI, please refer [install helm](https://docs.helm.sh/using_helm/#installing-helm). Run command `helm version` to make sure the version of Helm CLI is v2.9.1+.
As a helm chart repository, Harbor can interoperate with Helm CLI. To install Helm CLI, please refer [install helm](https://helm.sh/docs/intro/install/). Run command `helm version` to make sure the version of Helm CLI is v2.9.1+.
```sh
helm version
@ -136,7 +138,7 @@ Search the chart with the keyword if you're not sure where it is:
```sh
helm search hello
#NAME CHART VERSION APP VERSION DESCRIPTION
#NAME CHART VERSION APP VERSION DESCRIPTION
#local/hello-helm 0.3.10 1.3 A Helm chart for Kubernetes
#myrepo/chart_repo/hello-helm 0.1.10 1.2 A Helm chart for Kubernetes
#myrepo/library/hello-helm 0.3.10 1.3 A Helm chart for Kubernetes
@ -150,3 +152,54 @@ helm install --ca-file=ca.crt --username=admin --password=Passw0rd --version 0.1
For other more helm commands like how to sign a chart, please refer to the [helm doc](https://docs.helm.sh/helm/#helm).
## Manage Helm Charts with the OCI-compatible registry of Harbor
Helm 3 now supports registry operations for an OCI-compatible registry including pushing and pulling. To install the latest Helm CLI, please refer [install helm](https://helm.sh/docs/intro/install/). Please also run `helm version` command to make sure the version of Helm CLI is v3.0.0+.
```sh
helm version
#version.BuildInfo{Version:"v3.2.1", GitCommit:"fe51cd1e31e6a202cba7dead9552a6d418ded79a", GitTreeState:"clean", GoVersion:"go1.13.10"}
```
### Login to the OCI-compatible registry of Harbor
Before pull/push helm charts with the OCI-compatible registry of Harbor, Harbor should be logged with `helm registry login` command.
```sh
helm registry login xx.xx.xx.xx
```
{{< note >}}
The CA file used by the Harbor is necessary to be trusted in the system due to an [issue](https://github.com/helm/helm/issues/6324) in Helm.
{{< /note >}}
### Push Charts to the artifact Repository with the CLI
After logging in, run the `helm chart save` command to save a chart directory which will prepare the artifact for the pushing.
```sh
helm chart save dummy-chart xx.xx.xx.xx/library/dummy-chart
```
When the chart was saved run the `helm chart push` command to push your charts:
```sh
helm chart push xx.xx.xx.xx/library/dummy-chart:version
```
### Pull Charts from the artifact Repository with the CLI
To pull charts from the the OCI-compatible registry of Harbor, run the `helm chart pull` command just like pulling image via docker cli.
```sh
helm chart pull xx.xx.xx.xx/library/dummy-chart:version
```
### Manage Helm Charts artifacts in Harbor Interface
The charts pushed to the OCI-compatible registry of Harbor are treated like any other type of artifact. We can list, copy, delete, update labels, get details, add or remove tags for them just like we can for container images.
![chart artifact details](../../../img/chart-artifact-details.png)

View File

@ -0,0 +1,41 @@
---
title: Repositories
weight: 75
---
A repository is a collection of artifacts. Since version v2.0, in addition to container images, Harbor can manage different kinds of artifacts that are bundled in OCI-compatible format, such as helm chart (requires helm v3), CNAB, OPA bundle, etc.
### List Repositories
Click your project to enter the project detail page after successful logging in. Click the "Repositories" tab to view the list of of repositories.
![list_repositories](../../../img/list-repositories.png)
### Description of a repository
Click the repository, then click the "Info" tab. You can view the description of the project. Users with project admin, master or developer role can click the "Edit" button to edit the description. You can style the description via Markdown syntax.
![edit_repository_description](../../../img/edit-repository-description.png)
### List artifacts in a repository
Click the "Artifacts" tab to view the list of artifacts in a repository.
Each artifact is identified by its sha256 digest in the list of artifacts, and different types of artifacts can be distinguished by the icon on the left of the digest. Hover your mouse on the icon you can see the name of the type.
By clicking the icon in the column **Pull Command**, the command to pull the artifact in the row of the icon will be copied to the clipboard.
The column **Annotations** in the grid shows the manifest annotations of the artifact, which are a set of key-value pairs. More details about the annotations please refer to (https://github.com/opencontainers/image-spec/blob/master/annotations.md).
The column **Push Time** in the grid shows the time each artifact is pushed to the registry.
![list_artifacts](../../../img/list-artifacts.png)
By clicking the search icon in the top right of the list of artifacts, you can user different types of filters to filter the items in the artifact list. You can choose to filter by type, tags, labels. Particularly, if you choose to filter by tags, you can choose to view only the tagged or untagged artifacts.
![filter_artifacts](../../../img/filter-artifacts.png)
Since Harbor v2.0.0, [Image index](https://raw.githubusercontent.com/opencontainers/image-spec/master/image-index.md) can also be managed as an artifact in a repository. If an artifact is an index, there will be a folder icon on the right side of its digest.
![image_index](../../../img/index-icon.png)
Click the folder icon, you can see the list of artifacts that is referenced by the index. The artifacts in this view is read only. i.e. You can not remove an artifact from an index via Harbor's UI, and none of the actions like 'copy digest', 'add labels', 'copy' are available.
![index_detail](../../../img/index-detail.png)

View File

@ -1,17 +1,19 @@
---
title: Retagging Images
title: Retagging Artifacts
weight: 75
---
You can retag images in Harbor. Users with sufficient privileges can retag images to different repositories and projects. For example, you can retag images as follows:
User with sufficient privileges can copy artifacts in Harbor to different repositories and projects. For example, you can copy images as follows:
- `release/app:stg` --> `release/app:prd`
- `develop/app:v1.0` --> `release/app:v1.0`
To retag an image, you must have read permission (guest role or above) in the source project and write permission (developer role or above) in the target project.
To copy an artifact, you must have read permission (guest role or above) in the source project and write permission (developer role or above) in the target project.
In the Harbor interface, select the image to retag, and click `Retag`.
In the Harbor interface, select the artifact to copy, and click `Copy`.
![retag image](../../../img/retag-image.png)
![retag artifact](../../../img/retag1.png)
In the Retag windown, enter the project name, repository name, the new tag name, and click **Confirm**.
In the Retag window, enter the project name, repository name, the new tag name, and click **Confirm**.
![retag artifact](../../../img/retag2.png)

View File

@ -25,6 +25,7 @@ COPY src/portal /build_dir
ENV NPM_CONFIG_REGISTRY=${npm_registry}
RUN npm install --unsafe-perm
RUN npm run generate-build-timestamp
RUN node --max_old_space_size=2048 'node_modules/@angular/cli/bin/ng' build --prod
FROM ${harbor_base_namespace}/harbor-portal-base:${harbor_base_image_version}

View File

@ -33,14 +33,14 @@ func main() {
log.Fatalf("Failed to connect to Database, error: %v\n", err)
}
defer db.Close()
c := make(chan int, 1)
c := make(chan struct{}, 1)
go func() {
err := db.Ping()
for ; err != nil; err = db.Ping() {
log.Printf("Failed to Ping DB, sleep for 1 second.\n")
log.Println("Failed to Ping DB, sleep for 1 second.")
time.Sleep(1 * time.Second)
}
c <- 1
c <- struct{}{}
}()
select {
case <-c:
@ -54,11 +54,11 @@ func main() {
log.Fatalf("Failed to check schema_migrations table, error: %v \n", err)
}
if tblCount == 0 {
log.Printf("schema_migrations table does not exist, skip.\n")
log.Println("schema_migrations table does not exist, skip.")
return
}
if colCount > 0 {
log.Printf("schema_migrations table does not require update, skip.\n")
log.Println("schema_migrations table does not require update, skip.")
return
}
if _, err := db.Exec(pgSQLDelRows); err != nil {
@ -67,5 +67,5 @@ func main() {
if _, err := db.Exec(pgSQLAlterStmt); err != nil {
log.Fatalf("Failed to update database, error: %v \n", err)
}
log.Printf("Done updating database. \n")
log.Println("Done updating database.")
}

View File

@ -201,6 +201,10 @@ func constructReplicationPayload(event *event.ReplicationEvent) (*model.Payload,
}
func getMetadataFromResource(resource string) (namespace, nameAndTag string) {
// Usually resource format likes 'library/busybox:v1', but it could be 'busybox:v1' in docker registry
meta := strings.Split(resource, "/")
if len(meta) == 1 {
return "", meta[0]
}
return meta[0], meta[1]
}

View File

@ -92,7 +92,15 @@ func (f *fakedReplicationMgr) GetExecution(int64) (*daoModels.Execution, error)
func (f *fakedReplicationMgr) ListTasks(...*daoModels.TaskQuery) (int64, []*daoModels.Task, error) {
return 0, nil, nil
}
func (f *fakedReplicationMgr) GetTask(int64) (*daoModels.Task, error) {
func (f *fakedReplicationMgr) GetTask(id int64) (*daoModels.Task, error) {
if id == 1 {
return &daoModels.Task{
ExecutionID: 1,
// project info not included when replicating with docker registry
SrcResource: "alpine:[v1]",
DstResource: "gxt/alpine:[v1] ",
}, nil
}
return &daoModels.Task{
ExecutionID: 1,
SrcResource: "library/alpine:[v1]",
@ -254,14 +262,14 @@ func TestReplicationHandler_Handle(t *testing.T) {
wantErr bool
}{
{
name: "ImagePreprocessHandler Want Error 1",
name: "ReplicationHandler Want Error 1",
args: args{
data: "",
},
wantErr: true,
},
{
name: "ImagePreprocessHandler 1",
name: "ReplicationHandler 1",
args: args{
data: &event.ReplicationEvent{
OccurAt: time.Now(),
@ -269,6 +277,16 @@ func TestReplicationHandler_Handle(t *testing.T) {
},
wantErr: false,
},
{
name: "ReplicationHandler with docker registry",
args: args{
data: &event.ReplicationEvent{
OccurAt: time.Now(),
ReplicationTaskID: 1,
},
},
wantErr: false,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {

View File

@ -250,7 +250,7 @@ func (bc *basicController) GetRegistrationByProject(projectID int64, options ...
}
}
return registration, err
return registration, nil
}
// Ping ...

View File

@ -15,6 +15,7 @@
package scanner
import (
"fmt"
"testing"
"github.com/goharbor/harbor/src/common/models"
@ -46,8 +47,8 @@ func TestController(t *testing.T) {
suite.Run(t, new(ControllerTestSuite))
}
// SetupSuite prepares env for the controller test suite
func (suite *ControllerTestSuite) SetupSuite() {
// SetupTest prepares env for the controller test suite
func (suite *ControllerTestSuite) SetupTest() {
suite.mMgr = &scannertesting.Manager{}
suite.mMeta = new(MockProMetaManager)
@ -227,6 +228,31 @@ func (suite *ControllerTestSuite) TestGetRegistrationByProject() {
assert.Equal(suite.T(), "forUT", r.Name)
}
// TestGetRegistrationByProjectWhenPingError tests GetRegistrationByProject
func (suite *ControllerTestSuite) TestGetRegistrationByProjectWhenPingError() {
m := make(map[string]string, 1)
m[proScannerMetaKey] = "uuid"
// Configured at project level
var pid int64 = 1
suite.sample.UUID = "uuid"
suite.mMeta.On("Get", pid, []string{proScannerMetaKey}).Return(m, nil)
suite.mMgr.On("Get", "uuid").Return(suite.sample, nil)
// Ping error
mc := &v1testing.Client{}
mc.On("GetMetadata").Return(nil, fmt.Errorf("getMetadata error"))
mcp := &v1testing.ClientPool{}
mocktesting.OnAnything(mcp, "Get").Return(mc, nil)
suite.c.clientPool = mcp
r, err := suite.c.GetRegistrationByProject(pid)
require.NoError(suite.T(), err)
assert.Equal(suite.T(), "unhealthy", r.Health)
}
// TestPing ...
func (suite *ControllerTestSuite) TestPing() {
meta, err := suite.c.Ping(suite.sample)

View File

@ -23,6 +23,10 @@ const (
ViolateForeignKeyConstraintCode = "VIOLATE_FOREIGN_KEY_CONSTRAINT"
// DIGESTINVALID ...
DIGESTINVALID = "DIGEST_INVALID"
// MANIFESTINVALID ...
MANIFESTINVALID = "MANIFEST_INVALID"
// UNSUPPORTED is for digest UNSUPPORTED error
UNSUPPORTED = "UNSUPPORTED"
)
// NotFoundError is error for the case of object not found

View File

@ -54,9 +54,9 @@ type authorizer struct {
}
func (a *authorizer) Modify(req *http.Request) error {
// Nil URL means this is the first time the authorizer is called
// Nil underlying authorizer means this is the first time the authorizer is called
// Try to connect to the registry and determine the auth scheme
if a.url == nil {
if a.authorizer == nil {
// to avoid concurrent issue
a.Lock()
defer a.Unlock()
@ -74,7 +74,7 @@ func (a *authorizer) Modify(req *http.Request) error {
}
func (a *authorizer) initialize(u *url.URL) error {
if a.url != nil {
if a.authorizer != nil {
return nil
}
url, err := url.Parse(u.Scheme + "://" + u.Host + "/v2/")

View File

@ -142,5 +142,8 @@ func (a *authorizer) fetchToken(scopes []*scope) (*token, error) {
if err = json.Unmarshal(body, token); err != nil {
return nil, err
}
if len(token.Token) == 0 && len(token.AccessToken) > 0 {
token.Token = token.AccessToken
}
return token, nil
}

View File

@ -19,7 +19,8 @@
"build": "ng build --aot",
"release": "ng build --prod",
"build-mock-api-server": "tsc -p server",
"mock-api-server": "npm run build-mock-api-server && node server/dist/server/src/mock-api.js"
"mock-api-server": "npm run build-mock-api-server && node server/dist/server/src/mock-api.js",
"generate-build-timestamp": "node scripts/generate-build-timestamp.js"
},
"private": true,
"dependencies": {

View File

@ -0,0 +1,19 @@
/**
* generate timestamp for each production build
*/
const fs = require('fs');
const data = fs.readFileSync('src/environments/environment.prod.ts', 'utf8').split('\n');
let buildTimestampIndex = 0;
data.forEach((item,index) => {
if(item.indexOf('buildTimestamp') !== -1) {
buildTimestampIndex = index;
}
});
if (buildTimestampIndex > 0) {
const timestamp = new Date().getTime();
data[buildTimestampIndex] = ` buildTimestamp: ${timestamp},`;
fs.writeFileSync('src/environments/environment.prod.ts', data.join('\n'), 'utf8');
}

View File

@ -81,19 +81,15 @@
</clr-vertical-nav-group>
</div>
<div>
<div class="vertical-nav-footer">
<ng-container *ngFor="let theme of themeArray;let i=index">
<ng-container *ngIf="theme.showStyle === styleMode">
<a class="nav-link nav-icon theme-select"
(click)="themeChanged(theme)">
<clr-icon size="20" *ngIf="styleMode ==='DARK'" shape="sun" class="is-solid"></clr-icon>
<clr-icon size="20" *ngIf="styleMode ==='LIGHT'" shape="moon" class="is-solid"></clr-icon>
<ng-container *ngFor="let theme of themeArray;let i=index">
<ng-container *ngIf="theme.showStyle === styleMode">
<a clrVerticalNavLink (click)="themeChanged(theme)">
<clr-icon clrVerticalNavIcon size="20" *ngIf="styleMode ==='DARK'" shape="sun" class="is-solid"></clr-icon>
<clr-icon clrVerticalNavIcon size="20" *ngIf="styleMode ==='LIGHT'" shape="moon" class="is-solid"></clr-icon>
{{ theme.text | translate }}
</a>
</ng-container>
</ng-container>
</div>
</ng-container>
</ng-container>
<clr-vertical-nav-group routerLinkActive="active">
<clr-icon shape="network-globe" clrVerticalNavIcon></clr-icon>
{{'SIDE_NAV.API_EXPLORER' | translate}}

View File

@ -32,22 +32,6 @@ clr-vertical-nav {
justify-content: space-between;
}
}
.vertical-nav-footer {
margin: 5px 23px;
a {
display: inline-block;
line-height: 0;
padding: 0;
height: 24px;
&:hover {
background: transparent;
cursor: default;
}
.api-button {
margin: 0;
}
}
}
}
.font-size-13 {
font-size: 13px;
@ -82,23 +66,3 @@ clr-vertical-nav {
.right {
text-align: right;
}
.theme-select {
width: 5.4rem;
display: flex;
align-items: center;
justify-content: flex-start;
height: 100%;
font-size: 14px;
letter-spacing: 1px;
cursor: pointer;
&:hover {
opacity: 1;
}
clr-icon {
position: static;
transform: none;
margin-right: .2rem;
min-width: 20px;
}
}

View File

@ -110,8 +110,8 @@ export class GroupComponent implements OnInit, OnDestroy {
});
// batchInfo.id = group.id;
let deletionMessage = new ConfirmationMessage(
"MEMBER.DELETION_TITLE",
"MEMBER.DELETION_SUMMARY",
"GROUP.DELETION_TITLE",
"GROUP.DELETION_SUMMARY",
nameArr.join(","),
this.selectedGroups,
ConfirmationTargets.PROJECT_MEMBER,
@ -185,7 +185,7 @@ export class GroupComponent implements OnInit, OnDestroy {
}
get canDeleteGroup(): boolean {
return (
this.selectedGroups.length === 1 &&
this.selectedGroups.length >= 1 &&
this.session.currentUser.has_admin_role
);
}

View File

@ -13,7 +13,7 @@
<span class="spinner spinner-inline" [hidden]="!checkOnGoing"></span>
</div>
<clr-control-error *ngIf="!isNameValid" class="tooltip-content">
{{ nameTooltipText | translate }}
<span id="name-error">{{ nameTooltipText | translate }}</span>
</clr-control-error>
</div>
</div>
@ -61,7 +61,7 @@
</form>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-outline" (click)="onCancel()">{{'BUTTON.CANCEL' | translate}}</button>
<button type="button" class="btn btn-primary" [disabled]="!isValid" (click)="onSubmit()">{{'BUTTON.OK' | translate}}</button>
<button id="new-project-cancel" type="button" class="btn btn-outline" (click)="onCancel()">{{'BUTTON.CANCEL' | translate}}</button>
<button id="new-project-ok" type="button" class="btn btn-primary" [disabled]="!isValid" (click)="onSubmit()">{{'BUTTON.OK' | translate}}</button>
</div>
</clr-modal>

View File

@ -7,14 +7,23 @@ import { ClarityModule } from '@clr/angular';
import { FormsModule } from '@angular/forms';
import { MessageHandlerService } from '../../shared/message-handler/message-handler.service';
import { ProjectService } from "../../../lib/services";
import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
import { of } from 'rxjs';
import { delay } from 'rxjs/operators';
describe('CreateProjectComponent', () => {
let component: CreateProjectComponent;
let fixture: ComponentFixture<CreateProjectComponent>;
const mockProjectService = {
checkProjectExists: function() {
checkProjectExists: function(name: string) {
if (name === 'test') {
return of({status: 200}).pipe(delay(10));
} else {
return of({status: 404}).pipe(delay(10));
}
},
createProject: function () {
return of(true);
}
};
const mockMessageHandlerService = {
@ -25,6 +34,7 @@ describe('CreateProjectComponent', () => {
beforeEach(async(() => {
TestBed.configureTestingModule({
imports: [
BrowserAnimationsModule,
FormsModule,
ClarityModule,
TranslateModule.forRoot()
@ -50,4 +60,53 @@ describe('CreateProjectComponent', () => {
it('should create', () => {
expect(component).toBeTruthy();
});
it('should open and close', async () => {
let modelBody: HTMLDivElement;
modelBody = fixture.nativeElement.querySelector(".modal-body");
expect(modelBody).toBeFalsy();
component.createProjectOpened = true;
fixture.detectChanges();
await fixture.whenStable();
modelBody = fixture.nativeElement.querySelector(".modal-body");
expect(modelBody).toBeTruthy();
const cancelButton: HTMLButtonElement = fixture.nativeElement.querySelector("#new-project-cancel");
cancelButton.click();
fixture.detectChanges();
await fixture.whenStable();
modelBody = fixture.nativeElement.querySelector(".modal-body");
expect(modelBody).toBeFalsy();
});
it('should check project name', async () => {
fixture.autoDetectChanges(true);
component.createProjectOpened = true;
await fixture.whenStable();
const nameInput: HTMLInputElement = fixture.nativeElement.querySelector("#create_project_name");
nameInput.blur();
nameInput.dispatchEvent(new Event('blur'));
await fixture.whenStable();
let el: HTMLSpanElement;
el = fixture.nativeElement.querySelector('#name-error');
expect(el).toBeTruthy();
nameInput.value = "test";
nameInput.dispatchEvent(new Event("input"));
nameInput.blur();
nameInput.dispatchEvent(new Event('blur'));
await fixture.whenStable();
el = fixture.nativeElement.querySelector('#name-error');
expect(el).toBeTruthy();
nameInput.value = "test1";
nameInput.dispatchEvent(new Event("input"));
nameInput.blur();
nameInput.dispatchEvent(new Event('blur'));
await fixture.whenStable();
el = fixture.nativeElement.querySelector('#name-error');
expect(el).toBeFalsy();
const okButton: HTMLButtonElement = fixture.nativeElement.querySelector("#new-project-ok");
okButton.click();
await fixture.whenStable();
const modelBody: HTMLDivElement = fixture.nativeElement.querySelector(".modal-body");
expect(modelBody).toBeFalsy();
});
});

View File

@ -161,10 +161,20 @@
<clr-dg-row *ngFor="let artifact of artifactList" [clrDgItem]="artifact" >
<clr-dg-cell class="truncated flex-max-width">
<div class="cell white-normal">
<img class="artifact-icon" [title]="artifact.type"
<img *ngIf="artifact?.type !== 'IMAGE';else elseBlock" class="artifact-icon" [title]="artifact.type"
[src]="artifact.type | selectArtifactIcon" />
&nbsp; &nbsp;
<a href="javascript:void(0)" class="max-width-100" (click)="goIntoArtifactSummaryPage(artifact)"
<ng-template #elseBlock>
<clr-tooltip>
<div clrTooltipTrigger class="level-border">
<img class="artifact-icon" [title]="artifact.type"
[src]="artifact.type | selectArtifactIcon" />
</div>
<clr-tooltip-content clrPosition="top-right" clrSize="lg" *clrIfOpen>
<span>Docker and the Docker logo are trademarks or registered trademarks of Docker, Inc. in the United States and/or other countries.</span>
</clr-tooltip-content>
</clr-tooltip>
</ng-template>
<a href="javascript:void(0)" class="max-width-100 margin-left-5" (click)="goIntoArtifactSummaryPage(artifact)"
title="{{artifact.digest}}">
{{ artifact.digest | slice:0:15}}</a>
<clr-tooltip *ngIf="artifact?.references && artifact?.references?.length">
@ -316,4 +326,4 @@
</clr-dg-footer>
</clr-datagrid>
</div>
</div>
</div>

View File

@ -418,4 +418,7 @@ clr-datagrid {
}
.no-border:focus {
outline: none;
}
}
.margin-left-5 {
margin-left: 5px;
}

View File

@ -29,7 +29,12 @@
<clr-dg-column [clrDgField]="'version'">{{'VULNERABILITY.GRID.COLUMN_VERSION' | translate}}</clr-dg-column>
<clr-dg-column [clrDgField]="'fix_version'">{{'VULNERABILITY.GRID.COLUMN_FIXED' | translate}}</clr-dg-column>
<clr-dg-placeholder>{{'VULNERABILITY.CHART.TOOLTIPS_TITLE_ZERO' | translate}}</clr-dg-placeholder>
<clr-dg-placeholder>
<span *ngIf="hasScanned();else elseBlock">{{'VULNERABILITY.STATE.OTHER_STATUS' | translate}}</span>
<ng-template #elseBlock>
{{'VULNERABILITY.CHART.TOOLTIPS_TITLE_ZERO' | translate}}
</ng-template>
</clr-dg-placeholder>
<clr-dg-row *clrDgItems="let res of scanningResults">
<clr-dg-cell>
<span *ngIf="!res.links || res.links.length === 0">{{res.id}}</span>
@ -73,4 +78,4 @@
</clr-dg-footer>
</clr-datagrid>
</div>
</div>
</div>

View File

@ -181,6 +181,13 @@ export class ArtifactVulnerabilitiesComponent implements OnInit, OnDestroy {
return this.hasViewInitWithDelay && this.resultBarChartComponent
&& (this.resultBarChartComponent.queued || this.resultBarChartComponent.scanning || this.resultBarChartComponent.error);
}
hasScanned(): boolean {
return this.hasViewInitWithDelay && this.resultBarChartComponent
&& !(this.resultBarChartComponent.completed
|| this.resultBarChartComponent.error
|| this.resultBarChartComponent.queued
|| this.resultBarChartComponent.scanning);
}
handleScanOverview(scanOverview: any): any {
if (scanOverview) {
return scanOverview[DEFAULT_SUPPORTED_MIME_TYPE];

View File

@ -14,8 +14,23 @@
<clr-icon class="rotate-90 arrow-back" shape="arrow" size="36" (click)="onBack()"></clr-icon>
</div>
<div class="title-block">
<h2 class="custom-h2 center-align-items"><img class="artifact-icon" [title]="artifact.type"
[src]="artifact.type | selectArtifactIcon" /> {{artifact?.digest | slice:0:15}} <clr-icon size="25" *ngIf="artifact?.references && artifact?.references?.length" class="icon-folder" shape="folder"></clr-icon></h2>
<h2 class="custom-h2 center-align-items">
<img *ngIf="artifact?.type !== 'IMAGE';else elseBlock" class="artifact-icon" [title]="artifact.type"
[src]="artifact.type | selectArtifactIcon" />
<ng-template #elseBlock>
<clr-tooltip>
<div clrTooltipTrigger class="level-border">
<img class="artifact-icon" [title]="artifact.type"
[src]="artifact.type | selectArtifactIcon" />
</div>
<clr-tooltip-content clrPosition="top-right" clrSize="lg" *clrIfOpen>
<span>Docker and the Docker logo are trademarks or registered trademarks of Docker, Inc. in the United States and/or other countries.</span>
</clr-tooltip-content>
</clr-tooltip>
</ng-template>
<span class="margin-left-10px">{{artifact?.digest | slice:0:15}}</span>
<clr-icon size="25" *ngIf="artifact?.references && artifact?.references?.length" class="icon-folder margin-left-10px" shape="folder"></clr-icon>
</h2>
</div>
</div>
<ng-container *ngIf="!loading">

View File

@ -21,13 +21,10 @@
.center-align-items {
display: flex;
align-items: center;
clr-icon {
margin-left: 10px;
}
img {
margin-right: 10px;
}
}
.artifact-icon {
width: 25px;
}
}
.margin-left-10px {
margin-left: 10px;
}

View File

@ -4,7 +4,7 @@
<clr-dg-action-bar>
<div class="clr-row">
<div class="clr-col-7">
<button id="new-webhook" type="button" class="btn btn-secondary" (click)="newWebhook()">
<button [disabled]="!hasCreatPermission" [clrLoading]="addBtnState" id="new-webhook" type="button" class="btn btn-secondary" (click)="newWebhook()">
<clr-icon shape="plus" size="16"></clr-icon>
{{'WEBHOOK.NEW_WEBHOOK' | translate}}
</button>
@ -13,7 +13,7 @@
<clr-icon class="clr-icon" shape="caret down"></clr-icon></span>
<clr-dropdown-menu *clrIfOpen>
<button clrDropdownItem (click)="switchWebhookStatus()"
[disabled]="!(selectedRow && selectedRow.length === 1)">
[disabled]="!(selectedRow && selectedRow.length === 1) || !hasUpdatePermission">
<span id="toggle-webhook">
<span *ngIf="selectedRow[0] && !selectedRow[0].enabled">
<clr-icon class="margin-top-2" size="16" shape="success-standard"></clr-icon>
@ -26,13 +26,13 @@
</span>
</button>
<button clrDropdownItem (click)="editWebhook()"
class="btn btn-secondary" [disabled]="!(selectedRow && selectedRow.length === 1)">
class="btn btn-secondary" [disabled]="!(selectedRow && selectedRow.length === 1) || !hasUpdatePermission">
<clr-icon class="margin-top-0" size="16" shape="pencil"></clr-icon>
<span id="edit-webhook" class="margin-left-10">{{'BUTTON.EDIT' | translate}}</span>
</button>
<div class="dropdown-divider"></div>
<button clrDropdownItem (click)="deleteWebhook()"
class="btn btn-secondary" [disabled]="!(selectedRow && selectedRow.length >= 1)">
class="btn btn-secondary" [disabled]="!(selectedRow && selectedRow.length >= 1) || !hasUpdatePermission">
<clr-icon class="margin-top-0" size="16" shape="times"></clr-icon>
<span id="delete-webhook"
class="margin-left-10">{{'BUTTON.DELETE' | translate}}</span>

View File

@ -17,6 +17,7 @@ import { AddWebhookFormComponent } from "./add-webhook-form/add-webhook-form.com
import { InlineAlertComponent } from "../../shared/inline-alert/inline-alert.component";
import { AddWebhookComponent } from "./add-webhook/add-webhook.component";
import { ConfirmationDialogComponent } from "../../../lib/components/confirmation-dialog";
import { UserPermissionService } from '../../../lib/services';
describe('WebhookComponent', () => {
let component: WebhookComponent;
let fixture: ComponentFixture<WebhookComponent>;
@ -92,6 +93,11 @@ describe('WebhookComponent', () => {
}
}
};
const mockUserPermissionService = {
getPermission() {
return of(true).pipe(delay(0));
}
};
beforeEach(async(() => {
TestBed.configureTestingModule({
@ -118,6 +124,7 @@ describe('WebhookComponent', () => {
{ provide: WebhookService, useValue: mockWebhookService },
{ provide: MessageHandlerService, useValue: mockMessageHandlerService },
{ provide: ActivatedRoute, useValue: mockActivatedRoute },
{ provide: UserPermissionService, useValue: mockUserPermissionService },
]
})
.compileComponents();

Some files were not shown because too many files have changed in this diff Show More