diff options
author | Valentin Rothberg <rothberg@redhat.com> | 2021-10-13 16:33:38 +0200 |
---|---|---|
committer | Valentin Rothberg <rothberg@redhat.com> | 2021-10-26 13:51:45 +0200 |
commit | 75f478c08b82a9d6a99628bee5698a85610f863c (patch) | |
tree | 2045a9f38472aa878e9d34bfff82afe800845329 /pkg/specgen | |
parent | 9d2b8d2791c23b83b6155b046099a83483860c56 (diff) | |
download | podman-75f478c08b82a9d6a99628bee5698a85610f863c.tar.gz podman-75f478c08b82a9d6a99628bee5698a85610f863c.tar.bz2 podman-75f478c08b82a9d6a99628bee5698a85610f863c.zip |
pod create: remove need for pause image
So far, the infra containers of pods required pulling down an image
rendering pods not usable in disconnected environments. Instead, build
an image locally which uses local pause binary.
Fixes: #10354
Signed-off-by: Valentin Rothberg <rothberg@redhat.com>
Diffstat (limited to 'pkg/specgen')
-rw-r--r-- | pkg/specgen/generate/pod_create.go | 97 |
1 files changed, 96 insertions, 1 deletions
diff --git a/pkg/specgen/generate/pod_create.go b/pkg/specgen/generate/pod_create.go index a4027eae7..88ebc7ae3 100644 --- a/pkg/specgen/generate/pod_create.go +++ b/pkg/specgen/generate/pod_create.go @@ -2,8 +2,12 @@ package generate import ( "context" + "fmt" + "io/ioutil" "net" + "os" + buildahDefine "github.com/containers/buildah/define" "github.com/containers/common/pkg/config" "github.com/containers/podman/v3/libpod" "github.com/containers/podman/v3/libpod/define" @@ -14,10 +18,102 @@ import ( "github.com/sirupsen/logrus" ) +func buildPauseImage(rt *libpod.Runtime, rtConfig *config.Config) (string, error) { + version, err := define.GetVersion() + if err != nil { + return "", err + } + imageName := fmt.Sprintf("localhost/podman-pause:%s-%d", version.Version, version.Built) + + // First check if the image has already been built. + if _, _, err := rt.LibimageRuntime().LookupImage(imageName, nil); err == nil { + return imageName, nil + } + + // NOTE: Having the pause binary in its own directory keeps the door + // open for replacing the image building with using an overlay root FS. + // The latter turned out to be complex and error prone (see #11956) but + // we may be able to come up with a proper solution at a later point in + // time. + pausePath, err := rtConfig.FindHelperBinary("pause/pause", false) + if err != nil { + return "", fmt.Errorf("finding pause binary: %w", err) + } + + buildContent := fmt.Sprintf(`FROM scratch +COPY %s /pause +ENTRYPOINT ["/pause"]`, pausePath) + + tmpF, err := ioutil.TempFile("", "pause.containerfile") + if err != nil { + return "", err + } + if _, err := tmpF.WriteString(buildContent); err != nil { + return "", err + } + if err := tmpF.Close(); err != nil { + return "", err + } + defer os.Remove(tmpF.Name()) + + buildOptions := buildahDefine.BuildOptions{ + CommonBuildOpts: &buildahDefine.CommonBuildOptions{}, + Output: imageName, + Quiet: true, + IIDFile: "/dev/null", // prevents Buildah from writing the ID on stdout + } + if _, _, err := rt.Build(context.Background(), buildOptions, tmpF.Name()); err != nil { + return "", err + } + + return imageName, nil +} + +func pullOrBuildInfraImage(p *entities.PodSpec, rt *libpod.Runtime) error { + if p.PodSpecGen.NoInfra { + return nil + } + + rtConfig, err := rt.GetConfigNoCopy() + if err != nil { + return err + } + + // NOTE: we need pull down the infra image if it was explicitly set by + // the user (or containers.conf) to the non-default one. + imageName := p.PodSpecGen.InfraImage + if imageName == "" { + imageName = rtConfig.Engine.InfraImage + } + + if imageName != config.DefaultInfraImage { + _, err := rt.LibimageRuntime().Pull(context.Background(), imageName, config.PullPolicyMissing, nil) + if err != nil { + return err + } + } else { + name, err := buildPauseImage(rt, rtConfig) + if err != nil { + return fmt.Errorf("building local pause image: %w", err) + } + imageName = name + } + + p.PodSpecGen.InfraImage = imageName + p.PodSpecGen.InfraContainerSpec.RawImageName = imageName + + return nil +} + func MakePod(p *entities.PodSpec, rt *libpod.Runtime) (*libpod.Pod, error) { if err := p.PodSpecGen.Validate(); err != nil { return nil, err } + + if err := pullOrBuildInfraImage(p, rt); err != nil { + return nil, err + } + if !p.PodSpecGen.NoInfra && p.PodSpecGen.InfraContainerSpec != nil { var err error p.PodSpecGen.InfraContainerSpec, err = MapSpec(&p.PodSpecGen) @@ -35,7 +131,6 @@ func MakePod(p *entities.PodSpec, rt *libpod.Runtime) (*libpod.Pod, error) { return nil, err } if !p.PodSpecGen.NoInfra && p.PodSpecGen.InfraContainerSpec != nil { - p.PodSpecGen.InfraContainerSpec.ContainerCreateCommand = []string{} // we do NOT want os.Args as the command, will display the pod create cmd if p.PodSpecGen.InfraContainerSpec.Name == "" { p.PodSpecGen.InfraContainerSpec.Name = pod.ID()[:12] + "-infra" } |