Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 13 additions & 3 deletions pkg/app/pipedv1/plugin/kubernetes/provider/deployment.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,15 +21,25 @@ import (
// FindContainerImages finds all container images that are referenced by the given manifest.
//
// It looks for container images in the following fields:
// - spec.template.spec.containers.image
//
// TODO: we should consider other fields like spec.template.spec.initContainers.image, spec.jobTempate.spec.template.spec.containers.image
// - spec.template.spec.containers[*].image
// - spec.template.spec.initContainers[*].image
// - spec.jobTemplate.spec.template.spec.containers[*].image
// - spec.jobTemplate.spec.template.spec.initContainers[*].image
func FindContainerImages(m Manifest) []string {
var images []string

if n := nestedStringSlice(m.body.Object, "spec", "template", "spec", "containers", "image"); len(n) > 0 {
images = append(images, n...)
}
if n := nestedStringSlice(m.body.Object, "spec", "template", "spec", "initContainers", "image"); len(n) > 0 {
images = append(images, n...)
}
if n := nestedStringSlice(m.body.Object, "spec", "jobTemplate", "spec", "template", "spec", "containers", "image"); len(n) > 0 {
images = append(images, n...)
}
if n := nestedStringSlice(m.body.Object, "spec", "jobTemplate", "spec", "template", "spec", "initContainers", "image"); len(n) > 0 {
images = append(images, n...)
}

slices.Sort(images)
return slices.Compact(images)
Expand Down
99 changes: 99 additions & 0 deletions pkg/app/pipedv1/plugin/kubernetes/provider/deployment_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -527,6 +527,105 @@ spec:
`,
expected: []string{"gcr.io/pipecd/helloworld:v0.5.0", "gcr.io/pipecd/sidecar:v0.5.0"},
},
{
name: "deployment with initContainers returns images from both containers and initContainers",
manifest: `
apiVersion: apps/v1
kind: Deployment
metadata:
name: with-init
labels:
app: with-init
spec:
replicas: 1
selector:
matchLabels:
app: with-init
template:
metadata:
labels:
app: with-init
spec:
initContainers:
- name: init-migrator
image: gcr.io/pipecd/migrator:v1.0.0
containers:
- name: app
image: gcr.io/pipecd/helloworld:v0.5.0
ports:
- containerPort: 9085
`,
expected: []string{"gcr.io/pipecd/helloworld:v0.5.0", "gcr.io/pipecd/migrator:v1.0.0"},
},
{
name: "cronjob returns images from spec.jobTemplate.spec.template.spec.containers",
manifest: `
apiVersion: batch/v1
kind: CronJob
metadata:
name: hello
spec:
schedule: "*/5 * * * *"
jobTemplate:
spec:
template:
spec:
containers:
- name: hello
image: gcr.io/pipecd/hello-job:v2.0.0
restartPolicy: OnFailure
`,
expected: []string{"gcr.io/pipecd/hello-job:v2.0.0"},
},
{
name: "cronjob with initContainers returns images from all jobTemplate paths",
manifest: `
apiVersion: batch/v1
kind: CronJob
metadata:
name: hello-with-init
spec:
schedule: "0 * * * *"
jobTemplate:
spec:
template:
spec:
initContainers:
- name: init-job
image: gcr.io/pipecd/init-job:v1.1.0
containers:
- name: main-job
image: gcr.io/pipecd/main-job:v1.2.0
restartPolicy: OnFailure
`,
expected: []string{"gcr.io/pipecd/init-job:v1.1.0", "gcr.io/pipecd/main-job:v1.2.0"},
},
{
name: "duplicates across paths are deduplicated",
manifest: `
apiVersion: apps/v1
kind: Deployment
metadata:
name: dedup-test
spec:
replicas: 1
selector:
matchLabels:
app: dedup-test
template:
metadata:
labels:
app: dedup-test
spec:
initContainers:
- name: init-a
image: gcr.io/pipecd/shared:v1.0.0
containers:
- name: main
image: gcr.io/pipecd/shared:v1.0.0
`,
expected: []string{"gcr.io/pipecd/shared:v1.0.0"},
},
}

for _, tc := range testcases {
Expand Down
Loading