podman/test/e2e/play_build_test.go

389 lines
13 KiB
Go

//go:build !remote_testing
// build for play kube is not supported on remote yet.
package integration
import (
"os"
"path/filepath"
. "github.com/containers/podman/v5/test/utils"
. "github.com/onsi/ginkgo/v2"
. "github.com/onsi/gomega"
. "github.com/onsi/gomega/gexec"
)
var _ = Describe("Podman play kube with build", func() {
var testYAML = `
apiVersion: v1
kind: Pod
metadata:
creationTimestamp: "2021-08-05T17:55:51Z"
labels:
app: foobar
name: top_pod
spec:
containers:
- command:
- top
env:
- name: PATH
value: /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
- name: TERM
value: xterm
- name: container
value: podman
image: foobar
name: foobar
resources: {}
securityContext:
allowPrivilegeEscalation: true
privileged: false
readOnlyRootFilesystem: false
seLinuxOptions: {}
tty: true
workingDir: /
dnsConfig: {}
status: {}
`
var playBuildFile = `
FROM ` + CITEST_IMAGE + `
LABEL homer=dad
COPY copyfile /copyfile
`
var prebuiltImage = `
FROM ` + CITEST_IMAGE + `
LABEL marge=mom
`
var copyFile = `just a text file
`
It("Check that image is built using Dockerfile", func() {
// Setup
yamlDir := filepath.Join(tempdir, RandomString(12))
err := os.Mkdir(yamlDir, 0755)
Expect(err).ToNot(HaveOccurred(), "mkdir "+yamlDir)
err = writeYaml(testYAML, filepath.Join(yamlDir, "top.yaml"))
Expect(err).ToNot(HaveOccurred())
app1Dir := filepath.Join(yamlDir, "foobar")
err = os.Mkdir(app1Dir, 0755)
Expect(err).ToNot(HaveOccurred())
err = writeYaml(playBuildFile, filepath.Join(app1Dir, "Dockerfile"))
Expect(err).ToNot(HaveOccurred())
// Write a file to be copied
err = writeYaml(copyFile, filepath.Join(app1Dir, "copyfile"))
Expect(err).ToNot(HaveOccurred())
// Switch to temp dir and restore it afterwards
cwd, err := os.Getwd()
Expect(err).ToNot(HaveOccurred())
Expect(os.Chdir(yamlDir)).To(Succeed())
defer func() { Expect(os.Chdir(cwd)).To(Succeed()) }()
session := podmanTest.Podman([]string{"kube", "play", "top.yaml"})
session.WaitWithDefaultTimeout()
Expect(session).Should(Exit(0))
stdErrString := session.ErrorToString()
Expect(stdErrString).To(ContainSubstring("Getting image source signatures"))
Expect(stdErrString).To(ContainSubstring("Writing manifest to image destination"))
exists := podmanTest.Podman([]string{"image", "exists", "foobar"})
exists.WaitWithDefaultTimeout()
Expect(exists).Should(ExitCleanly())
inspect := podmanTest.Podman([]string{"container", "inspect", "top_pod-foobar"})
inspect.WaitWithDefaultTimeout()
Expect(inspect).Should(ExitCleanly())
inspectData := inspect.InspectContainerToJSON()
Expect(inspectData).ToNot(BeEmpty())
Expect(inspectData[0].Config.Labels).To(HaveKeyWithValue("homer", "dad"))
})
It("Check that image is built using Containerfile", func() {
// Setup
yamlDir := filepath.Join(tempdir, RandomString(12))
err := os.Mkdir(yamlDir, 0755)
Expect(err).ToNot(HaveOccurred(), "mkdir "+yamlDir)
err = writeYaml(testYAML, filepath.Join(yamlDir, "top.yaml"))
Expect(err).ToNot(HaveOccurred())
app1Dir := filepath.Join(yamlDir, "foobar")
err = os.Mkdir(app1Dir, 0755)
Expect(err).ToNot(HaveOccurred())
err = writeYaml(playBuildFile, filepath.Join(app1Dir, "Containerfile"))
Expect(err).ToNot(HaveOccurred())
// Write a file to be copied
err = writeYaml(copyFile, filepath.Join(app1Dir, "copyfile"))
Expect(err).ToNot(HaveOccurred())
// Switch to temp dir and restore it afterwards
cwd, err := os.Getwd()
Expect(err).ToNot(HaveOccurred())
Expect(os.Chdir(yamlDir)).To(Succeed())
defer func() { Expect(os.Chdir(cwd)).To(Succeed()) }()
session := podmanTest.Podman([]string{"kube", "play", "top.yaml"})
session.WaitWithDefaultTimeout()
Expect(session).Should(Exit(0))
stdErrString := session.ErrorToString()
Expect(stdErrString).To(ContainSubstring("Getting image source signatures"))
Expect(stdErrString).To(ContainSubstring("Writing manifest to image destination"))
exists := podmanTest.Podman([]string{"image", "exists", "foobar"})
exists.WaitWithDefaultTimeout()
Expect(exists).Should(ExitCleanly())
inspect := podmanTest.Podman([]string{"container", "inspect", "top_pod-foobar"})
inspect.WaitWithDefaultTimeout()
Expect(inspect).Should(ExitCleanly())
inspectData := inspect.InspectContainerToJSON()
Expect(inspectData).ToNot(BeEmpty())
Expect(inspectData[0].Config.Labels).To(HaveKeyWithValue("homer", "dad"))
})
It("Do not build image if already in the local store", func() {
// Setup
yamlDir := filepath.Join(tempdir, RandomString(12))
err := os.Mkdir(yamlDir, 0755)
Expect(err).ToNot(HaveOccurred(), "mkdir "+yamlDir)
err = writeYaml(testYAML, filepath.Join(yamlDir, "top.yaml"))
Expect(err).ToNot(HaveOccurred())
// build an image called foobar but make sure it doesn't have
// the same label as the yaml buildfile, so we can check that
// the image is NOT rebuilt.
err = writeYaml(prebuiltImage, filepath.Join(yamlDir, "Containerfile"))
Expect(err).ToNot(HaveOccurred())
app1Dir := filepath.Join(yamlDir, "foobar")
err = os.Mkdir(app1Dir, 0755)
Expect(err).ToNot(HaveOccurred())
err = writeYaml(playBuildFile, filepath.Join(app1Dir, "Containerfile"))
Expect(err).ToNot(HaveOccurred())
// Write a file to be copied
err = writeYaml(copyFile, filepath.Join(app1Dir, "copyfile"))
Expect(err).ToNot(HaveOccurred())
// Switch to temp dir and restore it afterwards
cwd, err := os.Getwd()
Expect(err).ToNot(HaveOccurred())
Expect(os.Chdir(yamlDir)).To(Succeed())
defer func() { Expect(os.Chdir(cwd)).To(Succeed()) }()
// Build the image into the local store
build := podmanTest.Podman([]string{"build", "-t", "foobar", "-f", "Containerfile"})
build.WaitWithDefaultTimeout()
Expect(build).Should(ExitCleanly())
session := podmanTest.Podman([]string{"kube", "play", "top.yaml"})
session.WaitWithDefaultTimeout()
Expect(session).Should(ExitCleanly())
inspect := podmanTest.Podman([]string{"container", "inspect", "top_pod-foobar"})
inspect.WaitWithDefaultTimeout()
Expect(inspect).Should(ExitCleanly())
inspectData := inspect.InspectContainerToJSON()
Expect(inspectData).ToNot(BeEmpty())
Expect(inspectData[0].Config.Labels).To(Not(HaveKey("homer")))
Expect(inspectData[0].Config.Labels).To(HaveKeyWithValue("marge", "mom"))
})
It("Do not build image at all if --build=false", func() {
// Setup
yamlDir := filepath.Join(tempdir, RandomString(12))
err := os.Mkdir(yamlDir, 0755)
Expect(err).ToNot(HaveOccurred(), "mkdir "+yamlDir)
err = writeYaml(testYAML, filepath.Join(yamlDir, "top.yaml"))
Expect(err).ToNot(HaveOccurred())
// build an image called foobar but make sure it doesn't have
// the same label as the yaml buildfile, so we can check that
// the image is NOT rebuilt.
err = writeYaml(prebuiltImage, filepath.Join(yamlDir, "Containerfile"))
Expect(err).ToNot(HaveOccurred())
app1Dir := filepath.Join(yamlDir, "foobar")
err = os.Mkdir(app1Dir, 0755)
Expect(err).ToNot(HaveOccurred())
err = writeYaml(playBuildFile, filepath.Join(app1Dir, "Containerfile"))
Expect(err).ToNot(HaveOccurred())
// Write a file to be copied
err = writeYaml(copyFile, filepath.Join(app1Dir, "copyfile"))
Expect(err).ToNot(HaveOccurred())
// Switch to temp dir and restore it afterwards
cwd, err := os.Getwd()
Expect(err).ToNot(HaveOccurred())
Expect(os.Chdir(yamlDir)).To(Succeed())
defer func() { Expect(os.Chdir(cwd)).To(Succeed()) }()
// Build the image into the local store
build := podmanTest.Podman([]string{"build", "-t", "foobar", "-f", "Containerfile"})
build.WaitWithDefaultTimeout()
Expect(build).Should(ExitCleanly())
session := podmanTest.Podman([]string{"kube", "play", "--build=false", "top.yaml"})
session.WaitWithDefaultTimeout()
Expect(session).Should(ExitCleanly())
inspect := podmanTest.Podman([]string{"container", "inspect", "top_pod-foobar"})
inspect.WaitWithDefaultTimeout()
Expect(inspect).Should(ExitCleanly())
inspectData := inspect.InspectContainerToJSON()
Expect(inspectData).ToNot(BeEmpty())
Expect(inspectData[0].Config.Labels).To(Not(HaveKey("homer")))
Expect(inspectData[0].Config.Labels).To(HaveKeyWithValue("marge", "mom"))
})
It("--build should override image in store", func() {
// Setup
yamlDir := filepath.Join(tempdir, RandomString(12))
err := os.Mkdir(yamlDir, 0755)
Expect(err).ToNot(HaveOccurred(), "os.Mkdir "+yamlDir)
err = writeYaml(testYAML, filepath.Join(yamlDir, "top.yaml"))
Expect(err).ToNot(HaveOccurred())
// build an image called foobar but make sure it doesn't have
// the same label as the yaml buildfile, so we can check that
// the image is NOT rebuilt.
err = writeYaml(prebuiltImage, filepath.Join(yamlDir, "Containerfile"))
Expect(err).ToNot(HaveOccurred())
app1Dir := filepath.Join(yamlDir, "foobar")
err = os.Mkdir(app1Dir, 0755)
Expect(err).ToNot(HaveOccurred())
err = writeYaml(playBuildFile, filepath.Join(app1Dir, "Containerfile"))
Expect(err).ToNot(HaveOccurred())
// Write a file to be copied
err = writeYaml(copyFile, filepath.Join(app1Dir, "copyfile"))
Expect(err).ToNot(HaveOccurred())
// Switch to temp dir and restore it afterwards
cwd, err := os.Getwd()
Expect(err).ToNot(HaveOccurred())
Expect(os.Chdir(yamlDir)).To(Succeed())
defer func() { Expect(os.Chdir(cwd)).To(Succeed()) }()
// Build the image into the local store
build := podmanTest.Podman([]string{"build", "-t", "foobar", "-f", "Containerfile"})
build.WaitWithDefaultTimeout()
Expect(build).Should(ExitCleanly())
session := podmanTest.Podman([]string{"kube", "play", "--build", "top.yaml"})
session.WaitWithDefaultTimeout()
Expect(session).Should(Exit(0))
stdErrString := session.ErrorToString()
Expect(stdErrString).To(ContainSubstring("Getting image source signatures"))
Expect(stdErrString).To(ContainSubstring("Writing manifest to image destination"))
inspect := podmanTest.Podman([]string{"container", "inspect", "top_pod-foobar"})
inspect.WaitWithDefaultTimeout()
Expect(inspect).Should(ExitCleanly())
inspectData := inspect.InspectContainerToJSON()
Expect(inspectData).ToNot(BeEmpty())
Expect(inspectData[0].Config.Labels).To(HaveKeyWithValue("homer", "dad"))
Expect(inspectData[0].Config.Labels).To(Not(HaveKey("marge")))
})
var testYAMLForEnvExpand = `
apiVersion: v1
kind: Pod
metadata:
creationTimestamp: "2021-08-05T17:55:51Z"
labels:
app: foobar
name: echo_pod
spec:
containers:
- command:
- /bin/sh
- -c
- 'echo paren$(FOO) brace${FOO} dollardollarparen$$(FOO) interp$(FOO)olate'
env:
- name: PATH
value: /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
- name: TERM
value: xterm
- name: container
value: podman
- name: FOO
value: BAR
image: foobar
name: foobar
resources: {}
securityContext:
allowPrivilegeEscalation: true
privileged: false
readOnlyRootFilesystem: false
seLinuxOptions: {}
tty: true
workingDir: /
restartPolicy: Never
dnsConfig: {}
status: {}
`
It("Check that command is expanded", func() {
// Setup
yamlDir := filepath.Join(tempdir, RandomString(12))
err := os.Mkdir(yamlDir, 0755)
Expect(err).ToNot(HaveOccurred(), "mkdir "+yamlDir)
err = writeYaml(testYAMLForEnvExpand, filepath.Join(yamlDir, "echo.yaml"))
Expect(err).ToNot(HaveOccurred())
app1Dir := filepath.Join(yamlDir, "foobar")
err = os.Mkdir(app1Dir, 0755)
Expect(err).ToNot(HaveOccurred())
err = writeYaml(playBuildFile+`ENV FOO foo-from-buildfile
COPY FOO /bin/FOO
`, filepath.Join(app1Dir, "Containerfile"))
Expect(err).ToNot(HaveOccurred())
// Write a file to be copied
err = writeYaml(copyFile, filepath.Join(app1Dir, "copyfile"))
Expect(err).ToNot(HaveOccurred())
// Shell expansion of $(FOO) in container needs executable FOO
err = writeYaml(`#!/bin/sh
echo GOT-HERE
`, filepath.Join(app1Dir, "FOO"))
Expect(err).ToNot(HaveOccurred())
err = os.Chmod(filepath.Join(app1Dir, "FOO"), 0555)
Expect(err).ToNot(HaveOccurred(), "chmod FOO")
os.Setenv("FOO", "make sure we use FOO from kube file, not env")
defer os.Unsetenv("FOO")
// Switch to temp dir and restore it afterwards
cwd, err := os.Getwd()
Expect(err).ToNot(HaveOccurred())
Expect(os.Chdir(yamlDir)).To(Succeed())
defer func() { Expect(os.Chdir(cwd)).To(Succeed()) }()
session := podmanTest.Podman([]string{"kube", "play", "echo.yaml"})
session.WaitWithDefaultTimeout()
Expect(session).Should(Exit(0))
stdErrString := session.ErrorToString()
Expect(stdErrString).To(ContainSubstring("Getting image source signatures"))
Expect(stdErrString).To(ContainSubstring("Writing manifest to image destination"))
cid := "echo_pod-foobar"
wait := podmanTest.Podman([]string{"wait", cid})
wait.WaitWithDefaultTimeout()
Expect(wait).To(ExitCleanly())
logs := podmanTest.Podman([]string{"logs", cid})
logs.WaitWithDefaultTimeout()
Expect(logs).Should(ExitCleanly())
Expect(logs.OutputToString()).To(Equal("parenBAR braceBAR dollardollarparenGOT-HERE interpBARolate"))
inspect := podmanTest.Podman([]string{"container", "inspect", cid})
inspect.WaitWithDefaultTimeout()
Expect(inspect).Should(ExitCleanly())
inspectData := inspect.InspectContainerToJSON()
Expect(inspectData).ToNot(BeEmpty())
// dollar-paren are expanded by podman, never seen by container
Expect(inspectData[0].Args).To(HaveLen(2))
Expect(inspectData[0].Args[1]).To(Equal("echo parenBAR brace${FOO} dollardollarparen$(FOO) interpBARolate"))
})
})