-
Notifications
You must be signed in to change notification settings - Fork 6
Feat: Add Dagger Pipelines to Harbor #65
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
c93da7f
6c620dc
19f4958
01dba8a
c83f2d1
440f53e
ebdfb54
0f67947
8007c2e
71f2ea8
e8c2e47
bb7162f
ea4110c
de65768
ebc340a
f15638c
257afeb
171d9b4
70b03c9
6a1abab
cc97ec0
50c4048
ce86b43
9f809f1
91d2fa6
2210373
ebaa0c4
a8336a7
bd67811
e80b940
682eaaa
aaff6fe
7be31c1
747d54d
63b61d6
da2e863
4729d15
aeea1a5
5a9c1f6
dadc33b
1070e03
11c101c
dd36169
c6f9c91
783f396
f7bdfd2
aac2fd9
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -8,6 +8,9 @@ | |
| * Add date here... Add signature here... | ||
| - Add your reason here... | ||
|
|
||
| * Aug 12 2025 <[email protected]> | ||
| - Refresh base image | ||
|
|
||
| * Oct 24 2024 <[email protected]> | ||
| - Refresh base image | ||
|
|
||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,4 @@ | ||
| /dagger.gen.go linguist-generated | ||
| /internal/dagger/** linguist-generated | ||
| /internal/querybuilder/** linguist-generated | ||
| /internal/telemetry/** linguist-generated |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,5 @@ | ||
| /dagger.gen.go | ||
| /internal/dagger | ||
| /internal/querybuilder | ||
| /internal/telemetry | ||
| /.env | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,115 @@ | ||
| # Dagger Harbor Setup and Usage Guide | ||
|
|
||
| ## Introduction | ||
|
|
||
| This guide explains how to use Dagger to build, run, and test a Harbor setup locally. | ||
|
|
||
| ## Prerequisites | ||
|
|
||
| - Dagger installed | ||
| - Harbor source code available | ||
| - Generate `consts.go` | ||
|
|
||
| ## Getting Started | ||
|
|
||
| ### Generate `consts.go` file | ||
| ```bash | ||
| go run ./.dagger/scripts/parseMakefile.go | ||
| ``` | ||
|
|
||
| ### Step 1: Build and Spin Up Harbor Components Locally | ||
|
|
||
| Run the following command to build and start the necessary Harbor components inside Dagger: | ||
|
|
||
| ```bash | ||
| dagger call run-dev up -v | ||
| ``` | ||
|
|
||
| This command will: | ||
|
|
||
| - Build the Harbor components. | ||
| - Spin up the Harbor backend inside Dagger, similar to running the entire Harbor server. | ||
| - Bind Harbor to port `8080`. | ||
|
|
||
| ### Step 2: Start the Portal | ||
|
|
||
| After running the Harbor backend, you can move to the portal directory to spin up the Harbor portal: | ||
|
|
||
| ```bash | ||
| cd ./src/portal | ||
| ``` | ||
|
|
||
| > **Note:** The current portal image has some issues. | ||
| So follow the instructions in the `./src/portal/README.md` for setup. | ||
|
|
||
| Make sure to configure the portal to connect to the Harbor backend by setting the `target-harbor-server` in the portal's configuration to: | ||
|
|
||
| ```bash | ||
| http://localhost:8080 | ||
| ``` | ||
|
|
||
| This ensures the portal connects to the Harbor running inside Dagger. | ||
|
|
||
| ### Step 3: Running Harbor Locally | ||
|
|
||
| Once both Harbor backend and the portal are set up, you will have a working Harbor setup. You can now use this setup for building, running, and testing Harbor locally. | ||
|
|
||
| ## Available Functions in Dagger | ||
|
|
||
| You can list all available functions in Dagger by running: | ||
|
|
||
| ```bash | ||
| dagger functions | ||
| ``` | ||
|
|
||
| This will display a list of functions you can use. Currently, we have the following functions: | ||
|
|
||
| ### 1. **publish-all-images** | ||
|
|
||
| Publishes all images in the registry. | ||
|
|
||
| Example usage: | ||
|
|
||
| ```bash | ||
| dagger call publish-all-images --registry-username=harbor-cli --registry=demo.goharbor.io --registry-password=env:REGPASS --image-tags v3.0.0 --version v3.0.0 --debugbin=false --project-name=library/dagger-test -vvv | ||
| ``` | ||
|
|
||
| - `-vvv` flag is used for highly verbose output. You can remove this flag for a less verbose output. | ||
| - Feel free to change the version and registry flags according to your needs. | ||
|
|
||
| ### 2. **publish-image** | ||
|
|
||
| Publishes a specific image package. | ||
|
|
||
| Example usage: | ||
|
|
||
| ```bash | ||
| dagger call publish-image --registry-username=admin --registry=ttl.sh --registry-password=env:REGPASS --image-tags v3.2.2 --version v3.0 --pkg registryctl --debugbin=false --project-name=library/dagger-test -vvv -i | ||
| ``` | ||
|
|
||
| This will publish the `registryctl` package. | ||
|
|
||
| ### 3. **build-binary** | ||
|
|
||
| Builds specific Harbor binaries for a given platform. | ||
|
|
||
| Example usage: | ||
|
|
||
| ```bash | ||
| dagger call build-binary --pkg core --platform "linux/amd64" --version v2.12.2 --debugbin=false export --path=bin/harbor_core | ||
| ``` | ||
|
|
||
| This command will build the `core` package for the `linux/amd64` platform and export the binary to `harbor_core`. | ||
|
|
||
| #### Extras | ||
| Use these to pull the `dagger.json` and `.dagger` folder | ||
| In case if you want to use dagger in other branches this might be helpful. | ||
| Also while using this don't forget to Generate consts file based on the branch | ||
| ``` | ||
| oras pull bupd/harbor-dagger-dir:latest | ||
| oras pull bupd/harbor-dagger-json:latest | ||
| ``` | ||
|
|
||
| ## Conclusion | ||
|
|
||
| By following the above steps, you can have a fully functional Harbor setup running inside Dagger. You can use this setup for local development and testing. The available Dagger functions like `publish-all-images`, `publish-image`, and `build-binary` make it easy to manage Harbor images and binaries. |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,7 @@ | ||
| appname = Harbor | ||
| # runmode = prod | ||
| runmode = dev | ||
| enablegzip = true | ||
|
|
||
| [prod] | ||
| httpport = 8080 |
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| @@ -0,0 +1,51 @@ | ||||||||||||||||||||||||||
| CONFIG_PATH=/etc/core/app.conf | ||||||||||||||||||||||||||
| UAA_CA_ROOT=/etc/core/certificates/uaa_ca.pem | ||||||||||||||||||||||||||
| _REDIS_URL_CORE=redis://redis:6379?idle_timeout_seconds=30 | ||||||||||||||||||||||||||
| SYNC_QUOTA=true | ||||||||||||||||||||||||||
| _REDIS_URL_REG=redis://redis:6379/1?idle_timeout_seconds=30 | ||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| LOG_LEVEL=debug | ||||||||||||||||||||||||||
| EXT_ENDPOINT=http://localhost | ||||||||||||||||||||||||||
| DATABASE_TYPE=postgresql | ||||||||||||||||||||||||||
| POSTGRESQL_HOST=postgresql | ||||||||||||||||||||||||||
| POSTGRESQL_PORT=5432 | ||||||||||||||||||||||||||
| POSTGRESQL_USERNAME=postgres | ||||||||||||||||||||||||||
| POSTGRESQL_PASSWORD=root123 | ||||||||||||||||||||||||||
| POSTGRESQL_DATABASE=registry | ||||||||||||||||||||||||||
| POSTGRESQL_SSLMODE=disable | ||||||||||||||||||||||||||
|
Comment on lines
+10
to
+15
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🛠️ Refactor suggestion Also avoid committing DB credentials. POSTGRESQL_PASSWORD=root123 should be injected, even in dev. Apply: -POSTGRESQL_PASSWORD=root123
+POSTGRESQL_PASSWORD=${POSTGRESQL_PASSWORD:-devpassword}📝 Committable suggestion
Suggested change
🤖 Prompt for AI Agents |
||||||||||||||||||||||||||
| POSTGRESQL_MAX_IDLE_CONNS=100 | ||||||||||||||||||||||||||
| POSTGRESQL_MAX_OPEN_CONNS=900 | ||||||||||||||||||||||||||
| POSTGRESQL_CONN_MAX_LIFETIME=5m | ||||||||||||||||||||||||||
| POSTGRESQL_CONN_MAX_IDLE_TIME=0 | ||||||||||||||||||||||||||
| REGISTRY_URL=http://registry:5000 | ||||||||||||||||||||||||||
| PORTAL_URL=http://portal:8080 | ||||||||||||||||||||||||||
| TOKEN_SERVICE_URL=http://core:8080/service/token | ||||||||||||||||||||||||||
| HARBOR_ADMIN_PASSWORD=Harbor12345 | ||||||||||||||||||||||||||
| MAX_JOB_WORKERS=10 | ||||||||||||||||||||||||||
| CORE_SECRET=D1fWkYKg6OQgISeP | ||||||||||||||||||||||||||
| JOBSERVICE_SECRET=gVQJX0AlVjstElN8 | ||||||||||||||||||||||||||
| WITH_TRIVY=False | ||||||||||||||||||||||||||
|
Comment on lines
+25
to
+27
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Hardcoded secrets committed to VCS (critical). CORE_SECRET, JOBSERVICE_SECRET, and REGISTRY_CREDENTIAL_PASSWORD are real-looking secrets. Even for dev, keep them out of Git; load via Dagger Secrets, env injection, or a local .env not tracked. Suggested minimal hardening (placeholders + env expansion): -CORE_SECRET=D1fWkYKg6OQgISeP
-JOBSERVICE_SECRET=gVQJX0AlVjstElN8
+CORE_SECRET=${CORE_SECRET:?set CORE_SECRET via dev secrets}
+JOBSERVICE_SECRET=${JOBSERVICE_SECRET:?set JOBSERVICE_SECRET via dev secrets}
@@
-REGISTRY_CREDENTIAL_PASSWORD=TRJUhYbJgSjXZWAj3oLEet3ugJ3nAOk3
+REGISTRY_CREDENTIAL_PASSWORD=${REGISTRY_CREDENTIAL_PASSWORD:?set REGISTRY_CREDENTIAL_PASSWORD}Follow-up:
I can provide a Dagger snippet to load these from the host or a secret store. Also applies to: 37-37 🧰 Tools🪛 Gitleaks (8.27.2)25-25: Detected a Generic API Key, potentially exposing access to various services and sensitive operations. (generic-api-key) 26-26: Detected a Generic API Key, potentially exposing access to various services and sensitive operations. (generic-api-key) 🤖 Prompt for AI Agents |
||||||||||||||||||||||||||
| CORE_URL=http://core:8080 | ||||||||||||||||||||||||||
| CORE_LOCAL_URL=http://127.0.0.1:8080 | ||||||||||||||||||||||||||
| JOBSERVICE_URL=http://jobservice:8080 | ||||||||||||||||||||||||||
| TRIVY_ADAPTER_URL=http://trivy-adapter:8080 | ||||||||||||||||||||||||||
| REGISTRY_STORAGE_PROVIDER_NAME=filesystem | ||||||||||||||||||||||||||
| READ_ONLY=false | ||||||||||||||||||||||||||
| RELOAD_KEY= | ||||||||||||||||||||||||||
| REGISTRY_CONTROLLER_URL=http://registryctl:8080 | ||||||||||||||||||||||||||
| REGISTRY_CREDENTIAL_USERNAME=harbor_registry_user | ||||||||||||||||||||||||||
| REGISTRY_CREDENTIAL_PASSWORD=TRJUhYbJgSjXZWAj3oLEet3ugJ3nAOk3 | ||||||||||||||||||||||||||
| CSRF_KEY= | ||||||||||||||||||||||||||
| ROBOT_SCANNER_NAME_PREFIX=FFTP6U3S | ||||||||||||||||||||||||||
| PERMITTED_REGISTRY_TYPES_FOR_PROXY_CACHE=docker-hub,harbor,azure-acr,ali-acr,aws-ecr,google-gcr,quay,docker-registry,github-ghcr,jfrog-artifactory | ||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| HTTP_PROXY= | ||||||||||||||||||||||||||
| HTTPS_PROXY= | ||||||||||||||||||||||||||
| NO_PROXY=db,localhost,redis,log,exporter,postgresql,trivy-adapter,portal,.internal,registry,127.0.0.1,jobservice,nginx,.local,core,registryctl | ||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| PORT=8080 | ||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| QUOTA_UPDATE_PROVIDER=db | ||||||||||||||||||||||||||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,9 @@ | ||
| #!/bin/sh | ||
|
|
||
| # Execute the command (passed as $1 arg) | ||
| echo "Executing: dlv --headless=true --listen=0.0.0.0:4001 --accept-multiclient --log-output=debugger,debuglineerr,gdbwire,lldbout,rpc --log=true --continue --api-version=2 exec $1" | ||
|
|
||
| # Start the dlv process in the background | ||
| # /root/go/bin/dlv exec --headless --listen localhost:$2 $1 | ||
| dlv --headless=true --listen=0.0.0.0:4001 --accept-multiclient --log-output=debugger,debuglineerr,gdbwire,lldbout,rpc --log=true --continue --api-version=2 exec $1 | ||
| # dlv --headless=true --listen=0.0.0.0:4001 --accept-multiclient --log-output=debugger,debuglineerr,gdbwire,lldbout,rpc --log=true --api-version=2 attach $pid |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,47 @@ | ||
| # original config | ||
| --- | ||
| #Protocol used to serve | ||
| protocol: "http" | ||
|
|
||
| #Server listening port | ||
| port: 8080 | ||
|
|
||
| #Worker pool | ||
| worker_pool: | ||
| #Worker concurrency | ||
| workers: 10 | ||
| backend: "redis" | ||
| #Additional config if use 'redis' backend | ||
| redis_pool: | ||
| #redis://[arbitrary_username:password@]ipaddress:port/database_index | ||
| redis_url: redis://redis:6379/2?idle_timeout_seconds=30 | ||
| namespace: "harbor_job_service_namespace" | ||
| idle_timeout_second: 3600 | ||
| #Loggers for the running job | ||
| job_loggers: | ||
| # The jobLoggers backend name, only support "STD_OUTPUT", "FILE" and/or "DB" | ||
| - name: "STD_OUTPUT" | ||
| level: "DEBUG" # INFO/DEBUG/WARNING/ERROR/FATAL | ||
| - name: "FILE" | ||
| level: "DEBUG" | ||
| settings: # Customized settings of logger | ||
| base_dir: "/var/log/jobs" | ||
| sweeper: | ||
| duration: 1 #days | ||
| settings: # Customized settings of sweeper | ||
| work_dir: "/var/log/jobs" | ||
|
|
||
| #Loggers for the job service | ||
| loggers: | ||
| - name: "STD_OUTPUT" # Same with above | ||
| level: "DEBUG" | ||
|
|
||
|
|
||
| reaper: | ||
| # the max time to wait for a task to finish, if unfinished after max_update_hours, the task will be mark as error, but the task will continue to run, default value is 24, | ||
| max_update_hours: 24 | ||
| # the max time for execution in running state without new task created | ||
| max_dangling_hours: 168 | ||
|
|
||
| # the max size of job log returned by API, default is 10M | ||
| max_retrieve_size_mb: 10 |
| Original file line number | Diff line number | Diff line change | ||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| @@ -0,0 +1,17 @@ | ||||||||||||||||||
| CORE_SECRET=D1fWkYKg6OQgISeP | ||||||||||||||||||
| REGISTRY_URL=http://registry:5000 | ||||||||||||||||||
| JOBSERVICE_SECRET=gVQJX0AlVjstElN8 | ||||||||||||||||||
| CORE_URL=http://core:8080 | ||||||||||||||||||
|
Comment on lines
+1
to
+4
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 💡 Verification agent 🧩 Analysis chainRemove committed secrets; inject via Dagger/CI secrets and rotate immediately.
Apply this diff to redact and document: -CORE_SECRET=D1fWkYKg6OQgISeP
+## Inject via Dagger secret or env at runtime (e.g., dagger -e CORE_SECRET=...).
+CORE_SECRET=REPLACE_ME
-JOBSERVICE_SECRET=gVQJX0AlVjstElN8
+## Inject via Dagger secret or env at runtime.
+JOBSERVICE_SECRET=REPLACE_ME
...
-REGISTRY_CREDENTIAL_PASSWORD=TRJUhYbJgSjXZWAj3oLEet3ugJ3nAOk3
+## Inject via Dagger secret or env at runtime.
+REGISTRY_CREDENTIAL_PASSWORD=REPLACE_METo confirm no secrets remain: If you want, I can provide a follow-up patch to:
Also applies to: 10-15 🏁 Script executed: #!/bin/bash
# Fail on high-entropy strings resembling secrets (quick sweep).
rg -nP '(?i)(secret|passwd|password|token|apikey|key)\s*[:=]\s*[A-Za-z0-9+/=]{16,}' -C2Length of output: 15970 Remove hardcoded secrets in .dagger/config/jobservice/env .dagger/config/jobservice/env
-CORE_SECRET=D1fWkYKg6OQgISeP
+CORE_SECRET=REPLACE_ME
-JOBSERVICE_SECRET=gVQJX0AlVjstElN8
+JOBSERVICE_SECRET=REPLACE_ME📝 Committable suggestion
Suggested change
🧰 Tools🪛 Gitleaks (8.27.2)1-1: Detected a Generic API Key, potentially exposing access to various services and sensitive operations. (generic-api-key) 3-3: Detected a Generic API Key, potentially exposing access to various services and sensitive operations. (generic-api-key) 🤖 Prompt for AI Agents |
||||||||||||||||||
| REGISTRY_CONTROLLER_URL=http://registryctl:8080 | ||||||||||||||||||
| JOBSERVICE_WEBHOOK_JOB_MAX_RETRY=3 | ||||||||||||||||||
| JOBSERVICE_WEBHOOK_JOB_HTTP_CLIENT_TIMEOUT=3 | ||||||||||||||||||
|
|
||||||||||||||||||
|
|
||||||||||||||||||
| HTTP_PROXY= | ||||||||||||||||||
| HTTPS_PROXY= | ||||||||||||||||||
| NO_PROXY=db,localhost,redis,log,exporter,postgresql,trivy-adapter,portal,.internal,registry,127.0.0.1,jobservice,nginx,.local,core,registryctl | ||||||||||||||||||
| REGISTRY_CREDENTIAL_USERNAME=harbor_registry_user | ||||||||||||||||||
| REGISTRY_CREDENTIAL_PASSWORD=TRJUhYbJgSjXZWAj3oLEet3ugJ3nAOk3 | ||||||||||||||||||
|
|
||||||||||||||||||
|
|
||||||||||||||||||
|
|
||||||||||||||||||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,42 @@ | ||
| # original conf | ||
| worker_processes auto; | ||
| pid /tmp/nginx.pid; | ||
|
|
||
| events { | ||
| worker_connections 1024; | ||
| } | ||
|
|
||
| http { | ||
|
|
||
| client_body_temp_path /tmp/client_body_temp; | ||
| proxy_temp_path /tmp/proxy_temp; | ||
| fastcgi_temp_path /tmp/fastcgi_temp; | ||
| uwsgi_temp_path /tmp/uwsgi_temp; | ||
| scgi_temp_path /tmp/scgi_temp; | ||
|
|
||
| server { | ||
| listen 8080; | ||
| server_name localhost; | ||
|
|
||
| root /usr/share/nginx/html; | ||
| index index.html index.htm; | ||
| include /etc/nginx/mime.types; | ||
|
|
||
| gzip on; | ||
| gzip_min_length 1000; | ||
| gzip_proxied expired no-cache no-store private auth; | ||
| gzip_types text/plain text/css application/json application/javascript application/x-javascript text/xml application/xml application/xml+rss text/javascript; | ||
|
|
||
| location /devcenter-api-2.0 { | ||
| try_files $uri $uri/ /swagger-ui-index.html; | ||
| } | ||
|
|
||
| location / { | ||
| try_files $uri $uri/ /index.html; | ||
| } | ||
|
|
||
| location = /index.html { | ||
| add_header Cache-Control "no-store, no-cache, must-revalidate"; | ||
| } | ||
| } | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🛠️ Refactor suggestion
Ignore the real registry passwd to avoid committing secrets.
Add the concrete htpasswd path to this ignore list.
Apply:
/dagger.gen.go /internal/dagger /internal/querybuilder /internal/telemetry /.env + /config/registry/passwd📝 Committable suggestion
🤖 Prompt for AI Agents