github.com/hanks177/podman/v4@v4.1.3-0.20220613032544-16d90015bc83/pkg/specgen/generate/pause_image.go (about)

     1  package generate
     2  
     3  import (
     4  	"context"
     5  	"fmt"
     6  	"io/ioutil"
     7  	"os"
     8  
     9  	buildahDefine "github.com/containers/buildah/define"
    10  	"github.com/containers/common/pkg/config"
    11  	"github.com/hanks177/podman/v4/libpod"
    12  	"github.com/hanks177/podman/v4/libpod/define"
    13  )
    14  
    15  // PullOrBuildInfraImage pulls down the specified image or the one set in
    16  // containers.conf.  If none is set, it builds a local pause image.
    17  func PullOrBuildInfraImage(rt *libpod.Runtime, imageName string) (string, error) {
    18  	rtConfig, err := rt.GetConfigNoCopy()
    19  	if err != nil {
    20  		return "", err
    21  	}
    22  
    23  	if imageName == "" {
    24  		imageName = rtConfig.Engine.InfraImage
    25  	}
    26  
    27  	if imageName != "" {
    28  		_, err := rt.LibimageRuntime().Pull(context.Background(), imageName, config.PullPolicyMissing, nil)
    29  		if err != nil {
    30  			return "", err
    31  		}
    32  		return imageName, nil
    33  	}
    34  
    35  	name, err := buildPauseImage(rt, rtConfig)
    36  	if err != nil {
    37  		return "", fmt.Errorf("building local pause image: %w", err)
    38  	}
    39  	return name, nil
    40  }
    41  
    42  func buildPauseImage(rt *libpod.Runtime, rtConfig *config.Config) (string, error) {
    43  	version, err := define.GetVersion()
    44  	if err != nil {
    45  		return "", err
    46  	}
    47  	imageName := fmt.Sprintf("localhost/podman-pause:%s-%d", version.Version, version.Built)
    48  
    49  	// First check if the image has already been built.
    50  	if _, _, err := rt.LibimageRuntime().LookupImage(imageName, nil); err == nil {
    51  		return imageName, nil
    52  	}
    53  
    54  	// Also look into the path as some distributions install catatonit in
    55  	// /usr/bin.
    56  	catatonitPath, err := rtConfig.FindHelperBinary("catatonit", true)
    57  	if err != nil {
    58  		return "", fmt.Errorf("finding pause binary: %w", err)
    59  	}
    60  
    61  	buildContent := fmt.Sprintf(`FROM scratch
    62  COPY %s /catatonit
    63  ENTRYPOINT ["/catatonit", "-P"]`, catatonitPath)
    64  
    65  	tmpF, err := ioutil.TempFile("", "pause.containerfile")
    66  	if err != nil {
    67  		return "", err
    68  	}
    69  	if _, err := tmpF.WriteString(buildContent); err != nil {
    70  		return "", err
    71  	}
    72  	if err := tmpF.Close(); err != nil {
    73  		return "", err
    74  	}
    75  	defer os.Remove(tmpF.Name())
    76  
    77  	buildOptions := buildahDefine.BuildOptions{
    78  		CommonBuildOpts: &buildahDefine.CommonBuildOptions{},
    79  		Output:          imageName,
    80  		Quiet:           true,
    81  		IgnoreFile:      "/dev/null", // makes sure to not read a local .ignorefile (see #13529)
    82  		IIDFile:         "/dev/null", // prevents Buildah from writing the ID on stdout
    83  		IDMappingOptions: &buildahDefine.IDMappingOptions{
    84  			// Use the host UID/GID mappings for the build to avoid issues when
    85  			// running with a custom mapping (BZ #2083997).
    86  			HostUIDMapping: true,
    87  			HostGIDMapping: true,
    88  		},
    89  	}
    90  	if _, _, err := rt.Build(context.Background(), buildOptions, tmpF.Name()); err != nil {
    91  		return "", err
    92  	}
    93  
    94  	return imageName, nil
    95  }