From 3ebd62b409ee13fab0531b9ee9399ceec3b9b18f Mon Sep 17 00:00:00 2001 From: Aditya Chopra Date: Sun, 21 Dec 2025 01:50:41 +0530 Subject: [PATCH 1/9] create config used by harbor instance Signed-off-by: Aditya Chopra --- test/e2e/config/core/app.conf | 7 ++++ test/e2e/config/core/env | 51 ++++++++++++++++++++++++++++ test/e2e/config/core/private_key.pem | 27 +++++++++++++++ test/e2e/config/run_env.sh | 27 +++++++++++++++ 4 files changed, 112 insertions(+) create mode 100644 test/e2e/config/core/app.conf create mode 100644 test/e2e/config/core/env create mode 100644 test/e2e/config/core/private_key.pem create mode 100644 test/e2e/config/run_env.sh diff --git a/test/e2e/config/core/app.conf b/test/e2e/config/core/app.conf new file mode 100644 index 000000000..a22d03784 --- /dev/null +++ b/test/e2e/config/core/app.conf @@ -0,0 +1,7 @@ +appname = Harbor +# runmode = prod +runmode = dev +enablegzip = true + +[prod] +httpport = 8080 diff --git a/test/e2e/config/core/env b/test/e2e/config/core/env new file mode 100644 index 000000000..73a027e13 --- /dev/null +++ b/test/e2e/config/core/env @@ -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://core +DATABASE_TYPE=postgresql +POSTGRESQL_HOST=postgresql +POSTGRESQL_PORT=5432 +POSTGRESQL_USERNAME=postgres +POSTGRESQL_PASSWORD=root123 +POSTGRESQL_DATABASE=registry +POSTGRESQL_SSLMODE=disable +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 +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 diff --git a/test/e2e/config/core/private_key.pem b/test/e2e/config/core/private_key.pem new file mode 100644 index 000000000..9f97f8f6e --- /dev/null +++ b/test/e2e/config/core/private_key.pem @@ -0,0 +1,27 @@ +-----BEGIN RSA PRIVATE KEY----- +MIIEowIBAAKCAQEAuhpcYWGjmZPuWuq0zMf2dLwGkpufGozh8oxcfEmmpJ2rWQPf +j5SufJCx4XAvxJ0f3kH9NEGpNSYLt6OwPgfU9xHr8a8d/2b2/7zO0Cnbr69TYgUG +qFYMNUfA0fgvrEHTKZPhybPuabcLyiRtXJ/YPKaXJ01WFoxvYnlPGZ7LUbn2X0nn +i2UZ+F09Ei2YCRd4U4cOCZ92VKtUufCYGz+6YLO4AjK8lXf6OyOtlWF56SjBaAKf +8QdR+wR/PlhG285AZV1s1odFG4ql3rFKhYe5T3KdqCt92Jso0wRlQJLRk0QSCRUq +wwT8KiXjsbNptGxLkm6sUeDkb3UKGwDXVqdQrQIDAQABAoIBAAYtEEect31wsEO8 ++hrkAEeU+CyJihZAj9IJEEZWpQyy/Sf92H+PFLBRFqTPizedlZxpDmJbfdD5Tiu+ +Ef/+VLYOAUlwFpEuhVVs2mSESG8Jj5KXQ0aMXn4uf1VohLUqf7u86uIS/NSYzMUc +qt1x947ht26djX+/kYW61rdtXTwnyWW9AL7486dl7KM+DcwA4Oag62jStk6vvAt+ +cQDdMdXqHKkKAyri+WonKz0hYq/c3SXf19Cv5h5RfiDGt83qBXQ1nx7y+5mDX2xu +2Vig45YlF32Ll+F6ILL/7Kk2IIwdUmWdlXZZ2uHCWL0+OL6JtJ4yW/w4DEMPdNqk +seugCBECgYEAwbqO9k3fInDoQPn05OkBTCnf+NDPUvKDQf4JOPFHKon1RB5c8vy0 +6hJgLAi6EVKIflVLBB2PEcQY/JILnUeHJ0a7ywJlbdq3UZOJnIRW5yJgZqKOsy3b +7V18YmA9yO4bWKJtbNslkewp211zzjfQIoBdDY1OhUzpKsSNLl4jBvECgYEA9exM +FcfxBmM0SBpgYaqQ+Gug0gXNgQAzbJXO2ZxMdmbNX3XHlGLThqyBd180dgbSrZGV +2plOyFDIUqCWFObCyHbQPnKDN4bxLNOBKXiBumfEA1VAB1iEz1TaeXzs3Py1T/4+ +JpLIgO+iYVffXWfcSCgIjhfu0mUw7OlBIJw9vX0CgYBwFVyzOjiX95UYSsWaTwjW +JQAVN9JLnk28t5pkXIwdG3ZQs/R5DSYqqvkDYQUuEn8wAG8HcYad88O1FVYs5/5V +BgKOoNNILJuVUfPzH0ocLfJyTyiamDS+7zCQxjfY8ZHWxRrkOSJSe7130mi27em4 +nGW5+oBsdSQN/2vjYMmJMQKBgQDg3FMlh1BnWsYvN47xPpiXzTGbWBrz3U8n9kLQ +zw1LJeybYIJAt6xZ89ndYHwDf3Gbqwaufod+uf6xLoyMSAPKcHkw4FwCpaxYJHxx +gvJ7ku2zbnvBO7sUKK4rb4LU/Wx73CjP9F7JJlP/Ve2y5oiQoapQ4qlIT6ZQuWcH +flUlsQKBgFKJyNmmt2v5hwrcGc87WcjB/BoNKiQhxJ9gBvzP7A3IFbOtqv/pPUFs +WE8xY3znTZNHa+HAgdzFmIiDL2aw22ibeh69TANRan3CLHSsXjXm1o3vl1IE7N4+ +zUJp5kJkCd4yPdvw6kQobo7ODpg/ub+bbUoRUAQ+6KeCwrfSTJN3 +-----END RSA PRIVATE KEY----- diff --git a/test/e2e/config/run_env.sh b/test/e2e/config/run_env.sh new file mode 100644 index 000000000..a46ab892d --- /dev/null +++ b/test/e2e/config/run_env.sh @@ -0,0 +1,27 @@ +#!/bin/sh + +envFile="/envFile" + +# Check if the file exists +if [ ! -f "$envFile" ]; then + echo "Environment file not found: $envFile" + exit 1 +fi + +# Read the file and export each line as an environment variable +while IFS='=' read -r key value; do + # Ignore empty lines or comments + if [ -z "$key" ] || [ "${key:0:1}" = "#" ]; then + continue + fi + + # Export the environment variable + export "$key"="$value" + + # print the variable to verify it's set + echo "Set $key=$value" +done < "$envFile" + +# Execute the command (passed as $1 arg) +echo "Executing: $1" +eval "$1" From cd1c2845111c92a40ec6b695a4d31ac4a03d96e9 Mon Sep 17 00:00:00 2001 From: Aditya Chopra Date: Sun, 21 Dec 2025 14:58:37 +0530 Subject: [PATCH 2/9] create setupHarborRegistry in dagger Signed-off-by: Aditya Chopra --- .dagger/go.mod | 65 +++++++++++---------- .dagger/go.sum | 124 ++++++++++++++++++++--------------------- .dagger/harbor_test.go | 102 +++++++++++++++++++++++++++++++++ dagger.json | 5 +- 4 files changed, 199 insertions(+), 97 deletions(-) create mode 100644 .dagger/harbor_test.go diff --git a/.dagger/go.mod b/.dagger/go.mod index efda7b819..88347264e 100644 --- a/.dagger/go.mod +++ b/.dagger/go.mod @@ -2,50 +2,49 @@ module dagger/harbor-cli go 1.24.4 -replace go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploggrpc => go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploggrpc v0.12.2 +replace go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploggrpc => go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploggrpc v0.14.0 -replace go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploghttp => go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploghttp v0.12.2 +replace go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploghttp => go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploghttp v0.14.0 -replace go.opentelemetry.io/otel/log => go.opentelemetry.io/otel/log v0.12.2 +replace go.opentelemetry.io/otel/log => go.opentelemetry.io/otel/log v0.14.0 -replace go.opentelemetry.io/otel/sdk/log => go.opentelemetry.io/otel/sdk/log v0.12.2 +replace go.opentelemetry.io/otel/sdk/log => go.opentelemetry.io/otel/sdk/log v0.14.0 require ( - github.com/99designs/gqlgen v0.17.75 + github.com/99designs/gqlgen v0.17.81 github.com/Khan/genqlient v0.8.1 - github.com/vektah/gqlparser/v2 v2.5.28 - go.opentelemetry.io/otel v1.36.0 - go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploggrpc v0.12.2 - go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploghttp v0.12.2 - go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v1.32.0 - go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp v1.32.0 - go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.32.0 - go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.32.0 - go.opentelemetry.io/otel/log v0.12.2 - go.opentelemetry.io/otel/metric v1.36.0 - go.opentelemetry.io/otel/sdk v1.36.0 - go.opentelemetry.io/otel/sdk/log v0.12.2 - go.opentelemetry.io/otel/sdk/metric v1.36.0 - go.opentelemetry.io/otel/trace v1.36.0 - go.opentelemetry.io/proto/otlp v1.6.0 - golang.org/x/sync v0.15.0 - google.golang.org/grpc v1.73.0 + github.com/vektah/gqlparser/v2 v2.5.30 + go.opentelemetry.io/otel v1.38.0 + go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploggrpc v0.14.0 + go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploghttp v0.14.0 + go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v1.38.0 + go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp v1.38.0 + go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.38.0 + go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.38.0 + go.opentelemetry.io/otel/log v0.14.0 + go.opentelemetry.io/otel/metric v1.38.0 + go.opentelemetry.io/otel/sdk v1.38.0 + go.opentelemetry.io/otel/sdk/log v0.14.0 + go.opentelemetry.io/otel/sdk/metric v1.38.0 + go.opentelemetry.io/otel/trace v1.38.0 + go.opentelemetry.io/proto/otlp v1.8.0 + golang.org/x/sync v0.17.0 + google.golang.org/grpc v1.76.0 ) require ( - github.com/cenkalti/backoff/v4 v4.3.0 // indirect - github.com/cenkalti/backoff/v5 v5.0.2 // indirect - github.com/go-logr/logr v1.4.2 // indirect + github.com/cenkalti/backoff/v5 v5.0.3 // indirect + github.com/go-logr/logr v1.4.3 // indirect github.com/go-logr/stdr v1.2.2 // indirect github.com/google/uuid v1.6.0 // indirect - github.com/grpc-ecosystem/grpc-gateway/v2 v2.26.3 // indirect + github.com/grpc-ecosystem/grpc-gateway/v2 v2.27.2 // indirect github.com/sosodev/duration v1.3.1 // indirect go.opentelemetry.io/auto/sdk v1.1.0 // indirect - go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.32.0 // indirect - golang.org/x/net v0.41.0 // indirect - golang.org/x/sys v0.33.0 // indirect - golang.org/x/text v0.26.0 // indirect - google.golang.org/genproto/googleapis/api v0.0.0-20250519155744-55703ea1f237 // indirect - google.golang.org/genproto/googleapis/rpc v0.0.0-20250519155744-55703ea1f237 // indirect - google.golang.org/protobuf v1.36.6 // indirect + go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.38.0 // indirect + golang.org/x/net v0.44.0 // indirect + golang.org/x/sys v0.36.0 // indirect + golang.org/x/text v0.29.0 // indirect + google.golang.org/genproto/googleapis/api v0.0.0-20250825161204-c5933d9347a5 // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20250825161204-c5933d9347a5 // indirect + google.golang.org/protobuf v1.36.9 // indirect ) diff --git a/.dagger/go.sum b/.dagger/go.sum index 74758957c..03dea85c6 100644 --- a/.dagger/go.sum +++ b/.dagger/go.sum @@ -1,18 +1,16 @@ -github.com/99designs/gqlgen v0.17.75 h1:GwHJsptXWLHeY7JO8b7YueUI4w9Pom6wJTICosDtQuI= -github.com/99designs/gqlgen v0.17.75/go.mod h1:p7gbTpdnHyl70hmSpM8XG8GiKwmCv+T5zkdY8U8bLog= +github.com/99designs/gqlgen v0.17.81 h1:kCkN/xVyRb5rEQpuwOHRTYq83i0IuTQg9vdIiwEerTs= +github.com/99designs/gqlgen v0.17.81/go.mod h1:vgNcZlLwemsUhYim4dC1pvFP5FX0pr2Y+uYUoHFb1ig= github.com/Khan/genqlient v0.8.1 h1:wtOCc8N9rNynRLXN3k3CnfzheCUNKBcvXmVv5zt6WCs= github.com/Khan/genqlient v0.8.1/go.mod h1:R2G6DzjBvCbhjsEajfRjbWdVglSH/73kSivC9TLWVjU= github.com/andreyvit/diff v0.0.0-20170406064948-c7f18ee00883 h1:bvNMNQO63//z+xNgfBlViaCIJKLlCJ6/fmUseuG0wVQ= github.com/andreyvit/diff v0.0.0-20170406064948-c7f18ee00883/go.mod h1:rCTlJbsFo29Kk6CurOXKm700vrz8f0KW0JNfpkRJY/8= -github.com/cenkalti/backoff/v4 v4.3.0 h1:MyRJ/UdXutAwSAT+s3wNd7MfTIcy71VQueUuFK343L8= -github.com/cenkalti/backoff/v4 v4.3.0/go.mod h1:Y3VNntkOUPxTVeUxJ/G5vcM//AlwfmyYozVcomhLiZE= -github.com/cenkalti/backoff/v5 v5.0.2 h1:rIfFVxEf1QsI7E1ZHfp/B4DF/6QBAUhmgkxc0H7Zss8= -github.com/cenkalti/backoff/v5 v5.0.2/go.mod h1:rkhZdG3JZukswDf7f0cwqPNk4K0sa+F97BxZthm/crw= +github.com/cenkalti/backoff/v5 v5.0.3 h1:ZN+IMa753KfX5hd8vVaMixjnqRZ3y8CuJKRKj1xcsSM= +github.com/cenkalti/backoff/v5 v5.0.3/go.mod h1:rkhZdG3JZukswDf7f0cwqPNk4K0sa+F97BxZthm/crw= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= -github.com/go-logr/logr v1.4.2 h1:6pFjapn8bFcIbiKo3XT4j/BhANplGihG6tvd+8rYgrY= -github.com/go-logr/logr v1.4.2/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= +github.com/go-logr/logr v1.4.3 h1:CjnDlHq8ikf6E492q6eKboGOC0T8CDaOvkHCIg8idEI= +github.com/go-logr/logr v1.4.3/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE= github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek= @@ -21,69 +19,71 @@ github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8= github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU= github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= -github.com/grpc-ecosystem/grpc-gateway/v2 v2.26.3 h1:5ZPtiqj0JL5oKWmcsq4VMaAW5ukBEgSGXEN89zeH1Jo= -github.com/grpc-ecosystem/grpc-gateway/v2 v2.26.3/go.mod h1:ndYquD05frm2vACXE1nsccT4oJzjhw2arTS2cpUD1PI= +github.com/grpc-ecosystem/grpc-gateway/v2 v2.27.2 h1:8Tjv8EJ+pM1xP8mK6egEbD1OgnVTyacbefKhmbLhIhU= +github.com/grpc-ecosystem/grpc-gateway/v2 v2.27.2/go.mod h1:pkJQ2tZHJ0aFOVEEot6oZmaVEZcRme73eIFmhiVuRWs= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/sergi/go-diff v1.3.1 h1:xkr+Oxo4BOQKmkn/B9eMK0g5Kg/983T9DqqPHwYqD+8= github.com/sergi/go-diff v1.3.1/go.mod h1:aMJSSKb2lpPvRNec0+w3fl7LP9IOFzdc9Pa4NFbPK1I= github.com/sosodev/duration v1.3.1 h1:qtHBDMQ6lvMQsL15g4aopM4HEfOaYuhWBw3NPTtlqq4= github.com/sosodev/duration v1.3.1/go.mod h1:RQIBBX0+fMLc/D9+Jb/fwvVmo0eZvDDEERAikUR6SDg= -github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA= -github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= -github.com/vektah/gqlparser/v2 v2.5.28 h1:bIulcl3LF69ba6EiZVGD88y4MkM+Jxrf3P2MX8xLRkY= -github.com/vektah/gqlparser/v2 v2.5.28/go.mod h1:D1/VCZtV3LPnQrcPBeR/q5jkSQIPti0uYCP/RI0gIeo= +github.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu7U= +github.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U= +github.com/vektah/gqlparser/v2 v2.5.30 h1:EqLwGAFLIzt1wpx1IPpY67DwUujF1OfzgEyDsLrN6kE= +github.com/vektah/gqlparser/v2 v2.5.30/go.mod h1:D1/VCZtV3LPnQrcPBeR/q5jkSQIPti0uYCP/RI0gIeo= go.opentelemetry.io/auto/sdk v1.1.0 h1:cH53jehLUN6UFLY71z+NDOiNJqDdPRaXzTel0sJySYA= go.opentelemetry.io/auto/sdk v1.1.0/go.mod h1:3wSPjt5PWp2RhlCcmmOial7AvC4DQqZb7a7wCow3W8A= -go.opentelemetry.io/otel v1.36.0 h1:UumtzIklRBY6cI/lllNZlALOF5nNIzJVb16APdvgTXg= -go.opentelemetry.io/otel v1.36.0/go.mod h1:/TcFMXYjyRNh8khOAO9ybYkqaDBb/70aVwkNML4pP8E= -go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploggrpc v0.12.2 h1:06ZeJRe5BnYXceSM9Vya83XXVaNGe3H1QqsvqRANQq8= -go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploggrpc v0.12.2/go.mod h1:DvPtKE63knkDVP88qpatBj81JxN+w1bqfVbsbCbj1WY= -go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploghttp v0.12.2 h1:tPLwQlXbJ8NSOfZc4OkgU5h2A38M4c9kfHSVc4PFQGs= -go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploghttp v0.12.2/go.mod h1:QTnxBwT/1rBIgAG1goq6xMydfYOBKU6KTiYF4fp5zL8= -go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v1.32.0 h1:j7ZSD+5yn+lo3sGV69nW04rRR0jhYnBwjuX3r0HvnK0= -go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v1.32.0/go.mod h1:WXbYJTUaZXAbYd8lbgGuvih0yuCfOFC5RJoYnoLcGz8= -go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp v1.32.0 h1:t/Qur3vKSkUCcDVaSumWF2PKHt85pc7fRvFuoVT8qFU= -go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp v1.32.0/go.mod h1:Rl61tySSdcOJWoEgYZVtmnKdA0GeKrSqkHC1t+91CH8= -go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.32.0 h1:IJFEoHiytixx8cMiVAO+GmHR6Frwu+u5Ur8njpFO6Ac= -go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.32.0/go.mod h1:3rHrKNtLIoS0oZwkY2vxi+oJcwFRWdtUyRII+so45p8= -go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.32.0 h1:9kV11HXBHZAvuPUZxmMWrH8hZn/6UnHX4K0mu36vNsU= -go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.32.0/go.mod h1:JyA0FHXe22E1NeNiHmVp7kFHglnexDQ7uRWDiiJ1hKQ= -go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.32.0 h1:cMyu9O88joYEaI47CnQkxO1XZdpoTF9fEnW2duIddhw= -go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.32.0/go.mod h1:6Am3rn7P9TVVeXYG+wtcGE7IE1tsQ+bP3AuWcKt/gOI= -go.opentelemetry.io/otel/log v0.12.2 h1:yob9JVHn2ZY24byZeaXpTVoPS6l+UrrxmxmPKohXTwc= -go.opentelemetry.io/otel/log v0.12.2/go.mod h1:ShIItIxSYxufUMt+1H5a2wbckGli3/iCfuEbVZi/98E= -go.opentelemetry.io/otel/metric v1.36.0 h1:MoWPKVhQvJ+eeXWHFBOPoBOi20jh6Iq2CcCREuTYufE= -go.opentelemetry.io/otel/metric v1.36.0/go.mod h1:zC7Ks+yeyJt4xig9DEw9kuUFe5C3zLbVjV2PzT6qzbs= -go.opentelemetry.io/otel/sdk v1.36.0 h1:b6SYIuLRs88ztox4EyrvRti80uXIFy+Sqzoh9kFULbs= -go.opentelemetry.io/otel/sdk v1.36.0/go.mod h1:+lC+mTgD+MUWfjJubi2vvXWcVxyr9rmlshZni72pXeY= -go.opentelemetry.io/otel/sdk/log v0.12.2 h1:yNoETvTByVKi7wHvYS6HMcZrN5hFLD7I++1xIZ/k6W0= -go.opentelemetry.io/otel/sdk/log v0.12.2/go.mod h1:DcpdmUXHJgSqN/dh+XMWa7Vf89u9ap0/AAk/XGLnEzY= -go.opentelemetry.io/otel/sdk/log/logtest v0.0.0-20250521073539-a85ae98dcedc h1:uqxdywfHqqCl6LmZzI3pUnXT1RGFYyUgxj0AkWPFxi0= -go.opentelemetry.io/otel/sdk/log/logtest v0.0.0-20250521073539-a85ae98dcedc/go.mod h1:TY/N/FT7dmFrP/r5ym3g0yysP1DefqGpAZr4f82P0dE= -go.opentelemetry.io/otel/sdk/metric v1.36.0 h1:r0ntwwGosWGaa0CrSt8cuNuTcccMXERFwHX4dThiPis= -go.opentelemetry.io/otel/sdk/metric v1.36.0/go.mod h1:qTNOhFDfKRwX0yXOqJYegL5WRaW376QbB7P4Pb0qva4= -go.opentelemetry.io/otel/trace v1.36.0 h1:ahxWNuqZjpdiFAyrIoQ4GIiAIhxAunQR6MUoKrsNd4w= -go.opentelemetry.io/otel/trace v1.36.0/go.mod h1:gQ+OnDZzrybY4k4seLzPAWNwVBBVlF2szhehOBB/tGA= -go.opentelemetry.io/proto/otlp v1.6.0 h1:jQjP+AQyTf+Fe7OKj/MfkDrmK4MNVtw2NpXsf9fefDI= -go.opentelemetry.io/proto/otlp v1.6.0/go.mod h1:cicgGehlFuNdgZkcALOCh3VE6K/u2tAjzlRhDwmVpZc= +go.opentelemetry.io/otel v1.38.0 h1:RkfdswUDRimDg0m2Az18RKOsnI8UDzppJAtj01/Ymk8= +go.opentelemetry.io/otel v1.38.0/go.mod h1:zcmtmQ1+YmQM9wrNsTGV/q/uyusom3P8RxwExxkZhjM= +go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploggrpc v0.14.0 h1:OMqPldHt79PqWKOMYIAQs3CxAi7RLgPxwfFSwr4ZxtM= +go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploggrpc v0.14.0/go.mod h1:1biG4qiqTxKiUCtoWDPpL3fB3KxVwCiGw81j3nKMuHE= +go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploghttp v0.14.0 h1:QQqYw3lkrzwVsoEX0w//EhH/TCnpRdEenKBOOEIMjWc= +go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploghttp v0.14.0/go.mod h1:gSVQcr17jk2ig4jqJ2DX30IdWH251JcNAecvrqTxH1s= +go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v1.38.0 h1:vl9obrcoWVKp/lwl8tRE33853I8Xru9HFbw/skNeLs8= +go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v1.38.0/go.mod h1:GAXRxmLJcVM3u22IjTg74zWBrRCKq8BnOqUVLodpcpw= +go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp v1.38.0 h1:Oe2z/BCg5q7k4iXC3cqJxKYg0ieRiOqF0cecFYdPTwk= +go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp v1.38.0/go.mod h1:ZQM5lAJpOsKnYagGg/zV2krVqTtaVdYdDkhMoX6Oalg= +go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.38.0 h1:GqRJVj7UmLjCVyVJ3ZFLdPRmhDUp2zFmQe3RHIOsw24= +go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.38.0/go.mod h1:ri3aaHSmCTVYu2AWv44YMauwAQc0aqI9gHKIcSbI1pU= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.38.0 h1:lwI4Dc5leUqENgGuQImwLo4WnuXFPetmPpkLi2IrX54= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.38.0/go.mod h1:Kz/oCE7z5wuyhPxsXDuaPteSWqjSBD5YaSdbxZYGbGk= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.38.0 h1:aTL7F04bJHUlztTsNGJ2l+6he8c+y/b//eR0jjjemT4= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.38.0/go.mod h1:kldtb7jDTeol0l3ewcmd8SDvx3EmIE7lyvqbasU3QC4= +go.opentelemetry.io/otel/log v0.14.0 h1:2rzJ+pOAZ8qmZ3DDHg73NEKzSZkhkGIua9gXtxNGgrM= +go.opentelemetry.io/otel/log v0.14.0/go.mod h1:5jRG92fEAgx0SU/vFPxmJvhIuDU9E1SUnEQrMlJpOno= +go.opentelemetry.io/otel/metric v1.38.0 h1:Kl6lzIYGAh5M159u9NgiRkmoMKjvbsKtYRwgfrA6WpA= +go.opentelemetry.io/otel/metric v1.38.0/go.mod h1:kB5n/QoRM8YwmUahxvI3bO34eVtQf2i4utNVLr9gEmI= +go.opentelemetry.io/otel/sdk v1.38.0 h1:l48sr5YbNf2hpCUj/FoGhW9yDkl+Ma+LrVl8qaM5b+E= +go.opentelemetry.io/otel/sdk v1.38.0/go.mod h1:ghmNdGlVemJI3+ZB5iDEuk4bWA3GkTpW+DOoZMYBVVg= +go.opentelemetry.io/otel/sdk/log v0.14.0 h1:JU/U3O7N6fsAXj0+CXz21Czg532dW2V4gG1HE/e8Zrg= +go.opentelemetry.io/otel/sdk/log v0.14.0/go.mod h1:imQvII+0ZylXfKU7/wtOND8Hn4OpT3YUoIgqJVksUkM= +go.opentelemetry.io/otel/sdk/log/logtest v0.14.0 h1:Ijbtz+JKXl8T2MngiwqBlPaHqc4YCaP/i13Qrow6gAM= +go.opentelemetry.io/otel/sdk/log/logtest v0.14.0/go.mod h1:dCU8aEL6q+L9cYTqcVOk8rM9Tp8WdnHOPLiBgp0SGOA= +go.opentelemetry.io/otel/sdk/metric v1.38.0 h1:aSH66iL0aZqo//xXzQLYozmWrXxyFkBJ6qT5wthqPoM= +go.opentelemetry.io/otel/sdk/metric v1.38.0/go.mod h1:dg9PBnW9XdQ1Hd6ZnRz689CbtrUp0wMMs9iPcgT9EZA= +go.opentelemetry.io/otel/trace v1.38.0 h1:Fxk5bKrDZJUH+AMyyIXGcFAPah0oRcT+LuNtJrmcNLE= +go.opentelemetry.io/otel/trace v1.38.0/go.mod h1:j1P9ivuFsTceSWe1oY+EeW3sc+Pp42sO++GHkg4wwhs= +go.opentelemetry.io/proto/otlp v1.8.0 h1:fRAZQDcAFHySxpJ1TwlA1cJ4tvcrw7nXl9xWWC8N5CE= +go.opentelemetry.io/proto/otlp v1.8.0/go.mod h1:tIeYOeNBU4cvmPqpaji1P+KbB4Oloai8wN4rWzRrFF0= go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto= go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE= -golang.org/x/net v0.41.0 h1:vBTly1HeNPEn3wtREYfy4GZ/NECgw2Cnl+nK6Nz3uvw= -golang.org/x/net v0.41.0/go.mod h1:B/K4NNqkfmg07DQYrbwvSluqCJOOXwUjeb/5lOisjbA= -golang.org/x/sync v0.15.0 h1:KWH3jNZsfyT6xfAfKiz6MRNmd46ByHDYaZ7KSkCtdW8= -golang.org/x/sync v0.15.0/go.mod h1:1dzgHSNfp02xaA81J2MS99Qcpr2w7fw1gpm99rleRqA= -golang.org/x/sys v0.33.0 h1:q3i8TbbEz+JRD9ywIRlyRAQbM0qF7hu24q3teo2hbuw= -golang.org/x/sys v0.33.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k= -golang.org/x/text v0.26.0 h1:P42AVeLghgTYr4+xUnTRKDMqpar+PtX7KWuNQL21L8M= -golang.org/x/text v0.26.0/go.mod h1:QK15LZJUUQVJxhz7wXgxSy/CJaTFjd0G+YLonydOVQA= -google.golang.org/genproto/googleapis/api v0.0.0-20250519155744-55703ea1f237 h1:Kog3KlB4xevJlAcbbbzPfRG0+X9fdoGM+UBRKVz6Wr0= -google.golang.org/genproto/googleapis/api v0.0.0-20250519155744-55703ea1f237/go.mod h1:ezi0AVyMKDWy5xAncvjLWH7UcLBB5n7y2fQ8MzjJcto= -google.golang.org/genproto/googleapis/rpc v0.0.0-20250519155744-55703ea1f237 h1:cJfm9zPbe1e873mHJzmQ1nwVEeRDU/T1wXDK2kUSU34= -google.golang.org/genproto/googleapis/rpc v0.0.0-20250519155744-55703ea1f237/go.mod h1:qQ0YXyHHx3XkvlzUtpXDkS29lDSafHMZBAZDc03LQ3A= -google.golang.org/grpc v1.73.0 h1:VIWSmpI2MegBtTuFt5/JWy2oXxtjJ/e89Z70ImfD2ok= -google.golang.org/grpc v1.73.0/go.mod h1:50sbHOUqWoCQGI8V2HQLJM0B+LMlIUjNSZmow7EVBQc= -google.golang.org/protobuf v1.36.6 h1:z1NpPI8ku2WgiWnf+t9wTPsn6eP1L7ksHUlkfLvd9xY= -google.golang.org/protobuf v1.36.6/go.mod h1:jduwjTPXsFjZGTmRluh+L6NjiWu7pchiJ2/5YcXBHnY= +golang.org/x/net v0.44.0 h1:evd8IRDyfNBMBTTY5XRF1vaZlD+EmWx6x8PkhR04H/I= +golang.org/x/net v0.44.0/go.mod h1:ECOoLqd5U3Lhyeyo/QDCEVQ4sNgYsqvCZ722XogGieY= +golang.org/x/sync v0.17.0 h1:l60nONMj9l5drqw6jlhIELNv9I0A4OFgRsG9k2oT9Ug= +golang.org/x/sync v0.17.0/go.mod h1:9KTHXmSnoGruLpwFjVSX0lNNA75CykiMECbovNTZqGI= +golang.org/x/sys v0.36.0 h1:KVRy2GtZBrk1cBYA7MKu5bEZFxQk4NIDV6RLVcC8o0k= +golang.org/x/sys v0.36.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks= +golang.org/x/text v0.29.0 h1:1neNs90w9YzJ9BocxfsQNHKuAT4pkghyXc4nhZ6sJvk= +golang.org/x/text v0.29.0/go.mod h1:7MhJOA9CD2qZyOKYazxdYMF85OwPdEr9jTtBpO7ydH4= +gonum.org/v1/gonum v0.16.0 h1:5+ul4Swaf3ESvrOnidPp4GZbzf0mxVQpDCYUQE7OJfk= +gonum.org/v1/gonum v0.16.0/go.mod h1:fef3am4MQ93R2HHpKnLk4/Tbh/s0+wqD5nfa6Pnwy4E= +google.golang.org/genproto/googleapis/api v0.0.0-20250825161204-c5933d9347a5 h1:BIRfGDEjiHRrk0QKZe3Xv2ieMhtgRGeLcZQ0mIVn4EY= +google.golang.org/genproto/googleapis/api v0.0.0-20250825161204-c5933d9347a5/go.mod h1:j3QtIyytwqGr1JUDtYXwtMXWPKsEa5LtzIFN1Wn5WvE= +google.golang.org/genproto/googleapis/rpc v0.0.0-20250825161204-c5933d9347a5 h1:eaY8u2EuxbRv7c3NiGK0/NedzVsCcV6hDuU5qPX5EGE= +google.golang.org/genproto/googleapis/rpc v0.0.0-20250825161204-c5933d9347a5/go.mod h1:M4/wBTSeyLxupu3W3tJtOgB14jILAS/XWPSSa3TAlJc= +google.golang.org/grpc v1.76.0 h1:UnVkv1+uMLYXoIz6o7chp59WfQUYA2ex/BXQ9rHZu7A= +google.golang.org/grpc v1.76.0/go.mod h1:Ju12QI8M6iQJtbcsV+awF5a4hfJMLi4X0JLo94ULZ6c= +google.golang.org/protobuf v1.36.9 h1:w2gp2mA27hUeUzj9Ex9FBjsBm40zfaDtEWow293U7Iw= +google.golang.org/protobuf v1.36.9/go.mod h1:fuxRtAxBytpl4zzqUh6/eyUujkJdNiuEkXntxiD/uRU= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= diff --git a/.dagger/harbor_test.go b/.dagger/harbor_test.go new file mode 100644 index 000000000..af71b5aca --- /dev/null +++ b/.dagger/harbor_test.go @@ -0,0 +1,102 @@ +package main + +import ( + "context" + "errors" + "log" + + "dagger/harbor-cli/internal/dagger" +) + +const ( + + harborImageTag = "satellite" + + postgresImage = "registry.goharbor.io/dockerhub/goharbor/harbor-db:dev" + redisImage = "registry.goharbor.io/dockerhub/goharbor/redis-photon:dev" + coreImage = "registry.goharbor.io/harbor-next/harbor-core:" + harborImageTag + + configDirPath = "./test/e2e/testconfig/config/" + + postgresPort = 5432 + redisPort = 6379 + corePort = 8080 + coreDebugPort = 4001 +) + +// Returns container running harbor registry with all services running +func (m *HarborCli) setupHarborRegistry(ctx context.Context) { + log.Println("setting up harbor registry environment...") + + if err := m.startPostgresql(ctx); err != nil { + requireNoExecError(err, "start postgresql") + } + log.Println("postgresql service started") + + if err := m.startRedis(ctx); err != nil { + requireNoExecError(err, "start redis") + } + log.Println("redis service started") + + _, err := m.startCore(ctx) + if err != nil { + requireNoExecError(err, "start core service") + } + log.Println("core service started") +} + +func (m *HarborCli) startPostgresql(ctx context.Context) error { + _, err := dag.Container(). + From(postgresImage). + WithExposedPort(postgresPort). + AsService(). + WithHostname("postgresql"). + Start(ctx) + + return err +} + +func (m *HarborCli) startRedis(ctx context.Context) error { + _, err := dag.Container(). + From(redisImage). + WithExposedPort(redisPort). + AsService(). + WithHostname("redis"). + Start(ctx) + + return err +} + + +func (m *HarborCli) startCore(ctx context.Context) (*dagger.Service, error) { + + coreConfig := m.Source.File(configDirPath + "core/app.conf") + envCoreFile := m.Source.File(configDirPath + "core/env") + runScript := m.Source.File(configDirPath + "run_env.sh") + privatekey := m.Source.File(configDirPath + "core/private_key.pem") + + return dag.Container(). + From(coreImage). + WithMountedFile("/etc/core/app.conf", coreConfig). + WithMountedFile("/etc/core/private_key.pem", privatekey). + WithMountedFile("/envFile", envCoreFile). + WithMountedFile("/run_script", runScript). + WithExec([]string{"chmod", "+x", "/run_script"}). + WithExposedPort(corePort, dagger.ContainerWithExposedPortOpts{ExperimentalSkipHealthcheck: true}). + WithExposedPort(coreDebugPort, dagger.ContainerWithExposedPortOpts{ExperimentalSkipHealthcheck: true}). + WithEntrypoint([]string{"/run_script", "/core"}). + AsService(). + WithHostname("core"). + Start(ctx) + +} + + +func requireNoExecError(err error, step string) { + var e *dagger.ExecError + if errors.As(err, &e) { + log.Fatalf("failed to %s (exec error): %s", step, err) + } else { + log.Fatalf("failed to %s (unexpected error): %s", step, err) + } +} \ No newline at end of file diff --git a/dagger.json b/dagger.json index f1b2f6d1e..82c5f357e 100644 --- a/dagger.json +++ b/dagger.json @@ -1,6 +1,6 @@ { "name": "harbor-cli", - "engineVersion": "v0.18.12", + "engineVersion": "v0.19.8", "sdk": { "source": "go" }, @@ -11,5 +11,6 @@ "pin": "8359122a7b90f2c8c6f3165570fdcbec6e923023" } ], - "source": ".dagger" + "source": ".dagger", + "disableDefaultFunctionCaching": true } From 2d3b55634c9bd9873c23a244a218239e511a871f Mon Sep 17 00:00:00 2001 From: Aditya Chopra Date: Sun, 21 Dec 2025 17:41:53 +0530 Subject: [PATCH 3/9] create HarborTest in dagger Signed-off-by: Aditya Chopra --- .dagger/harbor_test.go | 25 +++++++++++++++++++++++-- 1 file changed, 23 insertions(+), 2 deletions(-) diff --git a/.dagger/harbor_test.go b/.dagger/harbor_test.go index af71b5aca..afcb41841 100644 --- a/.dagger/harbor_test.go +++ b/.dagger/harbor_test.go @@ -9,6 +9,8 @@ import ( ) const ( + harborAdminUser = "admin" + harborAdminPassword = "Harbor12345" harborImageTag = "satellite" @@ -24,8 +26,25 @@ const ( coreDebugPort = 4001 ) +func (m* HarborCli) HarborTest(ctx context.Context) (string, error) { + core := m.setupHarborRegistry(ctx) + + // Create instance for the HarborCLI to run tests in + test := dag.Container(). + From("golang:"+GO_VERSION+"-alpine"). + WithServiceBinding("core", core). + WithMountedDirectory("/src", m.Source). + WithWorkdir("/src"). + WithEnvVariable("TEST_HARBOR_URL", "core:8080"). + WithEnvVariable("TEST_HARBOR_USERNAME", harborAdminUser). + WithEnvVariable("TEST_HARBOR_PASSWORD", harborAdminPassword). + WithExec([]string{"go", "test", "-v", "./..."}) + + return test.Stdout(ctx) +} + // Returns container running harbor registry with all services running -func (m *HarborCli) setupHarborRegistry(ctx context.Context) { +func (m *HarborCli) setupHarborRegistry(ctx context.Context) *dagger.Service { log.Println("setting up harbor registry environment...") if err := m.startPostgresql(ctx); err != nil { @@ -38,11 +57,13 @@ func (m *HarborCli) setupHarborRegistry(ctx context.Context) { } log.Println("redis service started") - _, err := m.startCore(ctx) + core, err := m.startCore(ctx) if err != nil { requireNoExecError(err, "start core service") } log.Println("core service started") + + return core } func (m *HarborCli) startPostgresql(ctx context.Context) error { From 8ae47ed1ecb5466f6430abe5dd0b58b3d83a9ba5 Mon Sep 17 00:00:00 2001 From: Aditya Chopra Date: Sun, 21 Dec 2025 18:22:29 +0530 Subject: [PATCH 4/9] change login test registry endpoints Signed-off-by: Aditya Chopra --- .dagger/{harbor_test.go => harbor.go} | 3 -- cmd/harbor/root/login_test.go | 48 +++++++++++++++++++-------- test/helper/helpers.go | 22 ++++++++++++ 3 files changed, 57 insertions(+), 16 deletions(-) rename .dagger/{harbor_test.go => harbor.go} (99%) diff --git a/.dagger/harbor_test.go b/.dagger/harbor.go similarity index 99% rename from .dagger/harbor_test.go rename to .dagger/harbor.go index afcb41841..e61ca87cf 100644 --- a/.dagger/harbor_test.go +++ b/.dagger/harbor.go @@ -88,7 +88,6 @@ func (m *HarborCli) startRedis(ctx context.Context) error { return err } - func (m *HarborCli) startCore(ctx context.Context) (*dagger.Service, error) { coreConfig := m.Source.File(configDirPath + "core/app.conf") @@ -109,10 +108,8 @@ func (m *HarborCli) startCore(ctx context.Context) (*dagger.Service, error) { AsService(). WithHostname("core"). Start(ctx) - } - func requireNoExecError(err error, step string) { var e *dagger.ExecError if errors.As(err, &e) { diff --git a/cmd/harbor/root/login_test.go b/cmd/harbor/root/login_test.go index 94cc45046..99a261854 100644 --- a/cmd/harbor/root/login_test.go +++ b/cmd/harbor/root/login_test.go @@ -14,6 +14,7 @@ package root_test import ( + "strings" "testing" "github.com/goharbor/harbor-cli/cmd/harbor/root" @@ -26,20 +27,34 @@ func Test_Login_Success(t *testing.T) { data := helpers.Initialize(t, tempDir) defer helpers.ConfigCleanup(t, data) cmd := root.LoginCommand() - validServerAddresses := []string{ - "http://demo.goharbor.io:80", - "https://demo.goharbor.io:443", - "http://demo.goharbor.io", - "https://demo.goharbor.io", - } + harborURL := helpers.GetTestHarborURL() + username, password := helpers.GetTestHarborCredentials() + + var validServerAddresses []string + if strings.Contains(harborURL, ":") { + // URL already has port (e.g : "core:8080" for local Dagger Harbor) + validServerAddresses = []string{ + "http://" + harborURL, + "https://" + harborURL, + } + } else { + // URL is hostname only (for: "demo.goharbor.io") + validServerAddresses = []string{ + "http://" + harborURL + ":80", + "https://" + harborURL + ":443", + "http://" + harborURL, + "https://" + harborURL, + } + } + for _, serverAddress := range validServerAddresses { t.Run("ValidServer_"+serverAddress, func(t *testing.T) { args := []string{serverAddress} cmd.SetArgs(args) - assert.NoError(t, cmd.Flags().Set("username", "harbor-cli")) - assert.NoError(t, cmd.Flags().Set("password", "Harbor12345")) + assert.NoError(t, cmd.Flags().Set("username", username)) + assert.NoError(t, cmd.Flags().Set("password", password)) err := cmd.Execute() assert.NoError(t, err, "Expected no error for server: %s", serverAddress) @@ -52,11 +67,13 @@ func Test_Login_Failure_WrongServer(t *testing.T) { data := helpers.Initialize(t, tempDir) defer helpers.ConfigCleanup(t, data) + username, password := helpers.GetTestHarborCredentials() + cmd := root.LoginCommand() cmd.SetArgs([]string{"wrongserver"}) - assert.NoError(t, cmd.Flags().Set("username", "harbor-cli")) - assert.NoError(t, cmd.Flags().Set("password", "Harbor12345")) + assert.NoError(t, cmd.Flags().Set("username", username)) + assert.NoError(t, cmd.Flags().Set("password", password)) err := cmd.Execute() assert.Error(t, err, "Expected error for invalid server") @@ -67,11 +84,14 @@ func Test_Login_Failure_WrongUsername(t *testing.T) { data := helpers.Initialize(t, tempDir) defer helpers.ConfigCleanup(t, data) + harborURL := helpers.GetTestHarborURL() + _, password := helpers.GetTestHarborCredentials() + cmd := root.LoginCommand() - cmd.SetArgs([]string{"http://demo.goharbor.io"}) + cmd.SetArgs([]string{harborURL}) assert.NoError(t, cmd.Flags().Set("username", "does-not-exist")) - assert.NoError(t, cmd.Flags().Set("password", "Harbor12345")) + assert.NoError(t, cmd.Flags().Set("password", password)) err := cmd.Execute() assert.Error(t, err, "Expected error for wrong username") @@ -82,8 +102,10 @@ func Test_Login_Failure_WrongPassword(t *testing.T) { data := helpers.Initialize(t, tempDir) defer helpers.ConfigCleanup(t, data) + harborURL := helpers.GetTestHarborURL() + cmd := root.LoginCommand() - cmd.SetArgs([]string{"http://demo.goharbor.io"}) + cmd.SetArgs([]string{harborURL}) assert.NoError(t, cmd.Flags().Set("username", "admin")) assert.NoError(t, cmd.Flags().Set("password", "wrong")) diff --git a/test/helper/helpers.go b/test/helper/helpers.go index 7fd895421..c3d4c7023 100644 --- a/test/helper/helpers.go +++ b/test/helper/helpers.go @@ -94,3 +94,25 @@ func ConfigCleanup(t *testing.T, data *utils.HarborData) { os.Unsetenv("XDG_DATA_HOME") resetAll() } + +func GetTestHarborURL() string { + if url := os.Getenv("TEST_HARBOR_URL"); url != "" { + return url + } + return "demo.goharbor.io" +} + + +func GetTestHarborCredentials() (username, password string) { + username = os.Getenv("TEST_HARBOR_USERNAME") + password = os.Getenv("TEST_HARBOR_PASSWORD") + + if username == "" { + username = "harbor-cli" + } + if password == "" { + password = "Harbor12345" + } + + return username, password +} \ No newline at end of file From cbba040ddd40c90013988ad0a92da1f0cacc5237 Mon Sep 17 00:00:00 2001 From: Aditya Chopra Date: Sun, 21 Dec 2025 18:28:51 +0530 Subject: [PATCH 5/9] chore: fix lint Signed-off-by: Aditya Chopra --- cmd/harbor/root/login_test.go | 2 +- test/helper/helpers.go | 7 +++---- 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/cmd/harbor/root/login_test.go b/cmd/harbor/root/login_test.go index 99a261854..23e70565c 100644 --- a/cmd/harbor/root/login_test.go +++ b/cmd/harbor/root/login_test.go @@ -47,7 +47,7 @@ func Test_Login_Success(t *testing.T) { "https://" + harborURL, } } - + for _, serverAddress := range validServerAddresses { t.Run("ValidServer_"+serverAddress, func(t *testing.T) { args := []string{serverAddress} diff --git a/test/helper/helpers.go b/test/helper/helpers.go index c3d4c7023..439851115 100644 --- a/test/helper/helpers.go +++ b/test/helper/helpers.go @@ -102,17 +102,16 @@ func GetTestHarborURL() string { return "demo.goharbor.io" } - func GetTestHarborCredentials() (username, password string) { username = os.Getenv("TEST_HARBOR_USERNAME") password = os.Getenv("TEST_HARBOR_PASSWORD") - + if username == "" { username = "harbor-cli" } if password == "" { password = "Harbor12345" } - + return username, password -} \ No newline at end of file +} From 218f80d887ae14e6e87ee8fe945ab4e2943e953a Mon Sep 17 00:00:00 2001 From: Aditya Chopra Date: Sun, 21 Dec 2025 18:34:28 +0530 Subject: [PATCH 6/9] chore: fix lint Signed-off-by: Aditya Chopra --- .dagger/harbor.go | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/.dagger/harbor.go b/.dagger/harbor.go index e61ca87cf..2bafeec60 100644 --- a/.dagger/harbor.go +++ b/.dagger/harbor.go @@ -12,11 +12,11 @@ const ( harborAdminUser = "admin" harborAdminPassword = "Harbor12345" - harborImageTag = "satellite" + harborImageTag = "satellite" - postgresImage = "registry.goharbor.io/dockerhub/goharbor/harbor-db:dev" - redisImage = "registry.goharbor.io/dockerhub/goharbor/redis-photon:dev" - coreImage = "registry.goharbor.io/harbor-next/harbor-core:" + harborImageTag + postgresImage = "registry.goharbor.io/dockerhub/goharbor/harbor-db:dev" + redisImage = "registry.goharbor.io/dockerhub/goharbor/redis-photon:dev" + coreImage = "registry.goharbor.io/harbor-next/harbor-core:" + harborImageTag configDirPath = "./test/e2e/testconfig/config/" @@ -26,7 +26,7 @@ const ( coreDebugPort = 4001 ) -func (m* HarborCli) HarborTest(ctx context.Context) (string, error) { +func (m *HarborCli) HarborTest(ctx context.Context) (string, error) { core := m.setupHarborRegistry(ctx) // Create instance for the HarborCLI to run tests in @@ -57,7 +57,7 @@ func (m *HarborCli) setupHarborRegistry(ctx context.Context) *dagger.Service { } log.Println("redis service started") - core, err := m.startCore(ctx) + core, err := m.startCore(ctx) if err != nil { requireNoExecError(err, "start core service") } @@ -117,4 +117,4 @@ func requireNoExecError(err error, step string) { } else { log.Fatalf("failed to %s (unexpected error): %s", step, err) } -} \ No newline at end of file +} From b4aee93b236ebe1d87b2961ea62ac4557e78fcfd Mon Sep 17 00:00:00 2001 From: Aditya Chopra Date: Mon, 22 Dec 2025 00:14:38 +0530 Subject: [PATCH 7/9] feat:add core service health check Signed-off-by: Aditya Chopra --- .dagger/harbor.go | 64 ++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 63 insertions(+), 1 deletion(-) diff --git a/.dagger/harbor.go b/.dagger/harbor.go index 2bafeec60..0173bc546 100644 --- a/.dagger/harbor.go +++ b/.dagger/harbor.go @@ -3,17 +3,22 @@ package main import ( "context" "errors" + "fmt" "log" + "time" "dagger/harbor-cli/internal/dagger" ) const ( + harborDomain = "http://core:8080" + harborAPIPath = "/api/v2.0" + harborBaseURL = harborDomain + harborAPIPath + harborAdminUser = "admin" harborAdminPassword = "Harbor12345" harborImageTag = "satellite" - postgresImage = "registry.goharbor.io/dockerhub/goharbor/harbor-db:dev" redisImage = "registry.goharbor.io/dockerhub/goharbor/redis-photon:dev" coreImage = "registry.goharbor.io/harbor-next/harbor-core:" + harborImageTag @@ -62,6 +67,11 @@ func (m *HarborCli) setupHarborRegistry(ctx context.Context) *dagger.Service { requireNoExecError(err, "start core service") } log.Println("core service started") + + if err := waitForCoreServiceHealth(ctx); err != nil { + requireNoExecError(err, "core service health check") + } + log.Println("core service health check passed") return core } @@ -118,3 +128,55 @@ func requireNoExecError(err error, step string) { log.Fatalf("failed to %s (unexpected error): %s", step, err) } } + + +func waitForCoreServiceHealth(ctx context.Context) error { + timeout := time.After(15 * time.Minute) + ticker := time.NewTicker(15 * time.Second) + defer ticker.Stop() + for { + select { + case <-timeout: + return fmt.Errorf("timeout waiting for services to be healthy") + case <-ticker.C: + _, err := executeHTTPRequest(ctx, "GET", "/health", "") + if err == nil { + log.Println("core service is healthy") + return nil + } + log.Printf("Services not ready yet: %v", err) + } + } +} + + +func executeHTTPRequest(ctx context.Context, method, endpoint, data string) (string, error) { + args := []string{"curl", "-s", "-X", method} + + if endpoint == "/configs" || endpoint == "/satellites" { + args = append(args, fmt.Sprintf("%s%s", "http://gc:8080", endpoint)) + } else { + args = append(args, "-u", fmt.Sprintf("%s:%s", harborAdminUser, harborAdminPassword)) + args = append(args, fmt.Sprintf("%s%s", harborBaseURL, endpoint)) + } + if data != "" { + args = append(args, "-H", "Content-Type: application/json") + args = append(args, "-d", data) + } + + stdout, err := curlContainer(ctx, args) + if err != nil { + return "", fmt.Errorf("HTTP %s %s failed: %w", method, endpoint, err) + } + + log.Printf("%s %s completed. response: %s", method, endpoint, stdout) + return stdout, err +} + +func curlContainer(ctx context.Context, cmd []string) (string, error) { + return dag.Container(). + From("curlimages/curl@sha256:9a1ed35addb45476afa911696297f8e115993df459278ed036182dd2cd22b67b"). + WithEnvVariable("CACHEBUSTER", time.Now().String()). + WithExec(cmd). + Stdout(ctx) +} \ No newline at end of file From 44818de93660ad2d196e376d3760228fc2815e02 Mon Sep 17 00:00:00 2001 From: Aditya Chopra Date: Mon, 22 Dec 2025 00:15:12 +0530 Subject: [PATCH 8/9] chore: fix lint Signed-off-by: Aditya Chopra --- .dagger/harbor.go | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/.dagger/harbor.go b/.dagger/harbor.go index 0173bc546..5026e9ab0 100644 --- a/.dagger/harbor.go +++ b/.dagger/harbor.go @@ -19,9 +19,9 @@ const ( harborAdminPassword = "Harbor12345" harborImageTag = "satellite" - postgresImage = "registry.goharbor.io/dockerhub/goharbor/harbor-db:dev" - redisImage = "registry.goharbor.io/dockerhub/goharbor/redis-photon:dev" - coreImage = "registry.goharbor.io/harbor-next/harbor-core:" + harborImageTag + postgresImage = "registry.goharbor.io/dockerhub/goharbor/harbor-db:dev" + redisImage = "registry.goharbor.io/dockerhub/goharbor/redis-photon:dev" + coreImage = "registry.goharbor.io/harbor-next/harbor-core:" + harborImageTag configDirPath = "./test/e2e/testconfig/config/" @@ -67,7 +67,7 @@ func (m *HarborCli) setupHarborRegistry(ctx context.Context) *dagger.Service { requireNoExecError(err, "start core service") } log.Println("core service started") - + if err := waitForCoreServiceHealth(ctx); err != nil { requireNoExecError(err, "core service health check") } @@ -129,7 +129,6 @@ func requireNoExecError(err error, step string) { } } - func waitForCoreServiceHealth(ctx context.Context) error { timeout := time.After(15 * time.Minute) ticker := time.NewTicker(15 * time.Second) @@ -149,7 +148,6 @@ func waitForCoreServiceHealth(ctx context.Context) error { } } - func executeHTTPRequest(ctx context.Context, method, endpoint, data string) (string, error) { args := []string{"curl", "-s", "-X", method} @@ -179,4 +177,4 @@ func curlContainer(ctx context.Context, cmd []string) (string, error) { WithEnvVariable("CACHEBUSTER", time.Now().String()). WithExec(cmd). Stdout(ctx) -} \ No newline at end of file +} From a33d82e0af5fb4111e6cd9c88652129ca266ae1f Mon Sep 17 00:00:00 2001 From: Aditya Chopra Date: Mon, 22 Dec 2025 00:32:30 +0530 Subject: [PATCH 9/9] docs: create documentation for HarborTest function Signed-off-by: Aditya Chopra --- .dagger/README.md | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/.dagger/README.md b/.dagger/README.md index 5655ae683..59bf46e34 100644 --- a/.dagger/README.md +++ b/.dagger/README.md @@ -70,6 +70,14 @@ dagger call publish-image \ --imageTags=v0.1.0,latest ``` +### `HarborTest(context)` + +Runs all Go tests inside Dagger containers, executing them against a Harbor service running as a Dagger service. Test output is streamed to the console. + +```bash +dagger call harbor-test +``` + --- ## ⚙️ Configuration Constants