package generate import ( "context" "fmt" "io/ioutil" "os" buildahDefine "github.com/containers/buildah/define" "github.com/containers/common/pkg/config" "github.com/containers/podman/v4/libpod" "github.com/containers/podman/v4/libpod/define" ) // PullOrBuildInfraImage pulls down the specified image or the one set in // containers.conf. If none is set, it builds a local pause image. func PullOrBuildInfraImage(rt *libpod.Runtime, imageName string) (string, error) { rtConfig, err := rt.GetConfigNoCopy() if err != nil { return "", err } if imageName == "" { imageName = rtConfig.Engine.InfraImage } if imageName != "" { _, err := rt.LibimageRuntime().Pull(context.Background(), imageName, config.PullPolicyMissing, nil) if err != nil { return "", err } return imageName, nil } name, err := buildPauseImage(rt, rtConfig) if err != nil { return "", fmt.Errorf("building local pause image: %w", err) } return name, nil } 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 } // Also look into the path as some distributions install catatonit in // /usr/bin. catatonitPath, err := rtConfig.FindHelperBinary("catatonit", true) if err != nil { return "", fmt.Errorf("finding pause binary: %w", err) } buildContent := fmt.Sprintf(`FROM scratch COPY %s /catatonit ENTRYPOINT ["/catatonit", "-P"]`, catatonitPath) 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, IgnoreFile: "/dev/null", // makes sure to not read a local .ignorefile (see #13529) 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 }