From 3a74cfbc15a43ee6ec88960d9c0b88410240d001 Mon Sep 17 00:00:00 2001 From: Tim Olbrich Date: Tue, 19 May 2020 23:44:45 +0200 Subject: [PATCH] #2 Image Push working --- ...harbourrocks_harbour_cmd_harbour_build.xml | 1 + deployments/registry/docker-compose.yml | 2 +- pkg/harbourbuild/builder.go | 55 +++++++++++++++---- pkg/harbourbuild/handler/build.go | 13 +++-- pkg/harbourbuild/models/buildjob.go | 1 + 5 files changed, 56 insertions(+), 16 deletions(-) diff --git a/.idea/runConfigurations/go_build_github_com_harbourrocks_harbour_cmd_harbour_build.xml b/.idea/runConfigurations/go_build_github_com_harbourrocks_harbour_cmd_harbour_build.xml index 5e2ec48..c36ff1d 100644 --- a/.idea/runConfigurations/go_build_github_com_harbourrocks_harbour_cmd_harbour_build.xml +++ b/.idea/runConfigurations/go_build_github_com_harbourrocks_harbour_cmd_harbour_build.xml @@ -9,6 +9,7 @@ + diff --git a/deployments/registry/docker-compose.yml b/deployments/registry/docker-compose.yml index ce4221b..bdee48e 100644 --- a/deployments/registry/docker-compose.yml +++ b/deployments/registry/docker-compose.yml @@ -7,7 +7,7 @@ services: - 5000:5000 environment: REGISTRY_AUTH_TOKEN_AUTOREDIRECT: "false" - REGISTRY_AUTH_TOKEN_REALM: http://192.168.0.10:5100/docker/auth/token + REGISTRY_AUTH_TOKEN_REALM: http://192.168.178.42:5100/docker/auth/token REGISTRY_AUTH_TOKEN_SERVICE: http://localhost:5000 REGISTRY_AUTH_TOKEN_ISSUER: http://localhost:5100 REGISTRY_AUTH_TOKEN_ROOTCERTBUNDLE: /certs/registry-auth.crt diff --git a/pkg/harbourbuild/builder.go b/pkg/harbourbuild/builder.go index 1c1b559..dc1bda7 100644 --- a/pkg/harbourbuild/builder.go +++ b/pkg/harbourbuild/builder.go @@ -85,7 +85,19 @@ func (b Builder) buildImage(job models.BuildJob) { } redisClient.HSet(job.BuildKey, "build_status", "Success", "logs", logs) - l.Trace("Image was built") + l.Tracef("Image %s was built", job.Request.Project) + + imageString := b.getImageString(job.RegistryUrl, job.Request.Project) + if len(job.Request.Tags) > 0 { + imageString += ":" + job.Request.Tags[0] + } + + if err = b.pushImage(imageString, job.RegistryToken); err != nil { + l.WithError(err).Error("Error while pushing image to registry") + return + } + + l.Tracef("Image %s was pushed to registry %s", job.Request.Project, job.RegistryUrl) } func (b Builder) cleanUpAfterBuild(buildContext *os.File, logs io.ReadCloser) { @@ -98,12 +110,6 @@ func (b Builder) cleanUpAfterBuild(buildContext *os.File, logs io.ReadCloser) { } } -//TODO Communicate with Harbour SCM in order to receive the path to the project-files -func (b Builder) getProjectPath(project string) (string, error) { - // Just returns a demo path - return fmt.Sprintf(b.repoPath+"%s", project), nil -} - func (b Builder) createBuildContext(project string) (*os.File, error) { buildContext := fmt.Sprintf(b.ctxPath+"%s.tar", project) projectPath, err := b.getProjectPath(project) @@ -126,21 +132,48 @@ func (b Builder) createBuildContext(project string) (*os.File, error) { } func (b Builder) pushImage(image string, token string) error { - authConfig := types.AuthConfig{IdentityToken: token} + authConfig := types.AuthConfig{RegistryToken: token} encodedJSON, err := json.Marshal(authConfig) if err != nil { return err } authStr := base64.URLEncoding.EncodeToString(encodedJSON) + options := types.ImagePushOptions{RegistryAuth: authStr} - out, err := b.cli.ImagePush(b.ctx, image, types.ImagePushOptions{RegistryAuth: authStr}) + out, err := b.cli.ImagePush(b.ctx, image, options) if err != nil { return err } - defer out.Close() - io.Copy(os.Stdout, out) + defer func() { + err = out.Close() + if err != nil { + l.WithError(err).Error("Error while closing file") + return + } + }() + + buf := new(bytes.Buffer) + _, err = buf.ReadFrom(out) + if err != nil { + return err + } + + logs := buf.String() + if strings.Contains(logs, "errorDetail") { + return fmt.Errorf("unable to push image: %s", logs) + } return nil } + +func (b Builder) getImageString(registryUrl string, image string) string { + return fmt.Sprintf("%s/%s", strings.Split(registryUrl, "//")[1], image) +} + +//TODO Communicate with Harbour SCM in order to receive the path to the project-files +func (b Builder) getProjectPath(project string) (string, error) { + // Just returns a demo path + return fmt.Sprintf(b.repoPath+"%s", project), nil +} diff --git a/pkg/harbourbuild/handler/build.go b/pkg/harbourbuild/handler/build.go index 6080c14..ffa8bd9 100644 --- a/pkg/harbourbuild/handler/build.go +++ b/pkg/harbourbuild/handler/build.go @@ -36,7 +36,7 @@ func (b BuilderModel) BuildImage(w http.ResponseWriter, r *http.Request) { return } - registryToken, err := fetchRegistryToken(r.Context(), b.config) + registryToken, err := fetchRegistryToken(r.Context(), buildRequest.Project, b.config) if err != nil { return // Error is already logged in get } @@ -47,7 +47,12 @@ func (b BuilderModel) BuildImage(w http.ResponseWriter, r *http.Request) { return } - b.buildChan <- models.BuildJob{Request: buildRequest, BuildKey: buildKey, RegistryToken: registryToken} + b.buildChan <- models.BuildJob{ + Request: buildRequest, + BuildKey: buildKey, + RegistryToken: registryToken, + RegistryUrl: b.config.DockerRegistry.RegistryUrl, + } log.Trace("Build job enqueued") w.WriteHeader(http.StatusAccepted) @@ -74,9 +79,9 @@ func createBuildEntry(ctx context.Context, request models.BuildRequest) (string, return buildKey, nil } -func fetchRegistryToken(ctx context.Context, registry *configuration.Options) (string, error) { +func fetchRegistryToken(ctx context.Context, repository string, registry *configuration.Options) (string, error) { oidcTokenStr := auth.GetOidcTokenStrCtx(ctx) - tokenUrl := registry.DockerRegistry.TokenURL("repository", "test", "push") + tokenUrl := registry.DockerRegistry.TokenURL("repository", repository, "push,pull") var registryToken string var tokenResponse registryModels.DockerTokenResponse diff --git a/pkg/harbourbuild/models/buildjob.go b/pkg/harbourbuild/models/buildjob.go index f0af12b..3eb7202 100644 --- a/pkg/harbourbuild/models/buildjob.go +++ b/pkg/harbourbuild/models/buildjob.go @@ -6,4 +6,5 @@ type BuildJob struct { Request BuildRequest BuildKey string RegistryToken string + RegistryUrl string }