diff --git a/assets/knative/service.yaml.tmpl b/assets/knative/service.yaml.tmpl index 8c3abab..84b74c7 100644 --- a/assets/knative/service.yaml.tmpl +++ b/assets/knative/service.yaml.tmpl @@ -1,11 +1,11 @@ apiVersion: serving.knative.dev/v1 kind: Service metadata: - name: {{ .Name }} + name: {{ .DockerImage.Name }} namespace: default spec: template: spec: containers: - - image: {{ .RemoteTag }} + - image: {{ .DockerImage.RemoteTag }}@{{ .ImageDigest }} imagePullPolicy: Always diff --git a/src/cli/deploy.go b/src/cli/deploy.go index 134ad05..fe24f42 100644 --- a/src/cli/deploy.go +++ b/src/cli/deploy.go @@ -20,7 +20,12 @@ func (c *icli) Deploy(cCtx *cli.Context) error { return err } - return knative.Apply(cCtx.String(namespaceFlag), config, project, c.dockerImage) + imageDigest, err := c.DockerService.GetImageDigest() + if err != nil { + return err + } + + return knative.Apply(cCtx.String(namespaceFlag), config, project, c.dockerImage, imageDigest) } func (c icli) DeployCMD() *cli.Command { diff --git a/src/services/docker/docker.go b/src/services/docker/docker.go index 7af5280..8dba39a 100644 --- a/src/services/docker/docker.go +++ b/src/services/docker/docker.go @@ -183,3 +183,24 @@ func (ds DockerService) Push() error { return logger.PrintStream(pushResponse) } + +func (ds DockerService) GetImageDigest() (string, error) { + logger.PrintInfo("Getting manifest digest for " + ds.dockerImage.RemoteTag()) + logger.PrintInfo("User: " + ds.AuthConfig.Username) + ctx, cancel := context.WithTimeout(context.Background(), time.Second*120) + defer cancel() + + encodedJSON, err := json.Marshal(ds.AuthConfig) + if err != nil { + return "", err + } + + encodedRegistryAuth := base64.URLEncoding.EncodeToString(encodedJSON) + distributionInspect, err := ds.Client.DistributionInspect(ctx, ds.dockerImage.RemoteTag(), encodedRegistryAuth) + if err != nil { + return "", err + } + + digest := distributionInspect.Descriptor.Digest + return fmt.Sprintf("%s", digest), nil +} diff --git a/src/services/k8s/knative.go b/src/services/k8s/knative.go index 744dd6f..3951ac5 100644 --- a/src/services/k8s/knative.go +++ b/src/services/k8s/knative.go @@ -23,6 +23,11 @@ import ( servingv1client "knative.dev/serving/pkg/client/clientset/versioned/typed/serving/v1" ) +type Image struct { + DockerImage docker.DockerImage + ImageDigest string +} + func Config(endpoint string, token string, caCrt []byte) (*rest.Config, error) { if _, err := certutil.NewPoolFromBytes(caCrt); err != nil { return nil, fmt.Errorf("Expected to load root CA from bytes, but got err: %v", err) @@ -37,7 +42,7 @@ func Config(endpoint string, token string, caCrt []byte) (*rest.Config, error) { }, nil } -func loadManifest(project *project.Project, dockerImage docker.DockerImage) (*servingv1.Service, error) { +func loadManifest(project *project.Project, image Image) (*servingv1.Service, error) { knativeTemplate := path.Join("assets", "knative", "service.yaml.tmpl") template, err := template.ParseFS(project.Resources, knativeTemplate) if err != nil { @@ -46,7 +51,7 @@ func loadManifest(project *project.Project, dockerImage docker.DockerImage) (*se output := &bytes.Buffer{} // TODO replace map[string]string{} with proper values - if err = template.Execute(output, dockerImage); err != nil { + if err = template.Execute(output, image); err != nil { return nil, err } @@ -71,12 +76,17 @@ func loadManifest(project *project.Project, dockerImage docker.DockerImage) (*se return service, nil } -func Apply(namespace string, config *rest.Config, project *project.Project, dockerImage docker.DockerImage) error { +func Apply(namespace string, config *rest.Config, project *project.Project, dockerImage docker.DockerImage, imageDigest string) error { log.Info("Deploying Knative service", "host", config.Host, "name", project.Name, "namespace", namespace) ctx, cancel := context.WithTimeout(context.Background(), time.Minute*5) defer cancel() - serviceManifest, err := loadManifest(project, dockerImage) + image := Image{ + DockerImage: dockerImage, + ImageDigest: imageDigest, + } + + serviceManifest, err := loadManifest(project, image) if err != nil { return err } diff --git a/src/services/k8s/knative_test.go b/src/services/k8s/knative_test.go index 8ba5320..b4a231e 100644 --- a/src/services/k8s/knative_test.go +++ b/src/services/k8s/knative_test.go @@ -59,14 +59,17 @@ func TestLoadManifest(t *testing.T) { Resources: os.DirFS(root), } - docker_image := docker.DockerImage{ - Registry: "example.com", - Directory: ".", - Name: "test", - Tag: "v1.1.0", + image := Image{ + DockerImage: docker.DockerImage{ + Registry: "example.com", + Directory: ".", + Name: "test", + Tag: "v1.1.0", + }, + ImageDigest: "sha256:3556949350924148437d1c40a2bfd74335fcd045da8b298e4ec4b6d5c53b4dc8", } - _, err := loadManifest(proj_knative, docker_image) + _, err := loadManifest(proj_knative, image) if err != nil { t.Fatalf(fmt.Sprintf("Error: %v", err))