github.com/containers/podman/v4@v4.9.4/pkg/specgen/generate/pause_image.go (about)

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