mirror of
https://github.com/containers/podman.git
synced 2025-09-27 00:34:32 +08:00
Set --force-rm for podman build to true by default
Since we use buildah containers for the build process, the user will not know if we have any buildah containers lingering due to a failed build. Setting this to true by default till we figure out a better way to solve this. Signed-off-by: Urvashi Mohnani <umohnani@redhat.com>
This commit is contained in:
@ -1,6 +1,11 @@
|
|||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"io/ioutil"
|
||||||
|
"os"
|
||||||
|
"path/filepath"
|
||||||
|
"strings"
|
||||||
|
|
||||||
"github.com/containers/buildah"
|
"github.com/containers/buildah"
|
||||||
"github.com/containers/buildah/imagebuildah"
|
"github.com/containers/buildah/imagebuildah"
|
||||||
buildahcli "github.com/containers/buildah/pkg/cli"
|
buildahcli "github.com/containers/buildah/pkg/cli"
|
||||||
@ -10,14 +15,14 @@ import (
|
|||||||
"github.com/pkg/errors"
|
"github.com/pkg/errors"
|
||||||
"github.com/sirupsen/logrus"
|
"github.com/sirupsen/logrus"
|
||||||
"github.com/urfave/cli"
|
"github.com/urfave/cli"
|
||||||
"io/ioutil"
|
|
||||||
"os"
|
|
||||||
"path/filepath"
|
|
||||||
"strings"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
layerFlags = []cli.Flag{
|
layerFlags = []cli.Flag{
|
||||||
|
cli.BoolTFlag{
|
||||||
|
Name: "force-rm",
|
||||||
|
Usage: "Always remove intermediate containers after a build, even if the build is unsuccessful. (default true)",
|
||||||
|
},
|
||||||
cli.BoolTFlag{
|
cli.BoolTFlag{
|
||||||
Name: "layers",
|
Name: "layers",
|
||||||
Usage: "cache intermediate layers during build. Use BUILDAH_LAYERS environment variable to override. ",
|
Usage: "cache intermediate layers during build. Use BUILDAH_LAYERS environment variable to override. ",
|
||||||
@ -230,7 +235,7 @@ func buildCmd(c *cli.Context) error {
|
|||||||
Layers: layers,
|
Layers: layers,
|
||||||
NoCache: c.Bool("no-cache"),
|
NoCache: c.Bool("no-cache"),
|
||||||
RemoveIntermediateCtrs: c.BoolT("rm"),
|
RemoveIntermediateCtrs: c.BoolT("rm"),
|
||||||
ForceRmIntermediateCtrs: c.Bool("force-rm"),
|
ForceRmIntermediateCtrs: c.BoolT("force-rm"),
|
||||||
}
|
}
|
||||||
|
|
||||||
if c.Bool("quiet") {
|
if c.Bool("quiet") {
|
||||||
|
@ -92,7 +92,7 @@ k8s.io/kube-openapi 275e2ce91dec4c05a4094a7b1daee5560b555ac9 https://github.com/
|
|||||||
k8s.io/utils 258e2a2fa64568210fbd6267cf1d8fd87c3cb86e https://github.com/kubernetes/utils
|
k8s.io/utils 258e2a2fa64568210fbd6267cf1d8fd87c3cb86e https://github.com/kubernetes/utils
|
||||||
github.com/mrunalp/fileutils master
|
github.com/mrunalp/fileutils master
|
||||||
github.com/varlink/go master
|
github.com/varlink/go master
|
||||||
github.com/containers/buildah 46c577c87d5a7ab30ef40cfa695cd2b96b32b117
|
github.com/containers/buildah 795d43e60e5a1ab283981b79eeda1dd14a65a0bd
|
||||||
github.com/Nvveen/Gotty master
|
github.com/Nvveen/Gotty master
|
||||||
github.com/fsouza/go-dockerclient master
|
github.com/fsouza/go-dockerclient master
|
||||||
github.com/openshift/imagebuilder master
|
github.com/openshift/imagebuilder master
|
||||||
|
1
vendor/github.com/containers/buildah/README.md
generated
vendored
1
vendor/github.com/containers/buildah/README.md
generated
vendored
@ -107,6 +107,7 @@ $ sudo ./lighttpd.sh
|
|||||||
| [buildah-images(1)](/docs/buildah-images.md) | List images in local storage. |
|
| [buildah-images(1)](/docs/buildah-images.md) | List images in local storage. |
|
||||||
| [buildah-inspect(1)](/docs/buildah-inspect.md) | Inspects the configuration of a container or image. |
|
| [buildah-inspect(1)](/docs/buildah-inspect.md) | Inspects the configuration of a container or image. |
|
||||||
| [buildah-mount(1)](/docs/buildah-mount.md) | Mount the working container's root filesystem. |
|
| [buildah-mount(1)](/docs/buildah-mount.md) | Mount the working container's root filesystem. |
|
||||||
|
| [buildah-pull(1)](/docs/buildah-pull.md) | Pull an image from the specified location. |
|
||||||
| [buildah-push(1)](/docs/buildah-push.md) | Push an image from local storage to elsewhere. |
|
| [buildah-push(1)](/docs/buildah-push.md) | Push an image from local storage to elsewhere. |
|
||||||
| [buildah-rename(1)](/docs/buildah-rename.md) | Rename a local container. |
|
| [buildah-rename(1)](/docs/buildah-rename.md) | Rename a local container. |
|
||||||
| [buildah-rm(1)](/docs/buildah-rm.md) | Removes one or more working containers. |
|
| [buildah-rm(1)](/docs/buildah-rm.md) | Removes one or more working containers. |
|
||||||
|
1
vendor/github.com/containers/buildah/buildah.go
generated
vendored
1
vendor/github.com/containers/buildah/buildah.go
generated
vendored
@ -224,6 +224,7 @@ func GetBuildInfo(b *Builder) BuilderInfo {
|
|||||||
ContainerID: b.ContainerID,
|
ContainerID: b.ContainerID,
|
||||||
MountPoint: b.MountPoint,
|
MountPoint: b.MountPoint,
|
||||||
ProcessLabel: b.ProcessLabel,
|
ProcessLabel: b.ProcessLabel,
|
||||||
|
MountLabel: b.MountLabel,
|
||||||
ImageAnnotations: b.ImageAnnotations,
|
ImageAnnotations: b.ImageAnnotations,
|
||||||
ImageCreatedBy: b.ImageCreatedBy,
|
ImageCreatedBy: b.ImageCreatedBy,
|
||||||
OCIv1: b.OCIv1,
|
OCIv1: b.OCIv1,
|
||||||
|
2
vendor/github.com/containers/buildah/chroot/run.go
generated
vendored
2
vendor/github.com/containers/buildah/chroot/run.go
generated
vendored
@ -1147,7 +1147,7 @@ func setupChrootBindMounts(spec *specs.Spec, bundlePath string) (undoBinds func(
|
|||||||
}
|
}
|
||||||
if uintptr(fs.Flags)&expectedFlags != expectedFlags {
|
if uintptr(fs.Flags)&expectedFlags != expectedFlags {
|
||||||
if err := unix.Mount(target, target, "bind", requestFlags|unix.MS_REMOUNT, ""); err != nil {
|
if err := unix.Mount(target, target, "bind", requestFlags|unix.MS_REMOUNT, ""); err != nil {
|
||||||
return undoBinds, errors.Wrapf(err, "error remounting %q in mount namespace with expected flags")
|
return undoBinds, errors.Wrapf(err, "error remounting %q in mount namespace with expected flags", target)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
28
vendor/github.com/containers/buildah/common.go
generated
vendored
28
vendor/github.com/containers/buildah/common.go
generated
vendored
@ -2,12 +2,14 @@ package buildah
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"io"
|
"io"
|
||||||
|
"os"
|
||||||
"github.com/sirupsen/logrus"
|
"path/filepath"
|
||||||
|
|
||||||
cp "github.com/containers/image/copy"
|
cp "github.com/containers/image/copy"
|
||||||
"github.com/containers/image/transports"
|
"github.com/containers/image/transports"
|
||||||
"github.com/containers/image/types"
|
"github.com/containers/image/types"
|
||||||
|
"github.com/containers/libpod/pkg/rootless"
|
||||||
|
"github.com/sirupsen/logrus"
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
@ -17,10 +19,20 @@ const (
|
|||||||
DOCKER = "docker"
|
DOCKER = "docker"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// userRegistriesFile is the path to the per user registry configuration file.
|
||||||
|
var userRegistriesFile = filepath.Join(os.Getenv("HOME"), ".config/containers/registries.conf")
|
||||||
|
|
||||||
func getCopyOptions(reportWriter io.Writer, sourceReference types.ImageReference, sourceSystemContext *types.SystemContext, destinationReference types.ImageReference, destinationSystemContext *types.SystemContext, manifestType string) *cp.Options {
|
func getCopyOptions(reportWriter io.Writer, sourceReference types.ImageReference, sourceSystemContext *types.SystemContext, destinationReference types.ImageReference, destinationSystemContext *types.SystemContext, manifestType string) *cp.Options {
|
||||||
sourceCtx := &types.SystemContext{}
|
sourceCtx := &types.SystemContext{}
|
||||||
if sourceSystemContext != nil {
|
if sourceSystemContext != nil {
|
||||||
*sourceCtx = *sourceSystemContext
|
*sourceCtx = *sourceSystemContext
|
||||||
|
} else {
|
||||||
|
if rootless.IsRootless() {
|
||||||
|
if _, err := os.Stat(userRegistriesFile); err == nil {
|
||||||
|
sourceCtx.SystemRegistriesConfPath = userRegistriesFile
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
sourceInsecure, err := isReferenceInsecure(sourceReference, sourceCtx)
|
sourceInsecure, err := isReferenceInsecure(sourceReference, sourceCtx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -33,6 +45,12 @@ func getCopyOptions(reportWriter io.Writer, sourceReference types.ImageReference
|
|||||||
destinationCtx := &types.SystemContext{}
|
destinationCtx := &types.SystemContext{}
|
||||||
if destinationSystemContext != nil {
|
if destinationSystemContext != nil {
|
||||||
*destinationCtx = *destinationSystemContext
|
*destinationCtx = *destinationSystemContext
|
||||||
|
} else {
|
||||||
|
if rootless.IsRootless() {
|
||||||
|
if _, err := os.Stat(userRegistriesFile); err == nil {
|
||||||
|
destinationCtx.SystemRegistriesConfPath = userRegistriesFile
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
destinationInsecure, err := isReferenceInsecure(destinationReference, destinationCtx)
|
destinationInsecure, err := isReferenceInsecure(destinationReference, destinationCtx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -58,5 +76,11 @@ func getSystemContext(defaults *types.SystemContext, signaturePolicyPath string)
|
|||||||
if signaturePolicyPath != "" {
|
if signaturePolicyPath != "" {
|
||||||
sc.SignaturePolicyPath = signaturePolicyPath
|
sc.SignaturePolicyPath = signaturePolicyPath
|
||||||
}
|
}
|
||||||
|
if sc.SystemRegistriesConfPath == "" && rootless.IsRootless() {
|
||||||
|
if _, err := os.Stat(userRegistriesFile); err == nil {
|
||||||
|
sc.SystemRegistriesConfPath = userRegistriesFile
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
return sc
|
return sc
|
||||||
}
|
}
|
||||||
|
3
vendor/github.com/containers/buildah/delete.go
generated
vendored
3
vendor/github.com/containers/buildah/delete.go
generated
vendored
@ -1,7 +1,6 @@
|
|||||||
package buildah
|
package buildah
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/opencontainers/selinux/go-selinux/label"
|
|
||||||
"github.com/pkg/errors"
|
"github.com/pkg/errors"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -14,5 +13,5 @@ func (b *Builder) Delete() error {
|
|||||||
b.MountPoint = ""
|
b.MountPoint = ""
|
||||||
b.Container = ""
|
b.Container = ""
|
||||||
b.ContainerID = ""
|
b.ContainerID = ""
|
||||||
return label.ReleaseLabel(b.ProcessLabel)
|
return nil
|
||||||
}
|
}
|
||||||
|
1
vendor/github.com/containers/buildah/image.go
generated
vendored
1
vendor/github.com/containers/buildah/image.go
generated
vendored
@ -107,7 +107,6 @@ func expectedDockerDiffIDs(image docker.V2Image) int {
|
|||||||
// compression that we'll be applying.
|
// compression that we'll be applying.
|
||||||
func (i *containerImageRef) computeLayerMIMEType(what string) (omediaType, dmediaType string, err error) {
|
func (i *containerImageRef) computeLayerMIMEType(what string) (omediaType, dmediaType string, err error) {
|
||||||
omediaType = v1.MediaTypeImageLayer
|
omediaType = v1.MediaTypeImageLayer
|
||||||
//TODO: Convert to manifest.DockerV2Schema2LayerUncompressedMediaType once available
|
|
||||||
dmediaType = docker.V2S2MediaTypeUncompressedLayer
|
dmediaType = docker.V2S2MediaTypeUncompressedLayer
|
||||||
if i.compression != archive.Uncompressed {
|
if i.compression != archive.Uncompressed {
|
||||||
switch i.compression {
|
switch i.compression {
|
||||||
|
98
vendor/github.com/containers/buildah/imagebuildah/build.go
generated
vendored
98
vendor/github.com/containers/buildah/imagebuildah/build.go
generated
vendored
@ -563,39 +563,39 @@ func NewExecutor(store storage.Store, options BuildOptions) (*Executor, error) {
|
|||||||
registry: options.Registry,
|
registry: options.Registry,
|
||||||
transport: options.Transport,
|
transport: options.Transport,
|
||||||
ignoreUnrecognizedInstructions: options.IgnoreUnrecognizedInstructions,
|
ignoreUnrecognizedInstructions: options.IgnoreUnrecognizedInstructions,
|
||||||
quiet: options.Quiet,
|
quiet: options.Quiet,
|
||||||
runtime: options.Runtime,
|
runtime: options.Runtime,
|
||||||
runtimeArgs: options.RuntimeArgs,
|
runtimeArgs: options.RuntimeArgs,
|
||||||
transientMounts: options.TransientMounts,
|
transientMounts: options.TransientMounts,
|
||||||
compression: options.Compression,
|
compression: options.Compression,
|
||||||
output: options.Output,
|
output: options.Output,
|
||||||
outputFormat: options.OutputFormat,
|
outputFormat: options.OutputFormat,
|
||||||
additionalTags: options.AdditionalTags,
|
additionalTags: options.AdditionalTags,
|
||||||
signaturePolicyPath: options.SignaturePolicyPath,
|
signaturePolicyPath: options.SignaturePolicyPath,
|
||||||
systemContext: options.SystemContext,
|
systemContext: options.SystemContext,
|
||||||
volumeCache: make(map[string]string),
|
volumeCache: make(map[string]string),
|
||||||
volumeCacheInfo: make(map[string]os.FileInfo),
|
volumeCacheInfo: make(map[string]os.FileInfo),
|
||||||
log: options.Log,
|
log: options.Log,
|
||||||
in: options.In,
|
in: options.In,
|
||||||
out: options.Out,
|
out: options.Out,
|
||||||
err: options.Err,
|
err: options.Err,
|
||||||
reportWriter: options.ReportWriter,
|
reportWriter: options.ReportWriter,
|
||||||
isolation: options.Isolation,
|
isolation: options.Isolation,
|
||||||
namespaceOptions: options.NamespaceOptions,
|
namespaceOptions: options.NamespaceOptions,
|
||||||
configureNetwork: options.ConfigureNetwork,
|
configureNetwork: options.ConfigureNetwork,
|
||||||
cniPluginPath: options.CNIPluginPath,
|
cniPluginPath: options.CNIPluginPath,
|
||||||
cniConfigDir: options.CNIConfigDir,
|
cniConfigDir: options.CNIConfigDir,
|
||||||
idmappingOptions: options.IDMappingOptions,
|
idmappingOptions: options.IDMappingOptions,
|
||||||
commonBuildOptions: options.CommonBuildOpts,
|
commonBuildOptions: options.CommonBuildOpts,
|
||||||
defaultMountsFilePath: options.DefaultMountsFilePath,
|
defaultMountsFilePath: options.DefaultMountsFilePath,
|
||||||
iidfile: options.IIDFile,
|
iidfile: options.IIDFile,
|
||||||
squash: options.Squash,
|
squash: options.Squash,
|
||||||
labels: append([]string{}, options.Labels...),
|
labels: append([]string{}, options.Labels...),
|
||||||
annotations: append([]string{}, options.Annotations...),
|
annotations: append([]string{}, options.Annotations...),
|
||||||
layers: options.Layers,
|
layers: options.Layers,
|
||||||
noCache: options.NoCache,
|
noCache: options.NoCache,
|
||||||
removeIntermediateCtrs: options.RemoveIntermediateCtrs,
|
removeIntermediateCtrs: options.RemoveIntermediateCtrs,
|
||||||
forceRmIntermediateCtrs: options.ForceRmIntermediateCtrs,
|
forceRmIntermediateCtrs: options.ForceRmIntermediateCtrs,
|
||||||
}
|
}
|
||||||
if exec.err == nil {
|
if exec.err == nil {
|
||||||
exec.err = os.Stderr
|
exec.err = os.Stderr
|
||||||
@ -764,7 +764,7 @@ func (b *Executor) resolveNameToImageRef() (types.ImageReference, error) {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
candidates, _, err := util.ResolveName(b.output, "", b.systemContext, b.store)
|
candidates, _, err := util.ResolveName(b.output, "", b.systemContext, b.store)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, errors.Wrapf(err, "error parsing target image name %q: %v", b.output)
|
return nil, errors.Wrapf(err, "error parsing target image name %q", b.output)
|
||||||
}
|
}
|
||||||
if len(candidates) == 0 {
|
if len(candidates) == 0 {
|
||||||
return nil, errors.Errorf("error parsing target image name %q", b.output)
|
return nil, errors.Errorf("error parsing target image name %q", b.output)
|
||||||
@ -1044,17 +1044,14 @@ func (b *Executor) copiedFilesMatch(node *parser.Node, historyTime *time.Time) (
|
|||||||
}
|
}
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
// For local files, walk the file tree and check the time stamps.
|
// Walks the file tree for local files and uses chroot to ensure we don't escape out of the allowed path
|
||||||
timeIsGreater := false
|
// when resolving any symlinks.
|
||||||
err := filepath.Walk(item, func(path string, info os.FileInfo, err error) error {
|
// Change the time format to ensure we don't run into a parsing error when converting again from string
|
||||||
if info.ModTime().After(*historyTime) {
|
// to time.Time. It is a known Go issue that the conversions cause errors sometimes, so specifying a particular
|
||||||
timeIsGreater = true
|
// time format here when converting to a string.
|
||||||
return nil
|
timeIsGreater, err := resolveModifiedTime(b.contextDir, item, historyTime.Format(time.RFC3339Nano))
|
||||||
}
|
|
||||||
return nil
|
|
||||||
})
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return false, errors.Wrapf(err, "error walking file tree %q", item)
|
return false, errors.Wrapf(err, "error resolving symlinks and comparing modified times: %q", item)
|
||||||
}
|
}
|
||||||
if timeIsGreater {
|
if timeIsGreater {
|
||||||
return false, nil
|
return false, nil
|
||||||
@ -1289,15 +1286,24 @@ func BuildDockerfiles(ctx context.Context, store storage.Store, options BuildOpt
|
|||||||
} else {
|
} else {
|
||||||
// If the Dockerfile isn't found try prepending the
|
// If the Dockerfile isn't found try prepending the
|
||||||
// context directory to it.
|
// context directory to it.
|
||||||
if _, err := os.Stat(dfile); os.IsNotExist(err) {
|
dinfo, err := os.Stat(dfile)
|
||||||
|
if os.IsNotExist(err) {
|
||||||
dfile = filepath.Join(options.ContextDirectory, dfile)
|
dfile = filepath.Join(options.ContextDirectory, dfile)
|
||||||
}
|
}
|
||||||
|
dinfo, err = os.Stat(dfile)
|
||||||
|
if err != nil {
|
||||||
|
return "", nil, errors.Wrapf(err, "error reading info about %q", dfile)
|
||||||
|
}
|
||||||
|
// If given a directory, add '/Dockerfile' to it.
|
||||||
|
if dinfo.Mode().IsDir() {
|
||||||
|
dfile = filepath.Join(dfile, "Dockerfile")
|
||||||
|
}
|
||||||
logrus.Debugf("reading local Dockerfile %q", dfile)
|
logrus.Debugf("reading local Dockerfile %q", dfile)
|
||||||
contents, err := os.Open(dfile)
|
contents, err := os.Open(dfile)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", nil, errors.Wrapf(err, "error reading %q", dfile)
|
return "", nil, errors.Wrapf(err, "error reading %q", dfile)
|
||||||
}
|
}
|
||||||
dinfo, err := contents.Stat()
|
dinfo, err = contents.Stat()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
contents.Close()
|
contents.Close()
|
||||||
return "", nil, errors.Wrapf(err, "error reading info about %q", dfile)
|
return "", nil, errors.Wrapf(err, "error reading info about %q", dfile)
|
||||||
|
133
vendor/github.com/containers/buildah/imagebuildah/chroot_symlink.go
generated
vendored
133
vendor/github.com/containers/buildah/imagebuildah/chroot_symlink.go
generated
vendored
@ -6,6 +6,7 @@ import (
|
|||||||
"os"
|
"os"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"strings"
|
"strings"
|
||||||
|
"time"
|
||||||
|
|
||||||
"github.com/containers/storage/pkg/reexec"
|
"github.com/containers/storage/pkg/reexec"
|
||||||
"github.com/pkg/errors"
|
"github.com/pkg/errors"
|
||||||
@ -14,13 +15,18 @@ import (
|
|||||||
|
|
||||||
const (
|
const (
|
||||||
symlinkChrootedCommand = "chrootsymlinks-resolve"
|
symlinkChrootedCommand = "chrootsymlinks-resolve"
|
||||||
|
symlinkModifiedTime = "modtimesymlinks-resolve"
|
||||||
maxSymlinksResolved = 40
|
maxSymlinksResolved = 40
|
||||||
)
|
)
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
reexec.Register(symlinkChrootedCommand, resolveChrootedSymlinks)
|
reexec.Register(symlinkChrootedCommand, resolveChrootedSymlinks)
|
||||||
|
reexec.Register(symlinkModifiedTime, resolveSymlinkTimeModified)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// main() for grandparent subprocess. Its main job is to shuttle stdio back
|
||||||
|
// and forth, managing a pseudo-terminal if we want one, for our child, the
|
||||||
|
// parent subprocess.
|
||||||
func resolveChrootedSymlinks() {
|
func resolveChrootedSymlinks() {
|
||||||
status := 0
|
status := 0
|
||||||
flag.Parse()
|
flag.Parse()
|
||||||
@ -39,7 +45,7 @@ func resolveChrootedSymlinks() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Our second parameter is the path name to evaluate for symbolic links
|
// Our second parameter is the path name to evaluate for symbolic links
|
||||||
symLink, err := getSymbolicLink(flag.Arg(0), flag.Arg(1))
|
symLink, err := getSymbolicLink(flag.Arg(1))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Fprintf(os.Stderr, "error getting symbolic links: %v\n", err)
|
fmt.Fprintf(os.Stderr, "error getting symbolic links: %v\n", err)
|
||||||
os.Exit(1)
|
os.Exit(1)
|
||||||
@ -51,7 +57,8 @@ func resolveChrootedSymlinks() {
|
|||||||
os.Exit(status)
|
os.Exit(status)
|
||||||
}
|
}
|
||||||
|
|
||||||
// ResolveSymlink resolves any symlink in filename in the context of rootdir.
|
// ResolveSymLink (in the grandparent process) resolves any symlink in filename
|
||||||
|
// in the context of rootdir.
|
||||||
func ResolveSymLink(rootdir, filename string) (string, error) {
|
func ResolveSymLink(rootdir, filename string) (string, error) {
|
||||||
// The child process expects a chroot and one path that
|
// The child process expects a chroot and one path that
|
||||||
// will be consulted relative to the chroot directory and evaluated
|
// will be consulted relative to the chroot directory and evaluated
|
||||||
@ -62,32 +69,121 @@ func ResolveSymLink(rootdir, filename string) (string, error) {
|
|||||||
return "", errors.Wrapf(err, string(output))
|
return "", errors.Wrapf(err, string(output))
|
||||||
}
|
}
|
||||||
|
|
||||||
// Hand back the resolved symlink, will be "" if a symlink is not found
|
// Hand back the resolved symlink, will be filename if a symlink is not found
|
||||||
return string(output), nil
|
return string(output), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// main() for grandparent subprocess. Its main job is to shuttle stdio back
|
||||||
|
// and forth, managing a pseudo-terminal if we want one, for our child, the
|
||||||
|
// parent subprocess.
|
||||||
|
func resolveSymlinkTimeModified() {
|
||||||
|
status := 0
|
||||||
|
flag.Parse()
|
||||||
|
if len(flag.Args()) < 1 {
|
||||||
|
os.Exit(1)
|
||||||
|
}
|
||||||
|
// Our first parameter is the directory to chroot into.
|
||||||
|
if err := unix.Chdir(flag.Arg(0)); err != nil {
|
||||||
|
fmt.Fprintf(os.Stderr, "chdir(): %v\n", err)
|
||||||
|
os.Exit(1)
|
||||||
|
}
|
||||||
|
if err := unix.Chroot(flag.Arg(0)); err != nil {
|
||||||
|
fmt.Fprintf(os.Stderr, "chroot(): %v\n", err)
|
||||||
|
os.Exit(1)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Our second parameter is the path name to evaluate for symbolic links.
|
||||||
|
// Our third parameter is the time the cached intermediate image was created.
|
||||||
|
// We check whether the modified time of the filepath we provide is after the time the cached image was created.
|
||||||
|
timeIsGreater, err := modTimeIsGreater(flag.Arg(0), flag.Arg(1), flag.Arg(2))
|
||||||
|
if err != nil {
|
||||||
|
fmt.Fprintf(os.Stderr, "error checking if modified time of resolved symbolic link is greater: %v\n", err)
|
||||||
|
os.Exit(1)
|
||||||
|
}
|
||||||
|
if _, err := os.Stdout.WriteString(fmt.Sprintf("%v", timeIsGreater)); err != nil {
|
||||||
|
fmt.Fprintf(os.Stderr, "error writing string to stdout: %v\n", err)
|
||||||
|
os.Exit(1)
|
||||||
|
}
|
||||||
|
os.Exit(status)
|
||||||
|
}
|
||||||
|
|
||||||
|
// resolveModifiedTime (in the grandparent process) checks filename for any symlinks,
|
||||||
|
// resolves it and compares the modified time of the file with historyTime, which is
|
||||||
|
// the creation time of the cached image. It returns true if filename was modified after
|
||||||
|
// historyTime, otherwise returns false.
|
||||||
|
func resolveModifiedTime(rootdir, filename, historyTime string) (bool, error) {
|
||||||
|
// The child process expects a chroot and one path that
|
||||||
|
// will be consulted relative to the chroot directory and evaluated
|
||||||
|
// for any symbolic links present.
|
||||||
|
cmd := reexec.Command(symlinkModifiedTime, rootdir, filename, historyTime)
|
||||||
|
output, err := cmd.CombinedOutput()
|
||||||
|
if err != nil {
|
||||||
|
return false, errors.Wrapf(err, string(output))
|
||||||
|
}
|
||||||
|
// Hand back true/false depending on in the file was modified after the caches image was created.
|
||||||
|
return string(output) == "true", nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// modTimeIsGreater goes through the files added/copied in using the Dockerfile and
|
||||||
|
// checks the time stamp (follows symlinks) with the time stamp of when the cached
|
||||||
|
// image was created. IT compares the two and returns true if the file was modified
|
||||||
|
// after the cached image was created, otherwise it returns false.
|
||||||
|
func modTimeIsGreater(rootdir, path string, historyTime string) (bool, error) {
|
||||||
|
var timeIsGreater bool
|
||||||
|
|
||||||
|
// Convert historyTime from string to time.Time for comparison
|
||||||
|
histTime, err := time.Parse(time.RFC3339Nano, historyTime)
|
||||||
|
if err != nil {
|
||||||
|
return false, errors.Wrapf(err, "error converting string to time.Time %q", historyTime)
|
||||||
|
}
|
||||||
|
// Walk the file tree and check the time stamps.
|
||||||
|
// Since we are chroot in rootdir, only want the path of the actual filename, i.e path - rootdir.
|
||||||
|
// +1 to account for the extra "/" (e.g rootdir=/home/user/mydir, path=/home/user/mydir/myfile.json)
|
||||||
|
err = filepath.Walk(path[len(rootdir)+1:], func(path string, info os.FileInfo, err error) error {
|
||||||
|
modTime := info.ModTime()
|
||||||
|
if info.Mode()&os.ModeSymlink == os.ModeSymlink {
|
||||||
|
// Evaluate any symlink that occurs to get updated modified information
|
||||||
|
resolvedPath, err := filepath.EvalSymlinks(path)
|
||||||
|
if err != nil {
|
||||||
|
return errors.Wrapf(err, "error evaluating symlink %q", path)
|
||||||
|
}
|
||||||
|
fileInfo, err := os.Stat(resolvedPath)
|
||||||
|
if err != nil {
|
||||||
|
return errors.Wrapf(err, "error getting file info %q", resolvedPath)
|
||||||
|
}
|
||||||
|
modTime = fileInfo.ModTime()
|
||||||
|
}
|
||||||
|
if modTime.After(histTime) {
|
||||||
|
timeIsGreater = true
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
return false, errors.Wrapf(err, "error walking file tree %q", path)
|
||||||
|
}
|
||||||
|
return timeIsGreater, err
|
||||||
|
}
|
||||||
|
|
||||||
// getSymbolic link goes through each part of the path and continues resolving symlinks as they appear.
|
// getSymbolic link goes through each part of the path and continues resolving symlinks as they appear.
|
||||||
// Returns what the whole target path for what "path" resolves to.
|
// Returns what the whole target path for what "path" resolves to.
|
||||||
func getSymbolicLink(rootdir, path string) (string, error) {
|
func getSymbolicLink(path string) (string, error) {
|
||||||
var (
|
var (
|
||||||
symPath string
|
symPath string
|
||||||
symLinksResolved int
|
symLinksResolved int
|
||||||
)
|
)
|
||||||
|
// Splitting path as we need to resolve each part of the path at a time
|
||||||
// Splitting path as we need to resolve each parth of the path at a time
|
|
||||||
splitPath := strings.Split(path, "/")
|
splitPath := strings.Split(path, "/")
|
||||||
if splitPath[0] == "" {
|
if splitPath[0] == "" {
|
||||||
splitPath = splitPath[1:]
|
splitPath = splitPath[1:]
|
||||||
symPath = "/"
|
symPath = "/"
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, p := range splitPath {
|
for _, p := range splitPath {
|
||||||
// If we have resolved 40 symlinks, that means something is terribly wrong
|
// If we have resolved 40 symlinks, that means something is terribly wrong
|
||||||
// will return an error and exit
|
// will return an error and exit
|
||||||
if symLinksResolved >= maxSymlinksResolved {
|
if symLinksResolved >= maxSymlinksResolved {
|
||||||
return "", errors.Errorf("have resolved %q symlinks, something is terribly wrong!", maxSymlinksResolved)
|
return "", errors.Errorf("have resolved %q symlinks, something is terribly wrong!", maxSymlinksResolved)
|
||||||
}
|
}
|
||||||
|
|
||||||
symPath = filepath.Join(symPath, p)
|
symPath = filepath.Join(symPath, p)
|
||||||
isSymlink, resolvedPath, err := hasSymlink(symPath)
|
isSymlink, resolvedPath, err := hasSymlink(symPath)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -119,16 +215,21 @@ func getSymbolicLink(rootdir, path string) (string, error) {
|
|||||||
// otherwise it returns false and path
|
// otherwise it returns false and path
|
||||||
func hasSymlink(path string) (bool, string, error) {
|
func hasSymlink(path string) (bool, string, error) {
|
||||||
info, err := os.Lstat(path)
|
info, err := os.Lstat(path)
|
||||||
if os.IsNotExist(err) {
|
if err != nil {
|
||||||
if err = os.MkdirAll(path, 0755); err != nil {
|
if os.IsNotExist(err) {
|
||||||
return false, "", errors.Wrapf(err, "error ensuring volume path %q exists", path)
|
if err = os.MkdirAll(path, 0755); err != nil {
|
||||||
}
|
return false, "", errors.Wrapf(err, "error ensuring volume path %q exists", path)
|
||||||
info, err = os.Lstat(path)
|
}
|
||||||
if err != nil {
|
info, err = os.Lstat(path)
|
||||||
return false, "", errors.Wrapf(err, "error running lstat on %q", path)
|
if err != nil {
|
||||||
|
return false, "", errors.Wrapf(err, "error running lstat on %q", path)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return false, path, errors.Wrapf(err, "error get stat of path %q", path)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Return false and path as path is not a symlink
|
|
||||||
|
// Return false and path as path if not a symlink
|
||||||
if info.Mode()&os.ModeSymlink != os.ModeSymlink {
|
if info.Mode()&os.ModeSymlink != os.ModeSymlink {
|
||||||
return false, path, nil
|
return false, path, nil
|
||||||
}
|
}
|
||||||
|
83
vendor/github.com/containers/buildah/new.go
generated
vendored
83
vendor/github.com/containers/buildah/new.go
generated
vendored
@ -3,6 +3,7 @@ package buildah
|
|||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"math/rand"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/containers/buildah/util"
|
"github.com/containers/buildah/util"
|
||||||
@ -12,7 +13,6 @@ import (
|
|||||||
"github.com/containers/image/transports/alltransports"
|
"github.com/containers/image/transports/alltransports"
|
||||||
"github.com/containers/image/types"
|
"github.com/containers/image/types"
|
||||||
"github.com/containers/storage"
|
"github.com/containers/storage"
|
||||||
"github.com/opencontainers/selinux/go-selinux/label"
|
|
||||||
"github.com/openshift/imagebuilder"
|
"github.com/openshift/imagebuilder"
|
||||||
"github.com/pkg/errors"
|
"github.com/pkg/errors"
|
||||||
"github.com/sirupsen/logrus"
|
"github.com/sirupsen/logrus"
|
||||||
@ -23,11 +23,6 @@ const (
|
|||||||
// as "no image".
|
// as "no image".
|
||||||
BaseImageFakeName = imagebuilder.NoBaseImageSpecifier
|
BaseImageFakeName = imagebuilder.NoBaseImageSpecifier
|
||||||
|
|
||||||
// DefaultTransport is a prefix that we apply to an image name if we
|
|
||||||
// can't find one in the local Store, in order to generate a source
|
|
||||||
// reference for the image that we can then copy to the local Store.
|
|
||||||
DefaultTransport = "docker://"
|
|
||||||
|
|
||||||
// minimumTruncatedIDLength is the minimum length of an identifier that
|
// minimumTruncatedIDLength is the minimum length of an identifier that
|
||||||
// we'll accept as possibly being a truncated image ID.
|
// we'll accept as possibly being a truncated image ID.
|
||||||
minimumTruncatedIDLength = 3
|
minimumTruncatedIDLength = 3
|
||||||
@ -150,7 +145,7 @@ func resolveImage(ctx context.Context, systemContext *types.SystemContext, store
|
|||||||
}
|
}
|
||||||
logrus.Debugf("error parsing image name %q as given, trying with transport %q: %v", image, options.Transport, err)
|
logrus.Debugf("error parsing image name %q as given, trying with transport %q: %v", image, options.Transport, err)
|
||||||
transport := options.Transport
|
transport := options.Transport
|
||||||
if transport != DefaultTransport {
|
if transport != util.DefaultTransport {
|
||||||
transport = transport + ":"
|
transport = transport + ":"
|
||||||
}
|
}
|
||||||
srcRef2, err := alltransports.ParseImageName(transport + image)
|
srcRef2, err := alltransports.ParseImageName(transport + image)
|
||||||
@ -232,6 +227,27 @@ func resolveImage(ctx context.Context, systemContext *types.SystemContext, store
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func containerNameExist(name string, containers []storage.Container) bool {
|
||||||
|
for _, container := range containers {
|
||||||
|
for _, cname := range container.Names {
|
||||||
|
if cname == name {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
func findUnusedContainer(name string, containers []storage.Container) string {
|
||||||
|
suffix := 1
|
||||||
|
tmpName := name
|
||||||
|
for containerNameExist(tmpName, containers) {
|
||||||
|
tmpName = fmt.Sprintf("%s-%d", name, suffix)
|
||||||
|
suffix++
|
||||||
|
}
|
||||||
|
return tmpName
|
||||||
|
}
|
||||||
|
|
||||||
func newBuilder(ctx context.Context, store storage.Store, options BuilderOptions) (*Builder, error) {
|
func newBuilder(ctx context.Context, store storage.Store, options BuilderOptions) (*Builder, error) {
|
||||||
var ref types.ImageReference
|
var ref types.ImageReference
|
||||||
var img *storage.Image
|
var img *storage.Image
|
||||||
@ -241,7 +257,7 @@ func newBuilder(ctx context.Context, store storage.Store, options BuilderOptions
|
|||||||
options.FromImage = ""
|
options.FromImage = ""
|
||||||
}
|
}
|
||||||
if options.Transport == "" {
|
if options.Transport == "" {
|
||||||
options.Transport = DefaultTransport
|
options.Transport = util.DefaultTransport
|
||||||
}
|
}
|
||||||
|
|
||||||
systemContext := getSystemContext(options.SystemContext, options.SignaturePolicyPath)
|
systemContext := getSystemContext(options.SystemContext, options.SignaturePolicyPath)
|
||||||
@ -277,23 +293,33 @@ func newBuilder(ctx context.Context, store storage.Store, options BuilderOptions
|
|||||||
name = imageNamePrefix(image) + "-" + name
|
name = imageNamePrefix(image) + "-" + name
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
var container *storage.Container
|
||||||
coptions := storage.ContainerOptions{}
|
tmpName := name
|
||||||
coptions.IDMappingOptions = newContainerIDMappingOptions(options.IDMappingOptions)
|
if options.Container == "" {
|
||||||
|
containers, err := store.Containers()
|
||||||
container, err := store.CreateContainer("", []string{name}, imageID, "", "", &coptions)
|
if err != nil {
|
||||||
suffix := 1
|
return nil, errors.Wrapf(err, "unable to check for container names")
|
||||||
for err != nil && errors.Cause(err) == storage.ErrDuplicateName && options.Container == "" {
|
|
||||||
suffix++
|
|
||||||
tmpName := fmt.Sprintf("%s-%d", name, suffix)
|
|
||||||
if container, err = store.CreateContainer("", []string{tmpName}, imageID, "", "", &coptions); err == nil {
|
|
||||||
name = tmpName
|
|
||||||
}
|
}
|
||||||
}
|
tmpName = findUnusedContainer(tmpName, containers)
|
||||||
if err != nil {
|
|
||||||
return nil, errors.Wrapf(err, "error creating container")
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
conflict := 100
|
||||||
|
for true {
|
||||||
|
coptions := storage.ContainerOptions{
|
||||||
|
LabelOpts: options.CommonBuildOpts.LabelOpts,
|
||||||
|
IDMappingOptions: newContainerIDMappingOptions(options.IDMappingOptions),
|
||||||
|
}
|
||||||
|
container, err = store.CreateContainer("", []string{tmpName}, imageID, "", "", &coptions)
|
||||||
|
if err == nil {
|
||||||
|
name = tmpName
|
||||||
|
break
|
||||||
|
}
|
||||||
|
if errors.Cause(err) != storage.ErrDuplicateName || options.Container != "" {
|
||||||
|
return nil, errors.Wrapf(err, "error creating container")
|
||||||
|
}
|
||||||
|
tmpName = fmt.Sprintf("%s-%d", name, rand.Int()%conflict)
|
||||||
|
conflict = conflict * 10
|
||||||
|
}
|
||||||
defer func() {
|
defer func() {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if err2 := store.DeleteContainer(container.ID); err2 != nil {
|
if err2 := store.DeleteContainer(container.ID); err2 != nil {
|
||||||
@ -302,13 +328,6 @@ func newBuilder(ctx context.Context, store storage.Store, options BuilderOptions
|
|||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
|
|
||||||
if err = ReserveSELinuxLabels(store, container.ID); err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
processLabel, mountLabel, err := label.InitLabels(options.CommonBuildOpts.LabelOpts)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
uidmap, gidmap := convertStorageIDMaps(container.UIDMap, container.GIDMap)
|
uidmap, gidmap := convertStorageIDMaps(container.UIDMap, container.GIDMap)
|
||||||
|
|
||||||
defaultNamespaceOptions, err := DefaultNamespaceOptions()
|
defaultNamespaceOptions, err := DefaultNamespaceOptions()
|
||||||
@ -328,8 +347,8 @@ func newBuilder(ctx context.Context, store storage.Store, options BuilderOptions
|
|||||||
ContainerID: container.ID,
|
ContainerID: container.ID,
|
||||||
ImageAnnotations: map[string]string{},
|
ImageAnnotations: map[string]string{},
|
||||||
ImageCreatedBy: "",
|
ImageCreatedBy: "",
|
||||||
ProcessLabel: processLabel,
|
ProcessLabel: container.ProcessLabel(),
|
||||||
MountLabel: mountLabel,
|
MountLabel: container.MountLabel(),
|
||||||
DefaultMountsFilePath: options.DefaultMountsFilePath,
|
DefaultMountsFilePath: options.DefaultMountsFilePath,
|
||||||
Isolation: options.Isolation,
|
Isolation: options.Isolation,
|
||||||
NamespaceOptions: namespaceOptions,
|
NamespaceOptions: namespaceOptions,
|
||||||
@ -351,7 +370,7 @@ func newBuilder(ctx context.Context, store storage.Store, options BuilderOptions
|
|||||||
}
|
}
|
||||||
|
|
||||||
if options.Mount {
|
if options.Mount {
|
||||||
_, err = builder.Mount(mountLabel)
|
_, err = builder.Mount(container.MountLabel())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, errors.Wrapf(err, "error mounting build container %q", builder.ContainerID)
|
return nil, errors.Wrapf(err, "error mounting build container %q", builder.ContainerID)
|
||||||
}
|
}
|
||||||
|
8
vendor/github.com/containers/buildah/pkg/cli/common.go
generated
vendored
8
vendor/github.com/containers/buildah/pkg/cli/common.go
generated
vendored
@ -70,6 +70,10 @@ var (
|
|||||||
}
|
}
|
||||||
|
|
||||||
LayerFlags = []cli.Flag{
|
LayerFlags = []cli.Flag{
|
||||||
|
cli.BoolFlag{
|
||||||
|
Name: "force-rm",
|
||||||
|
Usage: "Always remove intermediate containers after a build, even if the build is unsuccessful.",
|
||||||
|
},
|
||||||
cli.BoolFlag{
|
cli.BoolFlag{
|
||||||
Name: "layers",
|
Name: "layers",
|
||||||
Usage: fmt.Sprintf("cache intermediate layers during build. Use BUILDAH_LAYERS environment variable to override. (default %t)", UseLayers()),
|
Usage: fmt.Sprintf("cache intermediate layers during build. Use BUILDAH_LAYERS environment variable to override. (default %t)", UseLayers()),
|
||||||
@ -115,10 +119,6 @@ var (
|
|||||||
Name: "file, f",
|
Name: "file, f",
|
||||||
Usage: "`pathname or URL` of a Dockerfile",
|
Usage: "`pathname or URL` of a Dockerfile",
|
||||||
},
|
},
|
||||||
cli.BoolFlag{
|
|
||||||
Name: "force-rm",
|
|
||||||
Usage: "Always remove intermediate containers after a build, even if the build is unsuccessful.",
|
|
||||||
},
|
|
||||||
cli.StringFlag{
|
cli.StringFlag{
|
||||||
Name: "format",
|
Name: "format",
|
||||||
Usage: "`format` of the built image's manifest and metadata. Use BUILDAH_FORMAT environment variable to override.",
|
Usage: "`format` of the built image's manifest and metadata. Use BUILDAH_FORMAT environment variable to override.",
|
||||||
|
5
vendor/github.com/containers/buildah/pull.go
generated
vendored
5
vendor/github.com/containers/buildah/pull.go
generated
vendored
@ -146,11 +146,11 @@ func pullImage(ctx context.Context, store storage.Store, imageName string, optio
|
|||||||
srcRef, err := alltransports.ParseImageName(spec)
|
srcRef, err := alltransports.ParseImageName(spec)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if options.Transport == "" {
|
if options.Transport == "" {
|
||||||
options.Transport = DefaultTransport
|
options.Transport = util.DefaultTransport
|
||||||
}
|
}
|
||||||
logrus.Debugf("error parsing image name %q, trying with transport %q: %v", spec, options.Transport, err)
|
logrus.Debugf("error parsing image name %q, trying with transport %q: %v", spec, options.Transport, err)
|
||||||
transport := options.Transport
|
transport := options.Transport
|
||||||
if transport != DefaultTransport {
|
if transport != util.DefaultTransport {
|
||||||
transport = transport + ":"
|
transport = transport + ":"
|
||||||
}
|
}
|
||||||
spec = transport + spec
|
spec = transport + spec
|
||||||
@ -201,6 +201,7 @@ func pullImage(ctx context.Context, store storage.Store, imageName string, optio
|
|||||||
|
|
||||||
logrus.Debugf("copying %q to %q", spec, destName)
|
logrus.Debugf("copying %q to %q", spec, destName)
|
||||||
if _, err := cp.Image(ctx, policyContext, destRef, srcRef, getCopyOptions(options.ReportWriter, srcRef, sc, destRef, nil, "")); err != nil {
|
if _, err := cp.Image(ctx, policyContext, destRef, srcRef, getCopyOptions(options.ReportWriter, srcRef, sc, destRef, nil, "")); err != nil {
|
||||||
|
logrus.Debugf("error copying src image [%q] to dest image [%q] err: %v", spec, destName, err)
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
return destRef, nil
|
return destRef, nil
|
||||||
|
180
vendor/github.com/containers/buildah/run.go
generated
vendored
180
vendor/github.com/containers/buildah/run.go
generated
vendored
@ -451,7 +451,7 @@ func (b *Builder) setupMounts(mountPoint string, spec *specs.Spec, bundlePath st
|
|||||||
// Add temporary copies of the contents of volume locations at the
|
// Add temporary copies of the contents of volume locations at the
|
||||||
// volume locations, unless we already have something there.
|
// volume locations, unless we already have something there.
|
||||||
copyWithTar := b.copyWithTar(nil, nil)
|
copyWithTar := b.copyWithTar(nil, nil)
|
||||||
builtins, err := runSetupBuiltinVolumes(b.MountLabel, mountPoint, cdir, copyWithTar, builtinVolumes)
|
builtins, err := runSetupBuiltinVolumes(b.MountLabel, mountPoint, cdir, copyWithTar, builtinVolumes, int(rootUID), int(rootGID))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@ -493,15 +493,21 @@ func runSetupBoundFiles(bundlePath string, bindFiles map[string]string) (mounts
|
|||||||
return mounts, nil
|
return mounts, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func runSetupBuiltinVolumes(mountLabel, mountPoint, containerDir string, copyWithTar func(srcPath, dstPath string) error, builtinVolumes []string) ([]specs.Mount, error) {
|
func runSetupBuiltinVolumes(mountLabel, mountPoint, containerDir string, copyWithTar func(srcPath, dstPath string) error, builtinVolumes []string, rootUID, rootGID int) ([]specs.Mount, error) {
|
||||||
var mounts []specs.Mount
|
var mounts []specs.Mount
|
||||||
|
hostOwner := idtools.IDPair{UID: rootUID, GID: rootGID}
|
||||||
// Add temporary copies of the contents of volume locations at the
|
// Add temporary copies of the contents of volume locations at the
|
||||||
// volume locations, unless we already have something there.
|
// volume locations, unless we already have something there.
|
||||||
for _, volume := range builtinVolumes {
|
for _, volume := range builtinVolumes {
|
||||||
subdir := digest.Canonical.FromString(volume).Hex()
|
subdir := digest.Canonical.FromString(volume).Hex()
|
||||||
volumePath := filepath.Join(containerDir, "buildah-volumes", subdir)
|
volumePath := filepath.Join(containerDir, "buildah-volumes", subdir)
|
||||||
|
srcPath := filepath.Join(mountPoint, volume)
|
||||||
|
initializeVolume := false
|
||||||
// If we need to, initialize the volume path's initial contents.
|
// If we need to, initialize the volume path's initial contents.
|
||||||
if _, err := os.Stat(volumePath); err != nil && os.IsNotExist(err) {
|
if _, err := os.Stat(volumePath); err != nil {
|
||||||
|
if !os.IsNotExist(err) {
|
||||||
|
return nil, errors.Wrapf(err, "failed to stat %q for volume %q", volumePath, volume)
|
||||||
|
}
|
||||||
logrus.Debugf("setting up built-in volume at %q", volumePath)
|
logrus.Debugf("setting up built-in volume at %q", volumePath)
|
||||||
if err = os.MkdirAll(volumePath, 0755); err != nil {
|
if err = os.MkdirAll(volumePath, 0755); err != nil {
|
||||||
return nil, errors.Wrapf(err, "error creating directory %q for volume %q", volumePath, volume)
|
return nil, errors.Wrapf(err, "error creating directory %q for volume %q", volumePath, volume)
|
||||||
@ -509,11 +515,21 @@ func runSetupBuiltinVolumes(mountLabel, mountPoint, containerDir string, copyWit
|
|||||||
if err = label.Relabel(volumePath, mountLabel, false); err != nil {
|
if err = label.Relabel(volumePath, mountLabel, false); err != nil {
|
||||||
return nil, errors.Wrapf(err, "error relabeling directory %q for volume %q", volumePath, volume)
|
return nil, errors.Wrapf(err, "error relabeling directory %q for volume %q", volumePath, volume)
|
||||||
}
|
}
|
||||||
srcPath := filepath.Join(mountPoint, volume)
|
initializeVolume = true
|
||||||
stat, err := os.Stat(srcPath)
|
}
|
||||||
if err != nil {
|
stat, err := os.Stat(srcPath)
|
||||||
|
if err != nil {
|
||||||
|
if !os.IsNotExist(err) {
|
||||||
return nil, errors.Wrapf(err, "failed to stat %q for volume %q", srcPath, volume)
|
return nil, errors.Wrapf(err, "failed to stat %q for volume %q", srcPath, volume)
|
||||||
}
|
}
|
||||||
|
if err = idtools.MkdirAllAndChownNew(srcPath, 0755, hostOwner); err != nil {
|
||||||
|
return nil, errors.Wrapf(err, "error creating directory %q for volume %q", srcPath, volume)
|
||||||
|
}
|
||||||
|
if stat, err = os.Stat(srcPath); err != nil {
|
||||||
|
return nil, errors.Wrapf(err, "failed to stat %q for volume %q", srcPath, volume)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if initializeVolume {
|
||||||
if err = os.Chmod(volumePath, stat.Mode().Perm()); err != nil {
|
if err = os.Chmod(volumePath, stat.Mode().Perm()); err != nil {
|
||||||
return nil, errors.Wrapf(err, "failed to chmod %q for volume %q", volumePath, volume)
|
return nil, errors.Wrapf(err, "failed to chmod %q for volume %q", volumePath, volume)
|
||||||
}
|
}
|
||||||
@ -1044,24 +1060,31 @@ func (b *Builder) Run(command []string, options RunOptions) error {
|
|||||||
}
|
}
|
||||||
rootIDPair := &idtools.IDPair{UID: int(rootUID), GID: int(rootGID)}
|
rootIDPair := &idtools.IDPair{UID: int(rootUID), GID: int(rootGID)}
|
||||||
|
|
||||||
hostFile, err := b.addNetworkConfig(path, "/etc/hosts", rootIDPair)
|
bindFiles := make(map[string]string)
|
||||||
if err != nil {
|
namespaceOptions := append(b.NamespaceOptions, options.NamespaceOptions...)
|
||||||
return err
|
volumes := b.Volumes()
|
||||||
}
|
|
||||||
resolvFile, err := b.addNetworkConfig(path, "/etc/resolv.conf", rootIDPair)
|
if !contains(volumes, "/etc/hosts") {
|
||||||
if err != nil {
|
hostFile, err := b.addNetworkConfig(path, "/etc/hosts", rootIDPair)
|
||||||
return err
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
bindFiles["/etc/hosts"] = hostFile
|
||||||
|
|
||||||
|
if err := addHostsToFile(b.CommonBuildOpts.AddHost, hostFile); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := addHostsToFile(b.CommonBuildOpts.AddHost, hostFile); err != nil {
|
if !contains(volumes, "/etc/resolv.conf") {
|
||||||
return err
|
resolvFile, err := b.addNetworkConfig(path, "/etc/resolv.conf", rootIDPair)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
bindFiles["/etc/resolv.conf"] = resolvFile
|
||||||
}
|
}
|
||||||
|
|
||||||
bindFiles := map[string]string{
|
err = b.setupMounts(mountPoint, spec, path, options.Mounts, bindFiles, volumes, b.CommonBuildOpts.Volumes, b.CommonBuildOpts.ShmSize, namespaceOptions)
|
||||||
"/etc/hosts": hostFile,
|
|
||||||
"/etc/resolv.conf": resolvFile,
|
|
||||||
}
|
|
||||||
err = b.setupMounts(mountPoint, spec, path, options.Mounts, bindFiles, b.Volumes(), b.CommonBuildOpts.Volumes, b.CommonBuildOpts.ShmSize, append(b.NamespaceOptions, options.NamespaceOptions...))
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return errors.Wrapf(err, "error resolving mountpoints for container %q", b.ContainerID)
|
return errors.Wrapf(err, "error resolving mountpoints for container %q", b.ContainerID)
|
||||||
}
|
}
|
||||||
@ -1095,7 +1118,7 @@ func (b *Builder) Run(command []string, options RunOptions) error {
|
|||||||
} else {
|
} else {
|
||||||
moreCreateArgs = nil
|
moreCreateArgs = nil
|
||||||
}
|
}
|
||||||
err = b.runUsingRuntimeSubproc(options, configureNetwork, configureNetworks, moreCreateArgs, spec, mountPoint, path, Package+"-"+filepath.Base(path))
|
err = b.runUsingRuntimeSubproc(isolation, options, configureNetwork, configureNetworks, moreCreateArgs, spec, mountPoint, path, Package+"-"+filepath.Base(path))
|
||||||
case IsolationChroot:
|
case IsolationChroot:
|
||||||
err = chroot.RunUsingChroot(spec, path, options.Stdin, options.Stdout, options.Stderr)
|
err = chroot.RunUsingChroot(spec, path, options.Stdin, options.Stdout, options.Stderr)
|
||||||
case IsolationOCIRootless:
|
case IsolationOCIRootless:
|
||||||
@ -1109,13 +1132,22 @@ func (b *Builder) Run(command []string, options RunOptions) error {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
options.Args = append(options.Args, rootlessFlag...)
|
options.Args = append(options.Args, rootlessFlag...)
|
||||||
err = b.runUsingRuntimeSubproc(options, configureNetwork, configureNetworks, []string{"--no-new-keyring"}, spec, mountPoint, path, Package+"-"+filepath.Base(path))
|
err = b.runUsingRuntimeSubproc(isolation, options, configureNetwork, configureNetworks, []string{"--no-new-keyring"}, spec, mountPoint, path, Package+"-"+filepath.Base(path))
|
||||||
default:
|
default:
|
||||||
err = errors.Errorf("don't know how to run this command")
|
err = errors.Errorf("don't know how to run this command")
|
||||||
}
|
}
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func contains(volumes []string, v string) bool {
|
||||||
|
for _, i := range volumes {
|
||||||
|
if i == v {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
func checkAndOverrideIsolationOptions(isolation Isolation, options *RunOptions) error {
|
func checkAndOverrideIsolationOptions(isolation Isolation, options *RunOptions) error {
|
||||||
switch isolation {
|
switch isolation {
|
||||||
case IsolationOCIRootless:
|
case IsolationOCIRootless:
|
||||||
@ -1123,10 +1155,22 @@ func checkAndOverrideIsolationOptions(isolation Isolation, options *RunOptions)
|
|||||||
logrus.Debugf("Forcing use of an IPC namespace.")
|
logrus.Debugf("Forcing use of an IPC namespace.")
|
||||||
}
|
}
|
||||||
options.NamespaceOptions.AddOrReplace(NamespaceOption{Name: string(specs.IPCNamespace)})
|
options.NamespaceOptions.AddOrReplace(NamespaceOption{Name: string(specs.IPCNamespace)})
|
||||||
if ns := options.NamespaceOptions.Find(string(specs.NetworkNamespace)); ns != nil && !ns.Host {
|
_, err := exec.LookPath("slirp4netns")
|
||||||
logrus.Debugf("Disabling network namespace.")
|
hostNetworking := err != nil
|
||||||
|
networkNamespacePath := ""
|
||||||
|
if ns := options.NamespaceOptions.Find(string(specs.NetworkNamespace)); ns != nil {
|
||||||
|
hostNetworking = ns.Host
|
||||||
|
networkNamespacePath = ns.Path
|
||||||
|
if !hostNetworking && networkNamespacePath != "" && !filepath.IsAbs(networkNamespacePath) {
|
||||||
|
logrus.Debugf("Disabling network namespace configuration.")
|
||||||
|
networkNamespacePath = ""
|
||||||
|
}
|
||||||
}
|
}
|
||||||
options.NamespaceOptions.AddOrReplace(NamespaceOption{Name: string(specs.NetworkNamespace), Host: true})
|
options.NamespaceOptions.AddOrReplace(NamespaceOption{
|
||||||
|
Name: string(specs.NetworkNamespace),
|
||||||
|
Host: hostNetworking,
|
||||||
|
Path: networkNamespacePath,
|
||||||
|
})
|
||||||
if ns := options.NamespaceOptions.Find(string(specs.PIDNamespace)); ns == nil || ns.Host {
|
if ns := options.NamespaceOptions.Find(string(specs.PIDNamespace)); ns == nil || ns.Host {
|
||||||
logrus.Debugf("Forcing use of a PID namespace.")
|
logrus.Debugf("Forcing use of a PID namespace.")
|
||||||
}
|
}
|
||||||
@ -1227,9 +1271,10 @@ type runUsingRuntimeSubprocOptions struct {
|
|||||||
ConfigureNetworks []string
|
ConfigureNetworks []string
|
||||||
MoreCreateArgs []string
|
MoreCreateArgs []string
|
||||||
ContainerName string
|
ContainerName string
|
||||||
|
Isolation Isolation
|
||||||
}
|
}
|
||||||
|
|
||||||
func (b *Builder) runUsingRuntimeSubproc(options RunOptions, configureNetwork bool, configureNetworks, moreCreateArgs []string, spec *specs.Spec, rootPath, bundlePath, containerName string) (err error) {
|
func (b *Builder) runUsingRuntimeSubproc(isolation Isolation, options RunOptions, configureNetwork bool, configureNetworks, moreCreateArgs []string, spec *specs.Spec, rootPath, bundlePath, containerName string) (err error) {
|
||||||
var confwg sync.WaitGroup
|
var confwg sync.WaitGroup
|
||||||
config, conferr := json.Marshal(runUsingRuntimeSubprocOptions{
|
config, conferr := json.Marshal(runUsingRuntimeSubprocOptions{
|
||||||
Options: options,
|
Options: options,
|
||||||
@ -1240,6 +1285,7 @@ func (b *Builder) runUsingRuntimeSubproc(options RunOptions, configureNetwork bo
|
|||||||
ConfigureNetworks: configureNetworks,
|
ConfigureNetworks: configureNetworks,
|
||||||
MoreCreateArgs: moreCreateArgs,
|
MoreCreateArgs: moreCreateArgs,
|
||||||
ContainerName: containerName,
|
ContainerName: containerName,
|
||||||
|
Isolation: isolation,
|
||||||
})
|
})
|
||||||
if conferr != nil {
|
if conferr != nil {
|
||||||
return errors.Wrapf(conferr, "error encoding configuration for %q", runUsingRuntimeCommand)
|
return errors.Wrapf(conferr, "error encoding configuration for %q", runUsingRuntimeCommand)
|
||||||
@ -1318,7 +1364,7 @@ func runUsingRuntimeMain() {
|
|||||||
os.Exit(1)
|
os.Exit(1)
|
||||||
}
|
}
|
||||||
// Run the container, start to finish.
|
// Run the container, start to finish.
|
||||||
status, err := runUsingRuntime(options.Options, options.ConfigureNetwork, options.ConfigureNetworks, options.MoreCreateArgs, options.Spec, options.RootPath, options.BundlePath, options.ContainerName)
|
status, err := runUsingRuntime(options.Isolation, options.Options, options.ConfigureNetwork, options.ConfigureNetworks, options.MoreCreateArgs, options.Spec, options.RootPath, options.BundlePath, options.ContainerName)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Fprintf(os.Stderr, "error running container: %v\n", err)
|
fmt.Fprintf(os.Stderr, "error running container: %v\n", err)
|
||||||
os.Exit(1)
|
os.Exit(1)
|
||||||
@ -1333,7 +1379,7 @@ func runUsingRuntimeMain() {
|
|||||||
os.Exit(1)
|
os.Exit(1)
|
||||||
}
|
}
|
||||||
|
|
||||||
func runUsingRuntime(options RunOptions, configureNetwork bool, configureNetworks, moreCreateArgs []string, spec *specs.Spec, rootPath, bundlePath, containerName string) (wstatus unix.WaitStatus, err error) {
|
func runUsingRuntime(isolation Isolation, options RunOptions, configureNetwork bool, configureNetworks, moreCreateArgs []string, spec *specs.Spec, rootPath, bundlePath, containerName string) (wstatus unix.WaitStatus, err error) {
|
||||||
// Lock the caller to a single OS-level thread.
|
// Lock the caller to a single OS-level thread.
|
||||||
runtime.LockOSThread()
|
runtime.LockOSThread()
|
||||||
|
|
||||||
@ -1490,7 +1536,7 @@ func runUsingRuntime(options RunOptions, configureNetwork bool, configureNetwork
|
|||||||
}()
|
}()
|
||||||
|
|
||||||
if configureNetwork {
|
if configureNetwork {
|
||||||
teardown, err := runConfigureNetwork(options, configureNetworks, pid, containerName, spec.Process.Args)
|
teardown, err := runConfigureNetwork(isolation, options, configureNetworks, pid, containerName, spec.Process.Args)
|
||||||
if teardown != nil {
|
if teardown != nil {
|
||||||
defer teardown()
|
defer teardown()
|
||||||
}
|
}
|
||||||
@ -1623,9 +1669,81 @@ func runCollectOutput(fds, closeBeforeReadingFds []int) string {
|
|||||||
}
|
}
|
||||||
return b.String()
|
return b.String()
|
||||||
}
|
}
|
||||||
|
func setupRootlessNetwork(pid int) (teardown func(), err error) {
|
||||||
|
slirp4netns, err := exec.LookPath("slirp4netns")
|
||||||
|
if err != nil {
|
||||||
|
return nil, errors.Wrapf(err, "cannot find slirp4netns")
|
||||||
|
}
|
||||||
|
|
||||||
func runConfigureNetwork(options RunOptions, configureNetworks []string, pid int, containerName string, command []string) (teardown func(), err error) {
|
rootlessSlirpSyncR, rootlessSlirpSyncW, err := os.Pipe()
|
||||||
|
if err != nil {
|
||||||
|
return nil, errors.Wrapf(err, "cannot create slirp4netns sync pipe")
|
||||||
|
}
|
||||||
|
defer rootlessSlirpSyncR.Close()
|
||||||
|
|
||||||
|
// Be sure there are no fds inherited to slirp4netns except the sync pipe
|
||||||
|
files, err := ioutil.ReadDir("/proc/self/fd")
|
||||||
|
if err != nil {
|
||||||
|
return nil, errors.Wrapf(err, "cannot list open fds")
|
||||||
|
}
|
||||||
|
for _, f := range files {
|
||||||
|
fd, err := strconv.Atoi(f.Name())
|
||||||
|
if err != nil {
|
||||||
|
return nil, errors.Wrapf(err, "cannot parse fd")
|
||||||
|
}
|
||||||
|
if fd == int(rootlessSlirpSyncW.Fd()) {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
unix.CloseOnExec(fd)
|
||||||
|
}
|
||||||
|
|
||||||
|
cmd := exec.Command(slirp4netns, "-r", "3", "-c", fmt.Sprintf("%d", pid), "tap0")
|
||||||
|
cmd.Stdin, cmd.Stdout, cmd.Stderr = nil, nil, nil
|
||||||
|
cmd.ExtraFiles = []*os.File{rootlessSlirpSyncW}
|
||||||
|
|
||||||
|
err = cmd.Start()
|
||||||
|
rootlessSlirpSyncW.Close()
|
||||||
|
if err != nil {
|
||||||
|
return nil, errors.Wrapf(err, "cannot start slirp4netns")
|
||||||
|
}
|
||||||
|
|
||||||
|
b := make([]byte, 1)
|
||||||
|
for {
|
||||||
|
if err := rootlessSlirpSyncR.SetDeadline(time.Now().Add(1 * time.Second)); err != nil {
|
||||||
|
return nil, errors.Wrapf(err, "error setting slirp4netns pipe timeout")
|
||||||
|
}
|
||||||
|
if _, err := rootlessSlirpSyncR.Read(b); err == nil {
|
||||||
|
break
|
||||||
|
} else {
|
||||||
|
if os.IsTimeout(err) {
|
||||||
|
// Check if the process is still running.
|
||||||
|
var status syscall.WaitStatus
|
||||||
|
_, err := syscall.Wait4(cmd.Process.Pid, &status, syscall.WNOHANG, nil)
|
||||||
|
if err != nil {
|
||||||
|
return nil, errors.Wrapf(err, "failed to read slirp4netns process status")
|
||||||
|
}
|
||||||
|
if status.Exited() || status.Signaled() {
|
||||||
|
return nil, errors.New("slirp4netns failed")
|
||||||
|
}
|
||||||
|
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
return nil, errors.Wrapf(err, "failed to read from slirp4netns sync pipe")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return func() {
|
||||||
|
cmd.Process.Kill()
|
||||||
|
cmd.Wait()
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func runConfigureNetwork(isolation Isolation, options RunOptions, configureNetworks []string, pid int, containerName string, command []string) (teardown func(), err error) {
|
||||||
var netconf, undo []*libcni.NetworkConfigList
|
var netconf, undo []*libcni.NetworkConfigList
|
||||||
|
|
||||||
|
if isolation == IsolationOCIRootless {
|
||||||
|
return setupRootlessNetwork(pid)
|
||||||
|
}
|
||||||
// Scan for CNI configuration files.
|
// Scan for CNI configuration files.
|
||||||
confdir := options.CNIConfigDir
|
confdir := options.CNIConfigDir
|
||||||
files, err := libcni.ConfFiles(confdir, []string{".conf"})
|
files, err := libcni.ConfFiles(confdir, []string{".conf"})
|
||||||
@ -1956,7 +2074,7 @@ func runAcceptTerminal(consoleListener *net.UnixListener, terminalSize *specs.Bo
|
|||||||
for i := range scm {
|
for i := range scm {
|
||||||
fds, err := unix.ParseUnixRights(&scm[i])
|
fds, err := unix.ParseUnixRights(&scm[i])
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return -1, errors.Wrapf(err, "error parsing unix rights control message: %v")
|
return -1, errors.Wrapf(err, "error parsing unix rights control message: %v", &scm[i])
|
||||||
}
|
}
|
||||||
logrus.Debugf("fds: %v", fds)
|
logrus.Debugf("fds: %v", fds)
|
||||||
if len(fds) == 0 {
|
if len(fds) == 0 {
|
||||||
|
4
vendor/github.com/containers/buildah/unshare/unshare.go
generated
vendored
4
vendor/github.com/containers/buildah/unshare/unshare.go
generated
vendored
@ -55,6 +55,10 @@ func (c *Cmd) Start() error {
|
|||||||
}
|
}
|
||||||
c.Env = append(c.Env, fmt.Sprintf("_Buildah-unshare=%d", c.UnshareFlags))
|
c.Env = append(c.Env, fmt.Sprintf("_Buildah-unshare=%d", c.UnshareFlags))
|
||||||
|
|
||||||
|
// Please the libpod "rootless" package to find the expected env variables.
|
||||||
|
c.Env = append(c.Env, "_LIBPOD_USERNS_CONFIGURED=done")
|
||||||
|
c.Env = append(c.Env, fmt.Sprintf("_LIBPOD_ROOTLESS_UID=%d", os.Geteuid()))
|
||||||
|
|
||||||
// Create the pipe for reading the child's PID.
|
// Create the pipe for reading the child's PID.
|
||||||
pidRead, pidWrite, err := os.Pipe()
|
pidRead, pidWrite, err := os.Pipe()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
61
vendor/github.com/containers/buildah/util/util.go
generated
vendored
61
vendor/github.com/containers/buildah/util/util.go
generated
vendored
@ -7,10 +7,8 @@ import (
|
|||||||
"net/url"
|
"net/url"
|
||||||
"os"
|
"os"
|
||||||
"path"
|
"path"
|
||||||
"path/filepath"
|
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
"syscall"
|
|
||||||
|
|
||||||
"github.com/containers/image/directory"
|
"github.com/containers/image/directory"
|
||||||
dockerarchive "github.com/containers/image/docker/archive"
|
dockerarchive "github.com/containers/image/docker/archive"
|
||||||
@ -31,6 +29,10 @@ import (
|
|||||||
|
|
||||||
const (
|
const (
|
||||||
minimumTruncatedIDLength = 3
|
minimumTruncatedIDLength = 3
|
||||||
|
// DefaultTransport is a prefix that we apply to an image name if we
|
||||||
|
// can't find one in the local Store, in order to generate a source
|
||||||
|
// reference for the image that we can then copy to the local Store.
|
||||||
|
DefaultTransport = "docker://"
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
@ -89,6 +91,7 @@ func ResolveName(name string, firstRegistry string, sc *types.SystemContext, sto
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
name = strings.TrimPrefix(name, DefaultTransport)
|
||||||
// If the image name already included a domain component, we're done.
|
// If the image name already included a domain component, we're done.
|
||||||
named, err := reference.ParseNormalizedNamed(name)
|
named, err := reference.ParseNormalizedNamed(name)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -450,60 +453,6 @@ func ParseIDMappings(uidmap, gidmap []string) ([]idtools.IDMap, []idtools.IDMap,
|
|||||||
return uid, gid, nil
|
return uid, gid, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// UnsharedRootPath returns a location under ($XDG_DATA_HOME/containers/storage,
|
|
||||||
// or $HOME/.local/share/containers/storage, or
|
|
||||||
// (the user's home directory)/.local/share/containers/storage, or an error.
|
|
||||||
func UnsharedRootPath(homedir string) (string, error) {
|
|
||||||
// If $XDG_DATA_HOME is defined...
|
|
||||||
if envDataHome, haveDataHome := os.LookupEnv("XDG_DATA_HOME"); haveDataHome {
|
|
||||||
return filepath.Join(envDataHome, "containers", "storage"), nil
|
|
||||||
}
|
|
||||||
// If $XDG_DATA_HOME is not defined, but $HOME is defined...
|
|
||||||
if envHomedir, haveHomedir := os.LookupEnv("HOME"); haveHomedir {
|
|
||||||
// Default to the user's $HOME/.local/share/containers/storage subdirectory.
|
|
||||||
return filepath.Join(envHomedir, ".local", "share", "containers", "storage"), nil
|
|
||||||
}
|
|
||||||
// If we know where our home directory is...
|
|
||||||
if homedir != "" {
|
|
||||||
// Default to the user's homedir/.local/share/containers/storage subdirectory.
|
|
||||||
return filepath.Join(homedir, ".local", "share", "containers", "storage"), nil
|
|
||||||
}
|
|
||||||
return "", errors.New("unable to determine a --root location: neither $XDG_DATA_HOME nor $HOME is set")
|
|
||||||
}
|
|
||||||
|
|
||||||
// UnsharedRunrootPath returns $XDG_RUNTIME_DIR/run, /var/run/user/(the user's UID)/run, or an error.
|
|
||||||
func UnsharedRunrootPath(uid string) (string, error) {
|
|
||||||
// If $XDG_RUNTIME_DIR is defined...
|
|
||||||
if envRuntimeDir, haveRuntimeDir := os.LookupEnv("XDG_RUNTIME_DIR"); haveRuntimeDir {
|
|
||||||
return filepath.Join(envRuntimeDir, "run"), nil
|
|
||||||
}
|
|
||||||
var runtimeDir string
|
|
||||||
// If $XDG_RUNTIME_DIR is not defined, but we know our UID...
|
|
||||||
if uid != "" {
|
|
||||||
tmpDir := filepath.Join("/var/run/user", uid)
|
|
||||||
os.MkdirAll(tmpDir, 0700)
|
|
||||||
st, err := os.Stat(tmpDir)
|
|
||||||
if err == nil && int(st.Sys().(*syscall.Stat_t).Uid) == os.Getuid() && st.Mode().Perm() == 0700 {
|
|
||||||
runtimeDir = tmpDir
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if runtimeDir == "" {
|
|
||||||
home := os.Getenv("HOME")
|
|
||||||
if home == "" {
|
|
||||||
return "", errors.New("neither XDG_RUNTIME_DIR nor HOME was set non-empty")
|
|
||||||
}
|
|
||||||
resolvedHome, err := filepath.EvalSymlinks(home)
|
|
||||||
if err != nil {
|
|
||||||
return "", errors.Wrapf(err, "cannot resolve %s", home)
|
|
||||||
}
|
|
||||||
runtimeDir = filepath.Join(resolvedHome, "rundir")
|
|
||||||
}
|
|
||||||
if err := os.Setenv("XDG_RUNTIME_DIR", runtimeDir); err != nil {
|
|
||||||
return "", errors.New("could not set XDG_RUNTIME_DIR")
|
|
||||||
}
|
|
||||||
return runtimeDir, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// GetPolicyContext sets up, initializes and returns a new context for the specified policy
|
// GetPolicyContext sets up, initializes and returns a new context for the specified policy
|
||||||
func GetPolicyContext(ctx *types.SystemContext) (*signature.PolicyContext, error) {
|
func GetPolicyContext(ctx *types.SystemContext) (*signature.PolicyContext, error) {
|
||||||
policy, err := signature.DefaultPolicy(ctx)
|
policy, err := signature.DefaultPolicy(ctx)
|
||||||
|
6
vendor/github.com/containers/buildah/vendor.conf
generated
vendored
6
vendor/github.com/containers/buildah/vendor.conf
generated
vendored
@ -4,8 +4,8 @@ github.com/BurntSushi/toml master
|
|||||||
github.com/containerd/continuity master
|
github.com/containerd/continuity master
|
||||||
github.com/containernetworking/cni v0.7.0-alpha1
|
github.com/containernetworking/cni v0.7.0-alpha1
|
||||||
github.com/containers/image 5e5b67d6b1cf43cc349128ec3ed7d5283a6cc0d1
|
github.com/containers/image 5e5b67d6b1cf43cc349128ec3ed7d5283a6cc0d1
|
||||||
github.com/containers/libpod 2afadeec6696fefac468a49c8ba24b0bc275aa75
|
github.com/containers/libpod e75469ab99c48e9fbe2b36ade229d384bdea9144
|
||||||
github.com/containers/storage 41294c85d97bef688e18f710402895dbecde3308
|
github.com/containers/storage 09abf3a26b8a3aa69e29fd7faeb260b98d675759
|
||||||
github.com/docker/distribution 5f6282db7d65e6d72ad7c2cc66310724a57be716
|
github.com/docker/distribution 5f6282db7d65e6d72ad7c2cc66310724a57be716
|
||||||
github.com/docker/docker 86f080cff0914e9694068ed78d503701667c4c00
|
github.com/docker/docker 86f080cff0914e9694068ed78d503701667c4c00
|
||||||
github.com/docker/docker-credential-helpers d68f9aeca33f5fd3f08eeae5e9d175edf4e731d1
|
github.com/docker/docker-credential-helpers d68f9aeca33f5fd3f08eeae5e9d175edf4e731d1
|
||||||
@ -36,7 +36,7 @@ github.com/opencontainers/image-spec v1.0.0
|
|||||||
github.com/opencontainers/runc master
|
github.com/opencontainers/runc master
|
||||||
github.com/opencontainers/runtime-spec v1.0.0
|
github.com/opencontainers/runtime-spec v1.0.0
|
||||||
github.com/opencontainers/runtime-tools master
|
github.com/opencontainers/runtime-tools master
|
||||||
github.com/opencontainers/selinux b6fa367ed7f534f9ba25391cc2d467085dbb445a
|
github.com/opencontainers/selinux master
|
||||||
github.com/openshift/imagebuilder master
|
github.com/openshift/imagebuilder master
|
||||||
github.com/ostreedev/ostree-go aeb02c6b6aa2889db3ef62f7855650755befd460
|
github.com/ostreedev/ostree-go aeb02c6b6aa2889db3ef62f7855650755befd460
|
||||||
github.com/pborman/uuid master
|
github.com/pborman/uuid master
|
||||||
|
Reference in New Issue
Block a user