summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.cirrus.yml18
-rw-r--r--Dockerfile2
-rw-r--r--cmd/podman/attach.go2
-rw-r--r--cmd/podman/build.go2
-rw-r--r--cmd/podman/checkpoint.go2
-rw-r--r--cmd/podman/cleanup.go2
-rw-r--r--cmd/podman/cliconfig/config.go4
-rw-r--r--cmd/podman/commands.go2
-rw-r--r--cmd/podman/commit.go2
-rw-r--r--cmd/podman/common.go4
-rw-r--r--cmd/podman/container.go1
-rw-r--r--cmd/podman/containers_prune.go2
-rw-r--r--cmd/podman/cp.go2
-rw-r--r--cmd/podman/create.go2
-rw-r--r--cmd/podman/diff.go2
-rw-r--r--cmd/podman/events.go2
-rw-r--r--cmd/podman/exec.go2
-rw-r--r--cmd/podman/exists.go6
-rw-r--r--cmd/podman/export.go2
-rw-r--r--cmd/podman/generate_kube.go2
-rw-r--r--cmd/podman/healthcheck_run.go2
-rw-r--r--cmd/podman/history.go2
-rw-r--r--cmd/podman/images.go2
-rw-r--r--cmd/podman/images_prune.go2
-rw-r--r--cmd/podman/import.go2
-rw-r--r--cmd/podman/info.go2
-rw-r--r--cmd/podman/inspect.go2
-rw-r--r--cmd/podman/kill.go2
-rw-r--r--cmd/podman/libpodruntime/runtime.go22
-rw-r--r--cmd/podman/load.go2
-rw-r--r--cmd/podman/login.go4
-rw-r--r--cmd/podman/logs.go2
-rw-r--r--cmd/podman/main_local.go4
-rw-r--r--cmd/podman/mount.go2
-rw-r--r--cmd/podman/pause.go2
-rw-r--r--cmd/podman/play_kube.go2
-rw-r--r--cmd/podman/pod_create.go2
-rw-r--r--cmd/podman/pod_inspect.go2
-rw-r--r--cmd/podman/pod_kill.go2
-rw-r--r--cmd/podman/pod_pause.go2
-rw-r--r--cmd/podman/pod_ps.go2
-rw-r--r--cmd/podman/pod_restart.go2
-rw-r--r--cmd/podman/pod_rm.go2
-rw-r--r--cmd/podman/pod_start.go2
-rw-r--r--cmd/podman/pod_stats.go2
-rw-r--r--cmd/podman/pod_stop.go2
-rw-r--r--cmd/podman/pod_top.go2
-rw-r--r--cmd/podman/pod_unpause.go2
-rw-r--r--cmd/podman/pods_prune.go2
-rw-r--r--cmd/podman/port.go2
-rw-r--r--cmd/podman/ps.go2
-rw-r--r--cmd/podman/pull.go2
-rw-r--r--cmd/podman/push.go2
-rw-r--r--cmd/podman/refresh.go2
-rw-r--r--cmd/podman/restart.go2
-rw-r--r--cmd/podman/restore.go2
-rw-r--r--cmd/podman/rm.go2
-rw-r--r--cmd/podman/rmi.go2
-rw-r--r--cmd/podman/run.go2
-rw-r--r--cmd/podman/runlabel.go2
-rw-r--r--cmd/podman/save.go2
-rw-r--r--cmd/podman/shared/container.go3
-rw-r--r--cmd/podman/shared/create.go1
-rw-r--r--cmd/podman/shared/intermediate.go1
-rw-r--r--cmd/podman/shared/intermediate_varlink.go2
-rw-r--r--cmd/podman/sign.go2
-rw-r--r--cmd/podman/start.go2
-rw-r--r--cmd/podman/stats.go2
-rw-r--r--cmd/podman/stop.go2
-rw-r--r--cmd/podman/system_df.go2
-rw-r--r--cmd/podman/system_migrate.go50
-rw-r--r--cmd/podman/system_prune.go2
-rw-r--r--cmd/podman/system_renumber.go2
-rw-r--r--cmd/podman/tag.go2
-rw-r--r--cmd/podman/top.go2
-rw-r--r--cmd/podman/tree.go2
-rw-r--r--cmd/podman/trust_set_show.go4
-rw-r--r--cmd/podman/umount.go2
-rw-r--r--cmd/podman/unpause.go2
-rw-r--r--cmd/podman/varlink.go2
-rw-r--r--cmd/podman/varlink/io.podman.varlink1
-rw-r--r--cmd/podman/volume_create.go2
-rw-r--r--cmd/podman/volume_inspect.go2
-rw-r--r--cmd/podman/volume_ls.go2
-rw-r--r--cmd/podman/volume_prune.go2
-rw-r--r--cmd/podman/volume_rm.go2
-rw-r--r--cmd/podman/wait.go2
-rw-r--r--completions/bash/podman1
-rw-r--r--contrib/cirrus/packer/ubuntu_setup.sh3
-rwxr-xr-xcontrib/cirrus/setup_environment.sh1
-rw-r--r--docs/podman-create.1.md3
-rw-r--r--docs/podman-run.1.md9
-rw-r--r--docs/podman-system-migrate.1.md21
-rw-r--r--docs/podman-system.1.md1
-rw-r--r--libpod/container_internal_linux.go2
-rw-r--r--libpod/events.go10
-rw-r--r--libpod/events/config.go9
-rw-r--r--libpod/events/events.go15
-rw-r--r--libpod/events/events_linux.go5
-rw-r--r--libpod/events/journal_linux.go7
-rw-r--r--libpod/events/logfile.go8
-rw-r--r--libpod/options.go30
-rw-r--r--libpod/runtime.go49
-rw-r--r--libpod/runtime_migrate.go47
-rw-r--r--libpod/runtime_renumber.go3
-rw-r--r--pkg/adapter/runtime.go4
-rw-r--r--pkg/adapter/runtime_remote.go2
-rw-r--r--pkg/inspect/inspect.go3
-rw-r--r--pkg/spec/createconfig.go1
-rw-r--r--pkg/spec/spec.go25
-rw-r--r--vendor.conf4
-rw-r--r--vendor/github.com/containers/buildah/add.go2
-rw-r--r--vendor/github.com/containers/buildah/buildah.go4
-rw-r--r--vendor/github.com/containers/buildah/chroot/run.go2
-rw-r--r--vendor/github.com/containers/buildah/chroot/selinux.go2
-rw-r--r--vendor/github.com/containers/buildah/commit.go11
-rw-r--r--vendor/github.com/containers/buildah/image.go38
-rw-r--r--vendor/github.com/containers/buildah/imagebuildah/build.go266
-rw-r--r--vendor/github.com/containers/buildah/imagebuildah/chroot_symlink.go24
-rw-r--r--vendor/github.com/containers/buildah/imagebuildah/errors.go7
-rw-r--r--vendor/github.com/containers/buildah/pkg/cli/common.go2
-rw-r--r--vendor/github.com/containers/buildah/pkg/parse/parse.go2
-rw-r--r--vendor/github.com/containers/buildah/pkg/unshare/unshare.go105
-rw-r--r--vendor/github.com/containers/buildah/pkg/unshare/unshare_unsupported.go14
-rw-r--r--vendor/github.com/containers/buildah/run.go20
-rw-r--r--vendor/github.com/containers/buildah/selinux.go7
-rw-r--r--vendor/github.com/containers/buildah/util/util.go89
-rw-r--r--vendor/github.com/containers/buildah/vendor.conf2
-rw-r--r--vendor/github.com/containers/psgo/go.mod11
-rw-r--r--vendor/github.com/containers/storage/drivers/overlay/overlay.go55
-rw-r--r--vendor/github.com/fsouza/go-dockerclient/go.mod42
-rw-r--r--vendor/github.com/hashicorp/errwrap/go.mod1
-rw-r--r--vendor/github.com/hashicorp/go-multierror/go.mod3
-rw-r--r--vendor/github.com/stretchr/testify/go.mod7
-rw-r--r--vendor/golang.org/x/text/go.mod3
-rw-r--r--vendor/gopkg.in/yaml.v2/go.mod5
136 files changed, 920 insertions, 336 deletions
diff --git a/.cirrus.yml b/.cirrus.yml
index 325176179..0102dcb1a 100644
--- a/.cirrus.yml
+++ b/.cirrus.yml
@@ -28,15 +28,15 @@ env:
#### Cache-image names to test with
###
ACTIVE_CACHE_IMAGE_NAMES: >-
- fedora-28-libpod-6318419153518592
- fedora-29-libpod-6318419153518592
- ubuntu-18-libpod-6318419153518592
- rhel-7-libpod-6318419153518592
+ fedora-29-libpod-548c1c05
+ fedora-28-libpod-548c1c05
+ ubuntu-18-libpod-548c1c05
+ rhel-7-libpod-548c1c05
image-builder-image-1541772081
- FEDORA_CACHE_IMAGE_NAME: "fedora-29-libpod-6318419153518592"
- PRIOR_FEDORA_CACHE_IMAGE_NAME: "fedora-28-libpod-6318419153518592"
- UBUNTU_CACHE_IMAGE_NAME: "ubuntu-18-libpod-6318419153518592"
- PRIOR_RHEL_CACHE_IMAGE_NAME: "rhel-7-libpod-6318419153518592"
+ FEDORA_CACHE_IMAGE_NAME: "fedora-29-libpod-548c1c05"
+ PRIOR_FEDORA_CACHE_IMAGE_NAME: "fedora-28-libpod-548c1c05"
+ UBUNTU_CACHE_IMAGE_NAME: "ubuntu-18-libpod-548c1c05"
+ PRIOR_RHEL_CACHE_IMAGE_NAME: "rhel-7-libpod-548c1c05"
# RHEL_CACHE_IMAGE_NAME: "rhel-8-notready"
# CENTOS_CACHE_IMAGE_NAME: "centos-7-notready"
@@ -49,7 +49,7 @@ env:
CNI_COMMIT: "7480240de9749f9a0a5c8614b17f1f03e0c06ab9"
CRIO_COMMIT: "7a283c391abb7bd25086a8ff91dbb36ebdd24466"
CRIU_COMMIT: "c74b83cd49c00589c0c0468ba5fe685b67fdbd0a"
- RUNC_COMMIT: "25f3f893c86d07426df93b7aa172f33fdf093fbd"
+ RUNC_COMMIT: "029124da7af7360afa781a0234d1b083550f797c"
# CSV of cache-image names to build (see $PACKER_BASE/libpod_images.json)
PACKER_BUILDS: "ubuntu-18,fedora-29,fedora-28,rhel-7" # TODO: rhel-8,centos-7
# Version of packer to use
diff --git a/Dockerfile b/Dockerfile
index 83cd3fccd..767e64570 100644
--- a/Dockerfile
+++ b/Dockerfile
@@ -44,7 +44,7 @@ RUN apt-get update && apt-get install -y \
&& apt-get clean
# Install runc
-ENV RUNC_COMMIT 96ec2177ae841256168fcf76954f7177af9446eb
+ENV RUNC_COMMIT 029124da7af7360afa781a0234d1b083550f797c
RUN set -x \
&& export GOPATH="$(mktemp -d)" \
&& git clone https://github.com/opencontainers/runc.git "$GOPATH/src/github.com/opencontainers/runc" \
diff --git a/cmd/podman/attach.go b/cmd/podman/attach.go
index c07c0f1cf..37f8afbad 100644
--- a/cmd/podman/attach.go
+++ b/cmd/podman/attach.go
@@ -47,7 +47,7 @@ func attachCmd(c *cliconfig.AttachValues) error {
if remoteclient && len(c.InputArgs) != 1 {
return errors.Errorf("attach requires the name or id of one running container")
}
- runtime, err := adapter.GetRuntime(&c.PodmanCommand)
+ runtime, err := adapter.GetRuntime(getContext(), &c.PodmanCommand)
if err != nil {
return errors.Wrapf(err, "error creating runtime")
}
diff --git a/cmd/podman/build.go b/cmd/podman/build.go
index b69ac6e84..647ff1e86 100644
--- a/cmd/podman/build.go
+++ b/cmd/podman/build.go
@@ -206,7 +206,7 @@ func buildCmd(c *cliconfig.BuildValues) error {
dockerfiles = append(dockerfiles, filepath.Join(contextDir, "Dockerfile"))
}
- runtime, err := adapter.GetRuntime(&c.PodmanCommand)
+ runtime, err := adapter.GetRuntime(getContext(), &c.PodmanCommand)
if err != nil {
return errors.Wrapf(err, "could not get runtime")
}
diff --git a/cmd/podman/checkpoint.go b/cmd/podman/checkpoint.go
index f2f5d37da..234d683bb 100644
--- a/cmd/podman/checkpoint.go
+++ b/cmd/podman/checkpoint.go
@@ -54,7 +54,7 @@ func checkpointCmd(c *cliconfig.CheckpointValues) error {
return errors.New("checkpointing a container requires root")
}
- runtime, err := adapter.GetRuntime(&c.PodmanCommand)
+ runtime, err := adapter.GetRuntime(getContext(), &c.PodmanCommand)
if err != nil {
return errors.Wrapf(err, "could not get runtime")
}
diff --git a/cmd/podman/cleanup.go b/cmd/podman/cleanup.go
index f5b3cf55b..9434c68ba 100644
--- a/cmd/podman/cleanup.go
+++ b/cmd/podman/cleanup.go
@@ -49,7 +49,7 @@ func init() {
}
func cleanupCmd(c *cliconfig.CleanupValues) error {
- runtime, err := libpodruntime.GetRuntime(&c.PodmanCommand)
+ runtime, err := libpodruntime.GetRuntime(getContext(), &c.PodmanCommand)
if err != nil {
return errors.Wrapf(err, "could not get runtime")
}
diff --git a/cmd/podman/cliconfig/config.go b/cmd/podman/cliconfig/config.go
index 640a4bff4..77156f47a 100644
--- a/cmd/podman/cliconfig/config.go
+++ b/cmd/podman/cliconfig/config.go
@@ -581,6 +581,10 @@ type SystemRenumberValues struct {
PodmanCommand
}
+type SystemMigrateValues struct {
+ PodmanCommand
+}
+
type SystemDfValues struct {
PodmanCommand
Verbose bool
diff --git a/cmd/podman/commands.go b/cmd/podman/commands.go
index ef8debe42..4b0641d82 100644
--- a/cmd/podman/commands.go
+++ b/cmd/podman/commands.go
@@ -50,7 +50,6 @@ func getContainerSubCommands() []*cobra.Command {
_restoreCommand,
_runlabelCommand,
_statsCommand,
- _stopCommand,
_umountCommand,
}
}
@@ -75,6 +74,7 @@ func getSystemSubCommands() []*cobra.Command {
return []*cobra.Command{
_renumberCommand,
_dfSystemCommand,
+ _migrateCommand,
}
}
diff --git a/cmd/podman/commit.go b/cmd/podman/commit.go
index 8d79c1e28..2b38bab35 100644
--- a/cmd/podman/commit.go
+++ b/cmd/podman/commit.go
@@ -52,7 +52,7 @@ func init() {
}
func commitCmd(c *cliconfig.CommitValues) error {
- runtime, err := libpodruntime.GetRuntime(&c.PodmanCommand)
+ runtime, err := libpodruntime.GetRuntime(getContext(), &c.PodmanCommand)
if err != nil {
return errors.Wrapf(err, "could not get runtime")
}
diff --git a/cmd/podman/common.go b/cmd/podman/common.go
index ba4a3f519..eac96d3ba 100644
--- a/cmd/podman/common.go
+++ b/cmd/podman/common.go
@@ -434,6 +434,10 @@ func getCreateFlags(c *cliconfig.PodmanCommand) {
"read-only", false,
"Make containers root filesystem read-only",
)
+ createFlags.Bool(
+ "read-only-tmpfs", true,
+ "When running containers in read-only mode mount a read-write tmpfs on /run, /tmp and /var/tmp",
+ )
createFlags.String(
"restart", "",
"Restart is not supported. Please use a systemd unit file for restart",
diff --git a/cmd/podman/container.go b/cmd/podman/container.go
index 9cd8229f9..b3058bf12 100644
--- a/cmd/podman/container.go
+++ b/cmd/podman/container.go
@@ -65,6 +65,7 @@ var (
_runCommand,
_rmCommand,
_startCommand,
+ _stopCommand,
_topCommand,
_unpauseCommand,
_waitCommand,
diff --git a/cmd/podman/containers_prune.go b/cmd/podman/containers_prune.go
index 340c47e8d..b052bda36 100644
--- a/cmd/podman/containers_prune.go
+++ b/cmd/podman/containers_prune.go
@@ -39,7 +39,7 @@ func init() {
}
func pruneContainersCmd(c *cliconfig.PruneContainersValues) error {
- runtime, err := adapter.GetRuntime(&c.PodmanCommand)
+ runtime, err := adapter.GetRuntime(getContext(), &c.PodmanCommand)
if err != nil {
return errors.Wrapf(err, "could not get runtime")
}
diff --git a/cmd/podman/cp.go b/cmd/podman/cp.go
index 6e48b9f3b..82f2d3f20 100644
--- a/cmd/podman/cp.go
+++ b/cmd/podman/cp.go
@@ -58,7 +58,7 @@ func cpCmd(c *cliconfig.CpValues) error {
return errors.Errorf("you must provide a source path and a destination path")
}
- runtime, err := libpodruntime.GetRuntime(&c.PodmanCommand)
+ runtime, err := libpodruntime.GetRuntime(getContext(), &c.PodmanCommand)
if err != nil {
return errors.Wrapf(err, "could not get runtime")
}
diff --git a/cmd/podman/create.go b/cmd/podman/create.go
index cfc0fa0c3..cb3ba14c5 100644
--- a/cmd/podman/create.go
+++ b/cmd/podman/create.go
@@ -52,7 +52,7 @@ func createCmd(c *cliconfig.CreateValues) error {
return err
}
- runtime, err := adapter.GetRuntime(&c.PodmanCommand)
+ runtime, err := adapter.GetRuntime(getContext(), &c.PodmanCommand)
if err != nil {
return errors.Wrapf(err, "error creating libpod runtime")
}
diff --git a/cmd/podman/diff.go b/cmd/podman/diff.go
index 1138c48a3..9543113d8 100644
--- a/cmd/podman/diff.go
+++ b/cmd/podman/diff.go
@@ -87,7 +87,7 @@ func diffCmd(c *cliconfig.DiffValues) error {
return errors.Errorf("container, image, or layer name must be specified: podman diff [options [...]] ID-NAME")
}
- runtime, err := adapter.GetRuntime(&c.PodmanCommand)
+ runtime, err := adapter.GetRuntime(getContext(), &c.PodmanCommand)
if err != nil {
return errors.Wrapf(err, "could not get runtime")
}
diff --git a/cmd/podman/events.go b/cmd/podman/events.go
index 4c11fe1f3..15f5e9571 100644
--- a/cmd/podman/events.go
+++ b/cmd/podman/events.go
@@ -40,7 +40,7 @@ func init() {
}
func eventsCmd(c *cliconfig.EventValues) error {
- runtime, err := adapter.GetRuntime(&c.PodmanCommand)
+ runtime, err := adapter.GetRuntime(getContext(), &c.PodmanCommand)
if err != nil {
return errors.Wrapf(err, "error creating libpod runtime")
}
diff --git a/cmd/podman/exec.go b/cmd/podman/exec.go
index d0d88ee8b..deff44a92 100644
--- a/cmd/podman/exec.go
+++ b/cmd/podman/exec.go
@@ -68,7 +68,7 @@ func execCmd(c *cliconfig.ExecValues) error {
argStart = 0
}
cmd := args[argStart:]
- runtime, err := libpodruntime.GetRuntime(&c.PodmanCommand)
+ runtime, err := libpodruntime.GetRuntime(getContext(), &c.PodmanCommand)
if err != nil {
return errors.Wrapf(err, "error creating libpod runtime")
}
diff --git a/cmd/podman/exists.go b/cmd/podman/exists.go
index dae48f14b..6619522b6 100644
--- a/cmd/podman/exists.go
+++ b/cmd/podman/exists.go
@@ -86,7 +86,7 @@ func imageExistsCmd(c *cliconfig.ImageExistsValues) error {
if len(args) > 1 || len(args) < 1 {
return errors.New("you may only check for the existence of one image at a time")
}
- runtime, err := adapter.GetRuntime(&c.PodmanCommand)
+ runtime, err := adapter.GetRuntime(getContext(), &c.PodmanCommand)
if err != nil {
return errors.Wrapf(err, "could not get runtime")
}
@@ -107,7 +107,7 @@ func containerExistsCmd(c *cliconfig.ContainerExistsValues) error {
if len(args) > 1 || len(args) < 1 {
return errors.New("you may only check for the existence of one container at a time")
}
- runtime, err := adapter.GetRuntime(&c.PodmanCommand)
+ runtime, err := adapter.GetRuntime(getContext(), &c.PodmanCommand)
if err != nil {
return errors.Wrapf(err, "could not get runtime")
}
@@ -126,7 +126,7 @@ func podExistsCmd(c *cliconfig.PodExistsValues) error {
if len(args) > 1 || len(args) < 1 {
return errors.New("you may only check for the existence of one pod at a time")
}
- runtime, err := adapter.GetRuntime(&c.PodmanCommand)
+ runtime, err := adapter.GetRuntime(getContext(), &c.PodmanCommand)
if err != nil {
return errors.Wrapf(err, "could not get runtime")
}
diff --git a/cmd/podman/export.go b/cmd/podman/export.go
index 004c3ccde..82a4c13e7 100644
--- a/cmd/podman/export.go
+++ b/cmd/podman/export.go
@@ -41,7 +41,7 @@ func init() {
// exportCmd saves a container to a tarball on disk
func exportCmd(c *cliconfig.ExportValues) error {
- runtime, err := adapter.GetRuntime(&c.PodmanCommand)
+ runtime, err := adapter.GetRuntime(getContext(), &c.PodmanCommand)
if err != nil {
return errors.Wrapf(err, "could not get runtime")
}
diff --git a/cmd/podman/generate_kube.go b/cmd/podman/generate_kube.go
index 7963cde6e..318dd0771 100644
--- a/cmd/podman/generate_kube.go
+++ b/cmd/podman/generate_kube.go
@@ -54,7 +54,7 @@ func generateKubeYAMLCmd(c *cliconfig.GenerateKubeValues) error {
return errors.Errorf("you must provide exactly one container|pod ID or name")
}
- runtime, err := adapter.GetRuntime(&c.PodmanCommand)
+ runtime, err := adapter.GetRuntime(getContext(), &c.PodmanCommand)
if err != nil {
return errors.Wrapf(err, "could not get runtime")
}
diff --git a/cmd/podman/healthcheck_run.go b/cmd/podman/healthcheck_run.go
index 832451e0c..111318d9c 100644
--- a/cmd/podman/healthcheck_run.go
+++ b/cmd/podman/healthcheck_run.go
@@ -38,7 +38,7 @@ func init() {
}
func healthCheckCmd(c *cliconfig.HealthCheckValues) error {
- runtime, err := adapter.GetRuntime(&c.PodmanCommand)
+ runtime, err := adapter.GetRuntime(getContext(), &c.PodmanCommand)
if err != nil {
return errors.Wrap(err, "could not get runtime")
}
diff --git a/cmd/podman/history.go b/cmd/podman/history.go
index f96d7934c..cebf99a9f 100644
--- a/cmd/podman/history.go
+++ b/cmd/podman/history.go
@@ -67,7 +67,7 @@ func init() {
}
func historyCmd(c *cliconfig.HistoryValues) error {
- runtime, err := adapter.GetRuntime(&c.PodmanCommand)
+ runtime, err := adapter.GetRuntime(getContext(), &c.PodmanCommand)
if err != nil {
return errors.Wrapf(err, "could not get runtime")
}
diff --git a/cmd/podman/images.go b/cmd/podman/images.go
index 41aa213a8..1c46571c3 100644
--- a/cmd/podman/images.go
+++ b/cmd/podman/images.go
@@ -134,7 +134,7 @@ func imagesCmd(c *cliconfig.ImagesValues) error {
image string
)
- runtime, err := adapter.GetRuntime(&c.PodmanCommand)
+ runtime, err := adapter.GetRuntime(getContext(), &c.PodmanCommand)
if err != nil {
return errors.Wrapf(err, "Could not get runtime")
}
diff --git a/cmd/podman/images_prune.go b/cmd/podman/images_prune.go
index c522c8b15..1ac5bc65d 100644
--- a/cmd/podman/images_prune.go
+++ b/cmd/podman/images_prune.go
@@ -37,7 +37,7 @@ func init() {
}
func pruneImagesCmd(c *cliconfig.PruneImagesValues) error {
- runtime, err := adapter.GetRuntime(&c.PodmanCommand)
+ runtime, err := adapter.GetRuntime(getContext(), &c.PodmanCommand)
if err != nil {
return errors.Wrapf(err, "could not get runtime")
}
diff --git a/cmd/podman/import.go b/cmd/podman/import.go
index 2bba6cb0c..167d9f2c9 100644
--- a/cmd/podman/import.go
+++ b/cmd/podman/import.go
@@ -45,7 +45,7 @@ func init() {
}
func importCmd(c *cliconfig.ImportValues) error {
- runtime, err := adapter.GetRuntime(&c.PodmanCommand)
+ runtime, err := adapter.GetRuntime(getContext(), &c.PodmanCommand)
if err != nil {
return errors.Wrapf(err, "could not get runtime")
}
diff --git a/cmd/podman/info.go b/cmd/podman/info.go
index 2b6ae1882..a6fce7fcb 100644
--- a/cmd/podman/info.go
+++ b/cmd/podman/info.go
@@ -50,7 +50,7 @@ func infoCmd(c *cliconfig.InfoValues) error {
info := map[string]interface{}{}
remoteClientInfo := map[string]interface{}{}
- runtime, err := adapter.GetRuntime(&c.PodmanCommand)
+ runtime, err := adapter.GetRuntime(getContext(), &c.PodmanCommand)
if err != nil {
return errors.Wrapf(err, "could not get runtime")
}
diff --git a/cmd/podman/inspect.go b/cmd/podman/inspect.go
index 9491bc7c7..4303c149c 100644
--- a/cmd/podman/inspect.go
+++ b/cmd/podman/inspect.go
@@ -84,7 +84,7 @@ func inspectCmd(c *cliconfig.InspectValues) error {
return errors.Errorf("you cannot provide additional arguments with --latest")
}
- runtime, err := adapter.GetRuntime(&c.PodmanCommand)
+ runtime, err := adapter.GetRuntime(getContext(), &c.PodmanCommand)
if err != nil {
return errors.Wrapf(err, "error creating libpod runtime")
}
diff --git a/cmd/podman/kill.go b/cmd/podman/kill.go
index 0513a154f..edf69ff2e 100644
--- a/cmd/podman/kill.go
+++ b/cmd/podman/kill.go
@@ -59,7 +59,7 @@ func killCmd(c *cliconfig.KillValues) error {
return err
}
- runtime, err := adapter.GetRuntime(&c.PodmanCommand)
+ runtime, err := adapter.GetRuntime(getContext(), &c.PodmanCommand)
if err != nil {
return errors.Wrapf(err, "could not get runtime")
}
diff --git a/cmd/podman/libpodruntime/runtime.go b/cmd/podman/libpodruntime/runtime.go
index 78adf1252..b03846bbc 100644
--- a/cmd/podman/libpodruntime/runtime.go
+++ b/cmd/podman/libpodruntime/runtime.go
@@ -1,6 +1,8 @@
package libpodruntime
import (
+ "context"
+
"github.com/containers/libpod/cmd/podman/cliconfig"
"github.com/containers/libpod/libpod"
"github.com/containers/libpod/pkg/rootless"
@@ -9,17 +11,22 @@ import (
"github.com/pkg/errors"
)
+// GetRuntimeMigrate gets a libpod runtime that will perform a migration of existing containers
+func GetRuntimeMigrate(ctx context.Context, c *cliconfig.PodmanCommand) (*libpod.Runtime, error) {
+ return getRuntime(ctx, c, false, true)
+}
+
// GetRuntimeRenumber gets a libpod runtime that will perform a lock renumber
-func GetRuntimeRenumber(c *cliconfig.PodmanCommand) (*libpod.Runtime, error) {
- return getRuntime(c, true)
+func GetRuntimeRenumber(ctx context.Context, c *cliconfig.PodmanCommand) (*libpod.Runtime, error) {
+ return getRuntime(ctx, c, true, false)
}
// GetRuntime generates a new libpod runtime configured by command line options
-func GetRuntime(c *cliconfig.PodmanCommand) (*libpod.Runtime, error) {
- return getRuntime(c, false)
+func GetRuntime(ctx context.Context, c *cliconfig.PodmanCommand) (*libpod.Runtime, error) {
+ return getRuntime(ctx, c, false, false)
}
-func getRuntime(c *cliconfig.PodmanCommand, renumber bool) (*libpod.Runtime, error) {
+func getRuntime(ctx context.Context, c *cliconfig.PodmanCommand, renumber bool, migrate bool) (*libpod.Runtime, error) {
options := []libpod.RuntimeOption{}
storageOpts := storage.StoreOptions{}
storageSet := false
@@ -63,11 +70,16 @@ func getRuntime(c *cliconfig.PodmanCommand, renumber bool) (*libpod.Runtime, err
storageSet = true
storageOpts.GraphDriverOptions = c.GlobalFlags.StorageOpts
}
+ if migrate {
+ options = append(options, libpod.WithMigrate())
+ }
if renumber {
options = append(options, libpod.WithRenumber())
}
+ options = append(options, libpod.WithContext(ctx))
+
// Only set this if the user changes storage config on the command line
if storageSet {
options = append(options, libpod.WithStorageConfig(storageOpts))
diff --git a/cmd/podman/load.go b/cmd/podman/load.go
index 3cc5e67c7..f3bbed48f 100644
--- a/cmd/podman/load.go
+++ b/cmd/podman/load.go
@@ -58,7 +58,7 @@ func loadCmd(c *cliconfig.LoadValues) error {
return errors.New("too many arguments. Requires exactly 1")
}
- runtime, err := adapter.GetRuntime(&c.PodmanCommand)
+ runtime, err := adapter.GetRuntime(getContext(), &c.PodmanCommand)
if err != nil {
return errors.Wrapf(err, "could not get runtime")
}
diff --git a/cmd/podman/login.go b/cmd/podman/login.go
index 589255683..6bf148cca 100644
--- a/cmd/podman/login.go
+++ b/cmd/podman/login.go
@@ -11,6 +11,7 @@ import (
"github.com/containers/image/types"
"github.com/containers/libpod/cmd/podman/cliconfig"
"github.com/containers/libpod/libpod/image"
+ "github.com/docker/docker-credential-helpers/credentials"
"github.com/pkg/errors"
"github.com/spf13/cobra"
"golang.org/x/crypto/ssh/terminal"
@@ -90,7 +91,8 @@ func loginCmd(c *cliconfig.LoginValues) error {
// username of user logged in to server (if one exists)
userFromAuthFile, passFromAuthFile, err := config.GetAuthentication(sc, server)
- if err != nil {
+ // Do not return error if no credentials found in credHelpers, new credentials will be stored by config.SetAuthentication
+ if err != nil && err != credentials.NewErrCredentialsNotFound() {
return errors.Wrapf(err, "error reading auth file")
}
diff --git a/cmd/podman/logs.go b/cmd/podman/logs.go
index 6f24dc8fb..a1ec9f4ee 100644
--- a/cmd/podman/logs.go
+++ b/cmd/podman/logs.go
@@ -64,7 +64,7 @@ func init() {
func logsCmd(c *cliconfig.LogsValues) error {
var err error
- runtime, err := adapter.GetRuntime(&c.PodmanCommand)
+ runtime, err := adapter.GetRuntime(getContext(), &c.PodmanCommand)
if err != nil {
return errors.Wrapf(err, "could not get runtime")
}
diff --git a/cmd/podman/main_local.go b/cmd/podman/main_local.go
index 91ad42630..5afd51e28 100644
--- a/cmd/podman/main_local.go
+++ b/cmd/podman/main_local.go
@@ -103,7 +103,7 @@ func profileOff(cmd *cobra.Command) error {
}
func setupRootless(cmd *cobra.Command, args []string) error {
- if os.Geteuid() == 0 || cmd == _searchCommand || cmd == _versionCommand || cmd == _mountCommand || strings.HasPrefix(cmd.Use, "help") {
+ if os.Geteuid() == 0 || cmd == _searchCommand || cmd == _versionCommand || cmd == _mountCommand || cmd == _migrateCommand || strings.HasPrefix(cmd.Use, "help") {
return nil
}
podmanCmd := cliconfig.PodmanCommand{
@@ -112,7 +112,7 @@ func setupRootless(cmd *cobra.Command, args []string) error {
MainGlobalOpts,
remoteclient,
}
- runtime, err := libpodruntime.GetRuntime(&podmanCmd)
+ runtime, err := libpodruntime.GetRuntime(getContext(), &podmanCmd)
if err != nil {
return errors.Wrapf(err, "could not get runtime")
}
diff --git a/cmd/podman/mount.go b/cmd/podman/mount.go
index 2ade8949a..7c9150d1b 100644
--- a/cmd/podman/mount.go
+++ b/cmd/podman/mount.go
@@ -61,7 +61,7 @@ type jsonMountPoint struct {
}
func mountCmd(c *cliconfig.MountValues) error {
- runtime, err := libpodruntime.GetRuntime(&c.PodmanCommand)
+ runtime, err := libpodruntime.GetRuntime(getContext(), &c.PodmanCommand)
if err != nil {
return errors.Wrapf(err, "could not get runtime")
}
diff --git a/cmd/podman/pause.go b/cmd/podman/pause.go
index ca137150a..cd8370082 100644
--- a/cmd/podman/pause.go
+++ b/cmd/podman/pause.go
@@ -43,7 +43,7 @@ func pauseCmd(c *cliconfig.PauseValues) error {
return errors.New("pause is not supported for rootless containers")
}
- runtime, err := adapter.GetRuntime(&c.PodmanCommand)
+ runtime, err := adapter.GetRuntime(getContext(), &c.PodmanCommand)
if err != nil {
return errors.Wrapf(err, "could not get runtime")
}
diff --git a/cmd/podman/play_kube.go b/cmd/podman/play_kube.go
index d1008e615..967798399 100644
--- a/cmd/podman/play_kube.go
+++ b/cmd/podman/play_kube.go
@@ -75,7 +75,7 @@ func playKubeCmd(c *cliconfig.KubePlayValues) error {
}
ctx := getContext()
- runtime, err := libpodruntime.GetRuntime(&c.PodmanCommand)
+ runtime, err := libpodruntime.GetRuntime(ctx, &c.PodmanCommand)
if err != nil {
return errors.Wrapf(err, "could not get runtime")
}
diff --git a/cmd/podman/pod_create.go b/cmd/podman/pod_create.go
index 551010dce..c891f2c7b 100644
--- a/cmd/podman/pod_create.go
+++ b/cmd/podman/pod_create.go
@@ -62,7 +62,7 @@ func podCreateCmd(c *cliconfig.PodCreateValues) error {
podIdFile *os.File
)
- runtime, err := adapter.GetRuntime(&c.PodmanCommand)
+ runtime, err := adapter.GetRuntime(getContext(), &c.PodmanCommand)
if err != nil {
return errors.Wrapf(err, "error creating libpod runtime")
}
diff --git a/cmd/podman/pod_inspect.go b/cmd/podman/pod_inspect.go
index eb2366031..a22624078 100644
--- a/cmd/podman/pod_inspect.go
+++ b/cmd/podman/pod_inspect.go
@@ -49,7 +49,7 @@ func podInspectCmd(c *cliconfig.PodInspectValues) error {
return errors.Errorf("you must provide the name or id of a pod")
}
- runtime, err := adapter.GetRuntime(&c.PodmanCommand)
+ runtime, err := adapter.GetRuntime(getContext(), &c.PodmanCommand)
if err != nil {
return errors.Wrapf(err, "could not get runtime")
}
diff --git a/cmd/podman/pod_kill.go b/cmd/podman/pod_kill.go
index 145d0492f..c1ea66126 100644
--- a/cmd/podman/pod_kill.go
+++ b/cmd/podman/pod_kill.go
@@ -49,7 +49,7 @@ func init() {
// podKillCmd kills one or more pods with a signal
func podKillCmd(c *cliconfig.PodKillValues) error {
- runtime, err := adapter.GetRuntime(&c.PodmanCommand)
+ runtime, err := adapter.GetRuntime(getContext(), &c.PodmanCommand)
if err != nil {
return errors.Wrapf(err, "could not get runtime")
}
diff --git a/cmd/podman/pod_pause.go b/cmd/podman/pod_pause.go
index 1c6611ebc..e8574bfdc 100644
--- a/cmd/podman/pod_pause.go
+++ b/cmd/podman/pod_pause.go
@@ -45,7 +45,7 @@ func init() {
func podPauseCmd(c *cliconfig.PodPauseValues) error {
var lastError error
- runtime, err := adapter.GetRuntime(&c.PodmanCommand)
+ runtime, err := adapter.GetRuntime(getContext(), &c.PodmanCommand)
if err != nil {
return errors.Wrapf(err, "error creating libpod runtime")
}
diff --git a/cmd/podman/pod_ps.go b/cmd/podman/pod_ps.go
index f4b7437eb..b9dcbc05d 100644
--- a/cmd/podman/pod_ps.go
+++ b/cmd/podman/pod_ps.go
@@ -157,7 +157,7 @@ func podPsCmd(c *cliconfig.PodPsValues) error {
return errors.Wrapf(err, "error with flags passed")
}
- runtime, err := adapter.GetRuntime(&c.PodmanCommand)
+ runtime, err := adapter.GetRuntime(getContext(), &c.PodmanCommand)
if err != nil {
return errors.Wrapf(err, "error creating libpod runtime")
}
diff --git a/cmd/podman/pod_restart.go b/cmd/podman/pod_restart.go
index 519568974..a1f4c8359 100644
--- a/cmd/podman/pod_restart.go
+++ b/cmd/podman/pod_restart.go
@@ -47,7 +47,7 @@ func init() {
func podRestartCmd(c *cliconfig.PodRestartValues) error {
var lastError error
- runtime, err := adapter.GetRuntime(&c.PodmanCommand)
+ runtime, err := adapter.GetRuntime(getContext(), &c.PodmanCommand)
if err != nil {
return errors.Wrapf(err, "could not get runtime")
}
diff --git a/cmd/podman/pod_rm.go b/cmd/podman/pod_rm.go
index dd67bb0e0..218ed8154 100644
--- a/cmd/podman/pod_rm.go
+++ b/cmd/podman/pod_rm.go
@@ -47,7 +47,7 @@ func init() {
// podRmCmd deletes pods
func podRmCmd(c *cliconfig.PodRmValues) error {
- runtime, err := adapter.GetRuntime(&c.PodmanCommand)
+ runtime, err := adapter.GetRuntime(getContext(), &c.PodmanCommand)
if err != nil {
return errors.Wrapf(err, "could not get runtime")
}
diff --git a/cmd/podman/pod_start.go b/cmd/podman/pod_start.go
index 104f9ad73..5c9225428 100644
--- a/cmd/podman/pod_start.go
+++ b/cmd/podman/pod_start.go
@@ -45,7 +45,7 @@ func init() {
}
func podStartCmd(c *cliconfig.PodStartValues) error {
- runtime, err := adapter.GetRuntime(&c.PodmanCommand)
+ runtime, err := adapter.GetRuntime(getContext(), &c.PodmanCommand)
if err != nil {
return errors.Wrapf(err, "could not get runtime")
}
diff --git a/cmd/podman/pod_stats.go b/cmd/podman/pod_stats.go
index ed59d9a61..e0e5ca24e 100644
--- a/cmd/podman/pod_stats.go
+++ b/cmd/podman/pod_stats.go
@@ -78,7 +78,7 @@ func podStatsCmd(c *cliconfig.PodStatsValues) error {
all = true
}
- runtime, err := adapter.GetRuntime(&c.PodmanCommand)
+ runtime, err := adapter.GetRuntime(getContext(), &c.PodmanCommand)
if err != nil {
return errors.Wrapf(err, "could not get runtime")
}
diff --git a/cmd/podman/pod_stop.go b/cmd/podman/pod_stop.go
index 9cd425c29..b4b1718d9 100644
--- a/cmd/podman/pod_stop.go
+++ b/cmd/podman/pod_stop.go
@@ -47,7 +47,7 @@ func init() {
}
func podStopCmd(c *cliconfig.PodStopValues) error {
- runtime, err := adapter.GetRuntime(&c.PodmanCommand)
+ runtime, err := adapter.GetRuntime(getContext(), &c.PodmanCommand)
if err != nil {
return errors.Wrapf(err, "could not get runtime")
}
diff --git a/cmd/podman/pod_top.go b/cmd/podman/pod_top.go
index e997d1456..64e32318e 100644
--- a/cmd/podman/pod_top.go
+++ b/cmd/podman/pod_top.go
@@ -67,7 +67,7 @@ func podTopCmd(c *cliconfig.PodTopValues) error {
return errors.Errorf("you must provide the name or id of a running pod")
}
- runtime, err := adapter.GetRuntime(&c.PodmanCommand)
+ runtime, err := adapter.GetRuntime(getContext(), &c.PodmanCommand)
if err != nil {
return errors.Wrapf(err, "error creating libpod runtime")
}
diff --git a/cmd/podman/pod_unpause.go b/cmd/podman/pod_unpause.go
index 15375bee9..c5b7e6a18 100644
--- a/cmd/podman/pod_unpause.go
+++ b/cmd/podman/pod_unpause.go
@@ -46,7 +46,7 @@ func init() {
func podUnpauseCmd(c *cliconfig.PodUnpauseValues) error {
var lastError error
- runtime, err := adapter.GetRuntime(&c.PodmanCommand)
+ runtime, err := adapter.GetRuntime(getContext(), &c.PodmanCommand)
if err != nil {
return errors.Wrapf(err, "error creating libpod runtime")
}
diff --git a/cmd/podman/pods_prune.go b/cmd/podman/pods_prune.go
index e6946f068..bdd75f9de 100644
--- a/cmd/podman/pods_prune.go
+++ b/cmd/podman/pods_prune.go
@@ -36,7 +36,7 @@ func init() {
}
func podPruneCmd(c *cliconfig.PodPruneValues) error {
- runtime, err := adapter.GetRuntime(&c.PodmanCommand)
+ runtime, err := adapter.GetRuntime(getContext(), &c.PodmanCommand)
if err != nil {
return errors.Wrapf(err, "could not get runtime")
}
diff --git a/cmd/podman/port.go b/cmd/podman/port.go
index d63ae4aa9..7a9f01fe6 100644
--- a/cmd/podman/port.go
+++ b/cmd/podman/port.go
@@ -98,7 +98,7 @@ func portCmd(c *cliconfig.PortValues) error {
}
}
- runtime, err := libpodruntime.GetRuntime(&c.PodmanCommand)
+ runtime, err := libpodruntime.GetRuntime(getContext(), &c.PodmanCommand)
if err != nil {
return errors.Wrapf(err, "could not get runtime")
}
diff --git a/cmd/podman/ps.go b/cmd/podman/ps.go
index df1ea2765..623f17050 100644
--- a/cmd/podman/ps.go
+++ b/cmd/podman/ps.go
@@ -211,7 +211,7 @@ func psCmd(c *cliconfig.PsValues) error {
return errors.Wrapf(err, "error with flags passed")
}
- runtime, err := adapter.GetRuntime(&c.PodmanCommand)
+ runtime, err := adapter.GetRuntime(getContext(), &c.PodmanCommand)
if err != nil {
return errors.Wrapf(err, "error creating libpod runtime")
}
diff --git a/cmd/podman/pull.go b/cmd/podman/pull.go
index 521419e7a..f6a5beb17 100644
--- a/cmd/podman/pull.go
+++ b/cmd/podman/pull.go
@@ -73,7 +73,7 @@ func pullCmd(c *cliconfig.PullValues) (retError error) {
defer span.Finish()
}
- runtime, err := adapter.GetRuntime(&c.PodmanCommand)
+ runtime, err := adapter.GetRuntime(getContext(), &c.PodmanCommand)
if err != nil {
return errors.Wrapf(err, "could not get runtime")
diff --git a/cmd/podman/push.go b/cmd/podman/push.go
index e6beaaeb4..ee14b15e2 100644
--- a/cmd/podman/push.go
+++ b/cmd/podman/push.go
@@ -100,7 +100,7 @@ func pushCmd(c *cliconfig.PushValues) error {
registryCreds = creds
}
- runtime, err := adapter.GetRuntime(&c.PodmanCommand)
+ runtime, err := adapter.GetRuntime(getContext(), &c.PodmanCommand)
if err != nil {
return errors.Wrapf(err, "could not create runtime")
}
diff --git a/cmd/podman/refresh.go b/cmd/podman/refresh.go
index 6640d9954..9f9cbf908 100644
--- a/cmd/podman/refresh.go
+++ b/cmd/podman/refresh.go
@@ -38,7 +38,7 @@ func init() {
}
func refreshCmd(c *cliconfig.RefreshValues) error {
- runtime, err := libpodruntime.GetRuntime(&c.PodmanCommand)
+ runtime, err := libpodruntime.GetRuntime(getContext(), &c.PodmanCommand)
if err != nil {
return errors.Wrapf(err, "error creating libpod runtime")
}
diff --git a/cmd/podman/restart.go b/cmd/podman/restart.go
index 9ab2dd528..437676eef 100644
--- a/cmd/podman/restart.go
+++ b/cmd/podman/restart.go
@@ -51,7 +51,7 @@ func restartCmd(c *cliconfig.RestartValues) error {
return errors.Wrapf(libpod.ErrInvalidArg, "you must provide at least one container name or ID")
}
- runtime, err := adapter.GetRuntime(&c.PodmanCommand)
+ runtime, err := adapter.GetRuntime(getContext(), &c.PodmanCommand)
if err != nil {
return errors.Wrapf(err, "error creating libpod runtime")
}
diff --git a/cmd/podman/restore.go b/cmd/podman/restore.go
index d9e85c267..8cfd5ca0d 100644
--- a/cmd/podman/restore.go
+++ b/cmd/podman/restore.go
@@ -54,7 +54,7 @@ func restoreCmd(c *cliconfig.RestoreValues) error {
return errors.New("restoring a container requires root")
}
- runtime, err := adapter.GetRuntime(&c.PodmanCommand)
+ runtime, err := adapter.GetRuntime(getContext(), &c.PodmanCommand)
if err != nil {
return errors.Wrapf(err, "could not get runtime")
}
diff --git a/cmd/podman/rm.go b/cmd/podman/rm.go
index e3ee186ce..1bf56b782 100644
--- a/cmd/podman/rm.go
+++ b/cmd/podman/rm.go
@@ -48,7 +48,7 @@ func init() {
// rmCmd removes one or more containers
func rmCmd(c *cliconfig.RmValues) error {
- runtime, err := adapter.GetRuntime(&c.PodmanCommand)
+ runtime, err := adapter.GetRuntime(getContext(), &c.PodmanCommand)
if err != nil {
return errors.Wrapf(err, "could not get runtime")
}
diff --git a/cmd/podman/rmi.go b/cmd/podman/rmi.go
index be7c81dab..4c41a3ad5 100644
--- a/cmd/podman/rmi.go
+++ b/cmd/podman/rmi.go
@@ -51,7 +51,7 @@ func rmiCmd(c *cliconfig.RmiValues) error {
ctx := getContext()
removeAll := c.All
- runtime, err := adapter.GetRuntime(&c.PodmanCommand)
+ runtime, err := adapter.GetRuntime(getContext(), &c.PodmanCommand)
if err != nil {
return errors.Wrapf(err, "could not get runtime")
}
diff --git a/cmd/podman/run.go b/cmd/podman/run.go
index 717a36e04..01b12d282 100644
--- a/cmd/podman/run.go
+++ b/cmd/podman/run.go
@@ -48,7 +48,7 @@ func runCmd(c *cliconfig.RunValues) error {
return err
}
- runtime, err := adapter.GetRuntime(&c.PodmanCommand)
+ runtime, err := adapter.GetRuntime(getContext(), &c.PodmanCommand)
if err != nil {
return errors.Wrapf(err, "error creating libpod runtime")
}
diff --git a/cmd/podman/runlabel.go b/cmd/podman/runlabel.go
index 8267e941f..f097cb693 100644
--- a/cmd/podman/runlabel.go
+++ b/cmd/podman/runlabel.go
@@ -85,7 +85,7 @@ func runlabelCmd(c *cliconfig.RunlabelValues) error {
}
opts := make(map[string]string)
- runtime, err := libpodruntime.GetRuntime(&c.PodmanCommand)
+ runtime, err := libpodruntime.GetRuntime(getContext(), &c.PodmanCommand)
if err != nil {
return errors.Wrapf(err, "could not get runtime")
}
diff --git a/cmd/podman/save.go b/cmd/podman/save.go
index a45223b6a..4d204337e 100644
--- a/cmd/podman/save.go
+++ b/cmd/podman/save.go
@@ -70,7 +70,7 @@ func saveCmd(c *cliconfig.SaveValues) error {
return errors.Errorf("need at least 1 argument")
}
- runtime, err := adapter.GetRuntime(&c.PodmanCommand)
+ runtime, err := adapter.GetRuntime(getContext(), &c.PodmanCommand)
if err != nil {
return errors.Wrapf(err, "could not create runtime")
}
diff --git a/cmd/podman/shared/container.go b/cmd/podman/shared/container.go
index e14276bdf..9050fd2b9 100644
--- a/cmd/podman/shared/container.go
+++ b/cmd/podman/shared/container.go
@@ -658,7 +658,8 @@ func GetCtrInspectInfo(config *libpod.ContainerConfig, ctrInspectData *inspect.C
OomKillDisable: memDisableOOMKiller,
PidsLimit: pidsLimit,
Privileged: config.Privileged,
- ReadonlyRootfs: spec.Root.Readonly,
+ ReadOnlyRootfs: spec.Root.Readonly,
+ ReadOnlyTmpfs: createArtifact.ReadOnlyTmpfs,
Runtime: config.OCIRuntime,
NetworkMode: string(createArtifact.NetMode),
IpcMode: string(createArtifact.IpcMode),
diff --git a/cmd/podman/shared/create.go b/cmd/podman/shared/create.go
index 3f54e193f..c521f9cb6 100644
--- a/cmd/podman/shared/create.go
+++ b/cmd/podman/shared/create.go
@@ -650,6 +650,7 @@ func ParseCreateOpts(ctx context.Context, c *GenericCLIResults, runtime *libpod.
PortBindings: portBindings,
Quiet: c.Bool("quiet"),
ReadOnlyRootfs: c.Bool("read-only"),
+ ReadOnlyTmpfs: c.Bool("read-only-tmpfs"),
Resources: cc.CreateResourceConfig{
BlkioWeight: blkioWeight,
BlkioWeightDevice: c.StringSlice("blkio-weight-device"),
diff --git a/cmd/podman/shared/intermediate.go b/cmd/podman/shared/intermediate.go
index 2e1827561..9c494dec5 100644
--- a/cmd/podman/shared/intermediate.go
+++ b/cmd/podman/shared/intermediate.go
@@ -434,6 +434,7 @@ func NewIntermediateLayer(c *cliconfig.PodmanCommand, remote bool) GenericCLIRes
m["publish-all"] = newCRBool(c, "publish-all")
m["quiet"] = newCRBool(c, "quiet")
m["read-only"] = newCRBool(c, "read-only")
+ m["read-only-tmpfs"] = newCRBool(c, "read-only-tmpfs")
m["restart"] = newCRString(c, "restart")
m["rm"] = newCRBool(c, "rm")
m["rootfs"] = newCRBool(c, "rootfs")
diff --git a/cmd/podman/shared/intermediate_varlink.go b/cmd/podman/shared/intermediate_varlink.go
index d62a65955..5e21245e3 100644
--- a/cmd/podman/shared/intermediate_varlink.go
+++ b/cmd/podman/shared/intermediate_varlink.go
@@ -141,6 +141,7 @@ func (g GenericCLIResults) MakeVarlink() iopodman.Create {
PublishAll: BoolToPtr(g.Find("publish-all")),
Quiet: BoolToPtr(g.Find("quiet")),
Readonly: BoolToPtr(g.Find("read-only")),
+ Readonlytmpfs: BoolToPtr(g.Find("read-only-tmpfs")),
Restart: StringToPtr(g.Find("restart")),
Rm: BoolToPtr(g.Find("rm")),
Rootfs: BoolToPtr(g.Find("rootfs")),
@@ -397,6 +398,7 @@ func VarlinkCreateToGeneric(opts iopodman.Create) GenericCLIResults {
m["publish-all"] = boolFromVarlink(opts.PublishAll, "publish-all", false)
m["quiet"] = boolFromVarlink(opts.Quiet, "quiet", false)
m["read-only"] = boolFromVarlink(opts.Readonly, "read-only", false)
+ m["read-only-tmpfs"] = boolFromVarlink(opts.Readonlytmpfs, "read-only-tmpfs", true)
m["restart"] = stringFromVarlink(opts.Restart, "restart", nil)
m["rm"] = boolFromVarlink(opts.Rm, "rm", false)
m["rootfs"] = boolFromVarlink(opts.Rootfs, "rootfs", false)
diff --git a/cmd/podman/sign.go b/cmd/podman/sign.go
index b19b6a840..0c25eec62 100644
--- a/cmd/podman/sign.go
+++ b/cmd/podman/sign.go
@@ -56,7 +56,7 @@ func signCmd(c *cliconfig.SignValues) error {
if len(args) < 1 {
return errors.Errorf("at least one image name must be specified")
}
- runtime, err := libpodruntime.GetRuntime(&c.PodmanCommand)
+ runtime, err := libpodruntime.GetRuntime(getContext(), &c.PodmanCommand)
if err != nil {
return errors.Wrapf(err, "could not create runtime")
}
diff --git a/cmd/podman/start.go b/cmd/podman/start.go
index 9f93061f9..bd34010f2 100644
--- a/cmd/podman/start.go
+++ b/cmd/podman/start.go
@@ -65,7 +65,7 @@ func startCmd(c *cliconfig.StartValues) error {
return errors.Wrapf(libpod.ErrInvalidArg, "you cannot use sig-proxy without --attach")
}
- runtime, err := adapter.GetRuntime(&c.PodmanCommand)
+ runtime, err := adapter.GetRuntime(getContext(), &c.PodmanCommand)
if err != nil {
return errors.Wrapf(err, "error creating libpod runtime")
}
diff --git a/cmd/podman/stats.go b/cmd/podman/stats.go
index 6aa0cc10c..c2b2a688c 100644
--- a/cmd/podman/stats.go
+++ b/cmd/podman/stats.go
@@ -88,7 +88,7 @@ func statsCmd(c *cliconfig.StatsValues) error {
return errors.Errorf("you must specify --all, --latest, or at least one container")
}
- runtime, err := libpodruntime.GetRuntime(&c.PodmanCommand)
+ runtime, err := libpodruntime.GetRuntime(getContext(), &c.PodmanCommand)
if err != nil {
return errors.Wrapf(err, "could not get runtime")
}
diff --git a/cmd/podman/stop.go b/cmd/podman/stop.go
index f263bb166..d88c90deb 100644
--- a/cmd/podman/stop.go
+++ b/cmd/podman/stop.go
@@ -56,7 +56,7 @@ func stopCmd(c *cliconfig.StopValues) error {
defer span.Finish()
}
- runtime, err := adapter.GetRuntime(&c.PodmanCommand)
+ runtime, err := adapter.GetRuntime(getContext(), &c.PodmanCommand)
if err != nil {
return errors.Wrapf(err, "could not get runtime")
}
diff --git a/cmd/podman/system_df.go b/cmd/podman/system_df.go
index aa0ead022..840916547 100644
--- a/cmd/podman/system_df.go
+++ b/cmd/podman/system_df.go
@@ -99,7 +99,7 @@ func init() {
}
func dfSystemCmd(c *cliconfig.SystemDfValues) error {
- runtime, err := libpodruntime.GetRuntime(&c.PodmanCommand)
+ runtime, err := libpodruntime.GetRuntime(getContext(), &c.PodmanCommand)
if err != nil {
return errors.Wrapf(err, "Could not get runtime")
}
diff --git a/cmd/podman/system_migrate.go b/cmd/podman/system_migrate.go
new file mode 100644
index 000000000..4a0afcfad
--- /dev/null
+++ b/cmd/podman/system_migrate.go
@@ -0,0 +1,50 @@
+package main
+
+import (
+ "github.com/containers/libpod/cmd/podman/cliconfig"
+ "github.com/containers/libpod/cmd/podman/libpodruntime"
+ "github.com/pkg/errors"
+ "github.com/spf13/cobra"
+)
+
+var (
+ migrateCommand cliconfig.SystemMigrateValues
+ migrateDescription = `
+ podman system migrate
+
+ Migrate existing containers to a new version of Podman.
+`
+
+ _migrateCommand = &cobra.Command{
+ Use: "migrate",
+ Args: noSubArgs,
+ Short: "Migrate containers",
+ Long: migrateDescription,
+ RunE: func(cmd *cobra.Command, args []string) error {
+ migrateCommand.InputArgs = args
+ migrateCommand.GlobalFlags = MainGlobalOpts
+ return migrateCmd(&migrateCommand)
+ },
+ }
+)
+
+func init() {
+ migrateCommand.Command = _migrateCommand
+ migrateCommand.SetHelpTemplate(HelpTemplate())
+ migrateCommand.SetUsageTemplate(UsageTemplate())
+}
+
+func migrateCmd(c *cliconfig.SystemMigrateValues) error {
+ // We need to pass one extra option to NewRuntime.
+ // This will inform the OCI runtime to start a migrate.
+ // That's controlled by the last argument to GetRuntime.
+ r, err := libpodruntime.GetRuntimeMigrate(getContext(), &c.PodmanCommand)
+ if err != nil {
+ return errors.Wrapf(err, "error migrating containers")
+ }
+ if err := r.Shutdown(false); err != nil {
+ return err
+ }
+
+ return nil
+}
diff --git a/cmd/podman/system_prune.go b/cmd/podman/system_prune.go
index 37b6ef95f..d5b218cd8 100644
--- a/cmd/podman/system_prune.go
+++ b/cmd/podman/system_prune.go
@@ -72,7 +72,7 @@ Are you sure you want to continue? [y/N] `, volumeString)
}
}
- runtime, err := adapter.GetRuntime(&c.PodmanCommand)
+ runtime, err := adapter.GetRuntime(getContext(), &c.PodmanCommand)
if err != nil {
return errors.Wrapf(err, "could not get runtime")
}
diff --git a/cmd/podman/system_renumber.go b/cmd/podman/system_renumber.go
index 70ba706bb..81752a177 100644
--- a/cmd/podman/system_renumber.go
+++ b/cmd/podman/system_renumber.go
@@ -40,7 +40,7 @@ func renumberCmd(c *cliconfig.SystemRenumberValues) error {
// We need to pass one extra option to NewRuntime.
// This will inform the OCI runtime to start a renumber.
// That's controlled by the last argument to GetRuntime.
- r, err := libpodruntime.GetRuntimeRenumber(&c.PodmanCommand)
+ r, err := libpodruntime.GetRuntimeRenumber(getContext(), &c.PodmanCommand)
if err != nil {
return errors.Wrapf(err, "error renumbering locks")
}
diff --git a/cmd/podman/tag.go b/cmd/podman/tag.go
index deda4e985..58f221e26 100644
--- a/cmd/podman/tag.go
+++ b/cmd/podman/tag.go
@@ -38,7 +38,7 @@ func tagCmd(c *cliconfig.TagValues) error {
if len(args) < 2 {
return errors.Errorf("image name and at least one new name must be specified")
}
- runtime, err := adapter.GetRuntime(&c.PodmanCommand)
+ runtime, err := adapter.GetRuntime(getContext(), &c.PodmanCommand)
if err != nil {
return errors.Wrapf(err, "could not create runtime")
}
diff --git a/cmd/podman/top.go b/cmd/podman/top.go
index f1f594ebf..2e0a22d92 100644
--- a/cmd/podman/top.go
+++ b/cmd/podman/top.go
@@ -76,7 +76,7 @@ func topCmd(c *cliconfig.TopValues) error {
return errors.Errorf("you must provide the name or id of a running container")
}
- runtime, err := adapter.GetRuntime(&c.PodmanCommand)
+ runtime, err := adapter.GetRuntime(getContext(), &c.PodmanCommand)
if err != nil {
return errors.Wrapf(err, "error creating libpod runtime")
}
diff --git a/cmd/podman/tree.go b/cmd/podman/tree.go
index f205c83e4..6490c609d 100644
--- a/cmd/podman/tree.go
+++ b/cmd/podman/tree.go
@@ -51,7 +51,7 @@ func treeCmd(c *cliconfig.TreeValues) error {
return errors.Errorf("you must provide at most 1 argument")
}
- runtime, err := adapter.GetRuntime(&c.PodmanCommand)
+ runtime, err := adapter.GetRuntime(getContext(), &c.PodmanCommand)
if err != nil {
return errors.Wrapf(err, "error creating libpod runtime")
}
diff --git a/cmd/podman/trust_set_show.go b/cmd/podman/trust_set_show.go
index 580331673..b615f6266 100644
--- a/cmd/podman/trust_set_show.go
+++ b/cmd/podman/trust_set_show.go
@@ -74,7 +74,7 @@ File(s) must exist before using this command`)
}
func showTrustCmd(c *cliconfig.ShowTrustValues) error {
- runtime, err := libpodruntime.GetRuntime(&c.PodmanCommand)
+ runtime, err := libpodruntime.GetRuntime(getContext(), &c.PodmanCommand)
if err != nil {
return errors.Wrapf(err, "could not create runtime")
}
@@ -131,7 +131,7 @@ func showTrustCmd(c *cliconfig.ShowTrustValues) error {
}
func setTrustCmd(c *cliconfig.SetTrustValues) error {
- runtime, err := libpodruntime.GetRuntime(&c.PodmanCommand)
+ runtime, err := libpodruntime.GetRuntime(getContext(), &c.PodmanCommand)
if err != nil {
return errors.Wrapf(err, "could not create runtime")
}
diff --git a/cmd/podman/umount.go b/cmd/podman/umount.go
index cdf8b951a..ddbd00bd5 100644
--- a/cmd/podman/umount.go
+++ b/cmd/podman/umount.go
@@ -48,7 +48,7 @@ func init() {
}
func umountCmd(c *cliconfig.UmountValues) error {
- runtime, err := adapter.GetRuntime(&c.PodmanCommand)
+ runtime, err := adapter.GetRuntime(getContext(), &c.PodmanCommand)
if err != nil {
return errors.Wrapf(err, "error creating runtime")
}
diff --git a/cmd/podman/unpause.go b/cmd/podman/unpause.go
index fa946bfd7..2cd6846fe 100644
--- a/cmd/podman/unpause.go
+++ b/cmd/podman/unpause.go
@@ -42,7 +42,7 @@ func unpauseCmd(c *cliconfig.UnpauseValues) error {
return errors.New("unpause is not supported for rootless containers")
}
- runtime, err := adapter.GetRuntime(&c.PodmanCommand)
+ runtime, err := adapter.GetRuntime(getContext(), &c.PodmanCommand)
if err != nil {
return errors.Wrapf(err, "could not get runtime")
}
diff --git a/cmd/podman/varlink.go b/cmd/podman/varlink.go
index 787ad01cd..978678a84 100644
--- a/cmd/podman/varlink.go
+++ b/cmd/podman/varlink.go
@@ -55,7 +55,7 @@ func varlinkCmd(c *cliconfig.VarlinkValues) error {
timeout := time.Duration(c.Timeout) * time.Millisecond
// Create a single runtime for varlink
- runtime, err := libpodruntime.GetRuntime(&c.PodmanCommand)
+ runtime, err := libpodruntime.GetRuntime(getContext(), &c.PodmanCommand)
if err != nil {
return errors.Wrapf(err, "error creating libpod runtime")
}
diff --git a/cmd/podman/varlink/io.podman.varlink b/cmd/podman/varlink/io.podman.varlink
index 17179d665..309f9765a 100644
--- a/cmd/podman/varlink/io.podman.varlink
+++ b/cmd/podman/varlink/io.podman.varlink
@@ -346,6 +346,7 @@ type Create (
publishAll: ?bool,
quiet: ?bool,
readonly: ?bool,
+ readonlytmpfs: ?bool,
restart: ?string,
rm: ?bool,
rootfs: ?bool,
diff --git a/cmd/podman/volume_create.go b/cmd/podman/volume_create.go
index 2b10adb2b..84f6bba94 100644
--- a/cmd/podman/volume_create.go
+++ b/cmd/podman/volume_create.go
@@ -42,7 +42,7 @@ func init() {
}
func volumeCreateCmd(c *cliconfig.VolumeCreateValues) error {
- runtime, err := adapter.GetRuntime(&c.PodmanCommand)
+ runtime, err := adapter.GetRuntime(getContext(), &c.PodmanCommand)
if err != nil {
return errors.Wrapf(err, "error creating libpod runtime")
}
diff --git a/cmd/podman/volume_inspect.go b/cmd/podman/volume_inspect.go
index 66d394307..e4b05f96a 100644
--- a/cmd/podman/volume_inspect.go
+++ b/cmd/podman/volume_inspect.go
@@ -43,7 +43,7 @@ func volumeInspectCmd(c *cliconfig.VolumeInspectValues) error {
return errors.New("provide one or more volume names or use --all")
}
- runtime, err := adapter.GetRuntime(&c.PodmanCommand)
+ runtime, err := adapter.GetRuntime(getContext(), &c.PodmanCommand)
if err != nil {
return errors.Wrapf(err, "error creating libpod runtime")
}
diff --git a/cmd/podman/volume_ls.go b/cmd/podman/volume_ls.go
index b9ab89196..581e595cb 100644
--- a/cmd/podman/volume_ls.go
+++ b/cmd/podman/volume_ls.go
@@ -72,7 +72,7 @@ func init() {
}
func volumeLsCmd(c *cliconfig.VolumeLsValues) error {
- runtime, err := adapter.GetRuntime(&c.PodmanCommand)
+ runtime, err := adapter.GetRuntime(getContext(), &c.PodmanCommand)
if err != nil {
return errors.Wrapf(err, "error creating libpod runtime")
}
diff --git a/cmd/podman/volume_prune.go b/cmd/podman/volume_prune.go
index ad62bfc22..6dc9e2403 100644
--- a/cmd/podman/volume_prune.go
+++ b/cmd/podman/volume_prune.go
@@ -63,7 +63,7 @@ func volumePrune(runtime *adapter.LocalRuntime, ctx context.Context) error {
}
func volumePruneCmd(c *cliconfig.VolumePruneValues) error {
- runtime, err := adapter.GetRuntime(&c.PodmanCommand)
+ runtime, err := adapter.GetRuntime(getContext(), &c.PodmanCommand)
if err != nil {
return errors.Wrapf(err, "error creating libpod runtime")
}
diff --git a/cmd/podman/volume_rm.go b/cmd/podman/volume_rm.go
index 4534019c6..77137eb7a 100644
--- a/cmd/podman/volume_rm.go
+++ b/cmd/podman/volume_rm.go
@@ -47,7 +47,7 @@ func volumeRmCmd(c *cliconfig.VolumeRmValues) error {
return errors.New("choose either one or more volumes or all")
}
- runtime, err := adapter.GetRuntime(&c.PodmanCommand)
+ runtime, err := adapter.GetRuntime(getContext(), &c.PodmanCommand)
if err != nil {
return errors.Wrapf(err, "error creating libpod runtime")
}
diff --git a/cmd/podman/wait.go b/cmd/podman/wait.go
index 97ec75b0c..380e861ed 100644
--- a/cmd/podman/wait.go
+++ b/cmd/podman/wait.go
@@ -51,7 +51,7 @@ func waitCmd(c *cliconfig.WaitValues) error {
}
interval := time.Duration(c.Interval) * time.Millisecond
- runtime, err := adapter.GetRuntime(&c.PodmanCommand)
+ runtime, err := adapter.GetRuntime(getContext(), &c.PodmanCommand)
if err != nil {
return errors.Wrapf(err, "error creating runtime")
}
diff --git a/completions/bash/podman b/completions/bash/podman
index dce23df2b..6acdcc05a 100644
--- a/completions/bash/podman
+++ b/completions/bash/podman
@@ -1765,6 +1765,7 @@ _podman_container_run() {
--publish-all -P
--quiet
--read-only
+ --read-only-tmpfs
--tty -t
"
diff --git a/contrib/cirrus/packer/ubuntu_setup.sh b/contrib/cirrus/packer/ubuntu_setup.sh
index 24f1cce21..e84566ce3 100644
--- a/contrib/cirrus/packer/ubuntu_setup.sh
+++ b/contrib/cirrus/packer/ubuntu_setup.sh
@@ -49,7 +49,7 @@ ooe.sh sudo -E apt-get -qq install \
gettext \
go-md2man \
golang \
- iproute \
+ iproute2 \
iptables \
libaio-dev \
libapparmor-dev \
@@ -68,6 +68,7 @@ ooe.sh sudo -E apt-get -qq install \
libprotobuf-dev \
libseccomp-dev \
libseccomp2 \
+ libsystemd-dev \
libtool \
libudev-dev \
lsof \
diff --git a/contrib/cirrus/setup_environment.sh b/contrib/cirrus/setup_environment.sh
index 0d26f6c9a..3818abbc7 100755
--- a/contrib/cirrus/setup_environment.sh
+++ b/contrib/cirrus/setup_environment.sh
@@ -55,7 +55,6 @@ then
# Some setup needs to vary between distros
case "${OS_RELEASE_ID}-${OS_RELEASE_VER}" in
ubuntu-18)
- sudo apt-get -qq -y install libsystemd-dev
# Always install runc on Ubuntu
install_runc_from_git
;;
diff --git a/docs/podman-create.1.md b/docs/podman-create.1.md
index f61deebd2..52c965293 100644
--- a/docs/podman-create.1.md
+++ b/docs/podman-create.1.md
@@ -542,6 +542,9 @@ By default a container will have its root filesystem writable allowing processes
to write files anywhere. By specifying the `--read-only` flag the container will have
its root filesystem mounted as read only prohibiting any writes.
+**--read-only-tmpfs**=*true*|*false*
+If container is running in --read-only mode, then mount a read-write tmpfs on /run, /tmp, and /var/tmp. The default is *true*
+
**--restart=""**
Not implemented.
diff --git a/docs/podman-run.1.md b/docs/podman-run.1.md
index 5a311980f..e54e5e691 100644
--- a/docs/podman-run.1.md
+++ b/docs/podman-run.1.md
@@ -534,6 +534,9 @@ By default a container will have its root filesystem writable allowing processes
to write files anywhere. By specifying the `--read-only` flag the container will have
its root filesystem mounted as read only prohibiting any writes.
+**--read-only-tmpfs**=*true*|*false*
+If container is running in --read-only mode, then mount a read-write tmpfs on /run, /tmp, and /var/tmp. The default is *true*
+
**--restart=""**
Not implemented.
@@ -905,7 +908,11 @@ still need to write temporary data. The best way to handle this is to mount
tmpfs directories on /run and /tmp.
```
-$ podman run --read-only --tmpfs /run --tmpfs /tmp -i -t fedora /bin/bash
+$ podman run --read-only -i -t fedora /bin/bash
+```
+
+```
+$ podman run --read-only --read-only-tmpfs=false --tmpfs /run -i -t fedora /bin/bash
```
### Exposing log messages from the container to the host's log
diff --git a/docs/podman-system-migrate.1.md b/docs/podman-system-migrate.1.md
new file mode 100644
index 000000000..7c2d1823c
--- /dev/null
+++ b/docs/podman-system-migrate.1.md
@@ -0,0 +1,21 @@
+% podman-system-migrate(1) podman
+
+## NAME
+podman\-system\-migrate - Migrate container to the latest version of podman
+
+## SYNOPSIS
+** podman system migrate**
+
+## DESCRIPTION
+** podman system migrate** migrates containers to the latest podman version.
+
+**podman system migrate** takes care of migrating existing containers to the latest version of podman if any change is necessary.
+
+## SYNOPSIS
+**podman system migrate**
+
+## SEE ALSO
+`podman(1)`, `libpod.conf(5)`
+
+# HISTORY
+April 2019, Originally compiled by Giuseppe Scrivano (gscrivan at redhat dot com)
diff --git a/docs/podman-system.1.md b/docs/podman-system.1.md
index 32b3efdd9..d36715feb 100644
--- a/docs/podman-system.1.md
+++ b/docs/podman-system.1.md
@@ -17,6 +17,7 @@ The system command allows you to manage the podman systems
| info | [podman-system-info(1)](podman-info.1.md) | Displays Podman related system information. |
| prune | [podman-system-prune(1)](podman-system-prune.1.md) | Remove all unused data |
| renumber | [podman-system-renumber(1)](podman-system-renumber.1.md)| Migrate lock numbers to handle a change in maximum number of locks. |
+| migrate | [podman-system-migrate(1)](podman-system-migrate.1.md)| Migrate existing containers to a new podman version. |
## SEE ALSO
podman(1)
diff --git a/libpod/container_internal_linux.go b/libpod/container_internal_linux.go
index f352b188e..c5e404155 100644
--- a/libpod/container_internal_linux.go
+++ b/libpod/container_internal_linux.go
@@ -420,7 +420,7 @@ func (c *Container) generateSpec(ctx context.Context) (*spec.Spec, error) {
// It also expects to be able to write to /sys/fs/cgroup/systemd and /var/log/journal
func (c *Container) setupSystemd(mounts []spec.Mount, g generate.Generator) error {
options := []string{"rw", "rprivate", "noexec", "nosuid", "nodev"}
- for _, dest := range []string{"/run", "/run/lock"} {
+ for _, dest := range []string{"/run"} {
if MountExists(mounts, dest) {
continue
}
diff --git a/libpod/events.go b/libpod/events.go
index 1b5c3bd99..13bb5bdde 100644
--- a/libpod/events.go
+++ b/libpod/events.go
@@ -50,6 +50,16 @@ func (p *Pod) newPodEvent(status events.Status) {
}
}
+// newSystemEvent creates a new event for libpod as a whole.
+func (r *Runtime) newSystemEvent(status events.Status) {
+ e := events.NewEvent(status)
+ e.Type = events.System
+
+ if err := r.eventer.Write(e); err != nil {
+ logrus.Errorf("unable to write system event: %q", err)
+ }
+}
+
// newVolumeEvent creates a new event for a libpod volume
func (v *Volume) newVolumeEvent(status events.Status) {
e := events.NewEvent(status)
diff --git a/libpod/events/config.go b/libpod/events/config.go
index d3b6d8c50..36387e835 100644
--- a/libpod/events/config.go
+++ b/libpod/events/config.go
@@ -84,6 +84,9 @@ const (
Image Type = "image"
// Pod - event is related to pods
Pod Type = "pod"
+ // System - event is related to Podman whole and not to any specific
+ // container/pod/image/volume
+ System Type = "system"
// Volume - event is related to volumes
Volume Type = "volume"
@@ -123,8 +126,14 @@ const (
Pull Status = "pull"
// Push ...
Push Status = "push"
+ // Refresh indicates that the system refreshed the state after a
+ // reboot.
+ Refresh Status = "refresh"
// Remove ...
Remove Status = "remove"
+ // Renumber indicates that lock numbers were reallocated at user
+ // request.
+ Renumber Status = "renumber"
// Restore ...
Restore Status = "restore"
// Save ...
diff --git a/libpod/events/events.go b/libpod/events/events.go
index e8c61faa0..202c9db4e 100644
--- a/libpod/events/events.go
+++ b/libpod/events/events.go
@@ -49,6 +49,8 @@ func (e *Event) ToHumanReadable() string {
humanFormat = fmt.Sprintf("%s %s %s %s (image=%s, name=%s)", e.Time, e.Type, e.Status, e.ID, e.Image, e.Name)
case Image:
humanFormat = fmt.Sprintf("%s %s %s %s %s", e.Time, e.Type, e.Status, e.ID, e.Name)
+ case System:
+ humanFormat = fmt.Sprintf("%s %s %s", e.Time, e.Type, e.Status)
case Volume:
humanFormat = fmt.Sprintf("%s %s %s %s", e.Time, e.Type, e.Status, e.Name)
}
@@ -85,10 +87,12 @@ func StringToType(name string) (Type, error) {
return Image, nil
case Pod.String():
return Pod, nil
+ case System.String():
+ return System, nil
case Volume.String():
return Volume, nil
}
- return "", errors.Errorf("unknown event type %s", name)
+ return "", errors.Errorf("unknown event type %q", name)
}
// StringToStatus converts a string to an Event Status
@@ -107,7 +111,6 @@ func StringToStatus(name string) (Status, error) {
case Commit.String():
return Commit, nil
case Create.String():
-
return Create, nil
case Exec.String():
return Exec, nil
@@ -135,8 +138,14 @@ func StringToStatus(name string) (Status, error) {
return Pull, nil
case Push.String():
return Push, nil
+ case Refresh.String():
+ return Refresh, nil
case Remove.String():
return Remove, nil
+ case Renumber.String():
+ return Renumber, nil
+ case Restore.String():
+ return Restore, nil
case Save.String():
return Save, nil
case Start.String():
@@ -154,7 +163,7 @@ func StringToStatus(name string) (Status, error) {
case Untag.String():
return Untag, nil
}
- return "", errors.Errorf("unknown event status %s", name)
+ return "", errors.Errorf("unknown event status %q", name)
}
func (e EventLogFile) getTail(options ReadOptions) (*tail.Tail, error) {
diff --git a/libpod/events/events_linux.go b/libpod/events/events_linux.go
index d6898145c..da5d7965e 100644
--- a/libpod/events/events_linux.go
+++ b/libpod/events/events_linux.go
@@ -1,13 +1,16 @@
package events
import (
- "github.com/pkg/errors"
"strings"
+
+ "github.com/pkg/errors"
+ "github.com/sirupsen/logrus"
)
// NewEventer creates an eventer based on the eventer type
func NewEventer(options EventerOptions) (Eventer, error) {
var eventer Eventer
+ logrus.Debugf("Initializing event backend %s", options.EventerType)
switch strings.ToUpper(options.EventerType) {
case strings.ToUpper(Journald.String()):
eventer = EventJournalD{options}
diff --git a/libpod/events/journal_linux.go b/libpod/events/journal_linux.go
index e6b54db1d..8ba5bc2c7 100644
--- a/libpod/events/journal_linux.go
+++ b/libpod/events/journal_linux.go
@@ -7,6 +7,7 @@ import (
"github.com/coreos/go-systemd/journal"
"github.com/coreos/go-systemd/sdjournal"
"github.com/pkg/errors"
+ "github.com/sirupsen/logrus"
)
// EventJournalD is the journald implementation of an eventer
@@ -87,7 +88,11 @@ func (e EventJournalD) Read(options ReadOptions) error {
}
newEvent, err := newEventFromJournalEntry(entry)
if err != nil {
- return err
+ // We can't decode this event.
+ // Don't fail hard - that would make events unusable.
+ // Instead, log and continue.
+ logrus.Errorf("Unable to decode event: %v", err)
+ continue
}
include := true
for _, filter := range eventOptions {
diff --git a/libpod/events/logfile.go b/libpod/events/logfile.go
index 3232b86d0..e5efc09bb 100644
--- a/libpod/events/logfile.go
+++ b/libpod/events/logfile.go
@@ -4,6 +4,7 @@ import (
"fmt"
"os"
+ "github.com/containers/storage"
"github.com/pkg/errors"
)
@@ -15,6 +16,13 @@ type EventLogFile struct {
// Writes to the log file
func (e EventLogFile) Write(ee Event) error {
+ // We need to lock events file
+ lock, err := storage.GetLockfile(e.options.LogFilePath + ".lock")
+ if err != nil {
+ return err
+ }
+ lock.Lock()
+ defer lock.Unlock()
f, err := os.OpenFile(e.options.LogFilePath, os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0700)
if err != nil {
return err
diff --git a/libpod/options.go b/libpod/options.go
index 8038f1935..9932d5453 100644
--- a/libpod/options.go
+++ b/libpod/options.go
@@ -1,6 +1,7 @@
package libpod
import (
+ "context"
"net"
"os"
"path/filepath"
@@ -436,6 +437,22 @@ func WithRenumber() RuntimeOption {
}
}
+// WithMigrate instructs libpod to perform a lock migrateing while
+// initializing. This will handle migrations from early versions of libpod with
+// file locks to newer versions with SHM locking, as well as changes in the
+// number of configured locks.
+func WithMigrate() RuntimeOption {
+ return func(rt *Runtime) error {
+ if rt.valid {
+ return ErrRuntimeFinalized
+ }
+
+ rt.doMigrate = true
+
+ return nil
+ }
+}
+
// Container Creation Options
// WithShmDir sets the directory that should be mounted on /dev/shm.
@@ -450,6 +467,19 @@ func WithShmDir(dir string) CtrCreateOption {
}
}
+// WithContext sets the context to use.
+func WithContext(ctx context.Context) RuntimeOption {
+ return func(rt *Runtime) error {
+ if rt.valid {
+ return ErrRuntimeFinalized
+ }
+
+ rt.ctx = ctx
+
+ return nil
+ }
+}
+
// WithSystemd turns on systemd mode in the container
func WithSystemd() CtrCreateOption {
return func(ctr *Container) error {
diff --git a/libpod/runtime.go b/libpod/runtime.go
index d03731284..e85242028 100644
--- a/libpod/runtime.go
+++ b/libpod/runtime.go
@@ -1,8 +1,8 @@
package libpod
import (
+ "context"
"fmt"
- "github.com/containers/libpod/libpod/events"
"io/ioutil"
"os"
"path/filepath"
@@ -12,6 +12,7 @@ import (
"github.com/BurntSushi/toml"
is "github.com/containers/image/storage"
"github.com/containers/image/types"
+ "github.com/containers/libpod/libpod/events"
"github.com/containers/libpod/libpod/image"
"github.com/containers/libpod/libpod/lock"
"github.com/containers/libpod/pkg/firewall"
@@ -100,6 +101,8 @@ type Runtime struct {
// unused.
doRenumber bool
+ doMigrate bool
+
// valid indicates whether the runtime is ready to use.
// valid is set to true when a runtime is returned from GetRuntime(),
// and remains true until the runtime is shut down (rendering its
@@ -109,6 +112,8 @@ type Runtime struct {
// mechanism to read and write even logs
eventer events.Eventer
+
+ ctx context.Context
}
// OCIRuntimePath contains information about an OCI runtime.
@@ -754,6 +759,17 @@ func makeRuntime(runtime *Runtime) (err error) {
if err != nil {
return err
}
+
+ defer func() {
+ if err != nil && store != nil {
+ // Don't forcibly shut down
+ // We could be opening a store in use by another libpod
+ _, err2 := store.Shutdown(false)
+ if err2 != nil {
+ logrus.Errorf("Error removing store for partially-created runtime: %s", err2)
+ }
+ }
+ }()
}
runtime.store = store
@@ -780,17 +796,6 @@ func makeRuntime(runtime *Runtime) (err error) {
runtime.eventer = eventer
ir.Eventer = eventer
- defer func() {
- if err != nil && store != nil {
- // Don't forcibly shut down
- // We could be opening a store in use by another libpod
- _, err2 := store.Shutdown(false)
- if err2 != nil {
- logrus.Errorf("Error removing store for partially-created runtime: %s", err2)
- }
- }
- }()
-
// Set up a storage service for creating container root filesystems from
// images
storageService, err := getStorageService(runtime.store)
@@ -962,6 +967,24 @@ func makeRuntime(runtime *Runtime) (err error) {
// further
runtime.valid = true
+ if runtime.doMigrate {
+ if os.Geteuid() != 0 {
+ aliveLock.Unlock()
+ locked = false
+
+ became, ret, err := rootless.BecomeRootInUserNS()
+ if err != nil {
+ return err
+ }
+ if became {
+ os.Exit(ret)
+ }
+ }
+ if err := runtime.migrate(); err != nil {
+ return err
+ }
+ }
+
return nil
}
@@ -1074,6 +1097,8 @@ func (r *Runtime) refresh(alivePath string) error {
}
defer file.Close()
+ r.newSystemEvent(events.Refresh)
+
return nil
}
diff --git a/libpod/runtime_migrate.go b/libpod/runtime_migrate.go
new file mode 100644
index 000000000..a084df289
--- /dev/null
+++ b/libpod/runtime_migrate.go
@@ -0,0 +1,47 @@
+package libpod
+
+import (
+ "path/filepath"
+
+ "github.com/pkg/errors"
+ "github.com/sirupsen/logrus"
+)
+
+func (r *Runtime) migrate() error {
+ runningContainers, err := r.GetRunningContainers()
+ if err != nil {
+ return err
+ }
+
+ allCtrs, err := r.state.AllContainers()
+ if err != nil {
+ return err
+ }
+
+ logrus.Infof("stopping all containers")
+ for _, ctr := range runningContainers {
+ logrus.Infof("stopping %s", ctr.ID())
+ if err := ctr.Stop(); err != nil {
+ return errors.Wrapf(err, "cannot stop container %s", ctr.ID())
+ }
+ }
+
+ for _, ctr := range allCtrs {
+ oldLocation := filepath.Join(ctr.state.RunDir, "conmon.pid")
+ if ctr.config.ConmonPidFile == oldLocation {
+ logrus.Infof("changing conmon PID file for %s", ctr.ID())
+ ctr.config.ConmonPidFile = filepath.Join(ctr.config.StaticDir, "conmon.pid")
+ if err := r.state.RewriteContainerConfig(ctr, ctr.config); err != nil {
+ return errors.Wrapf(err, "error rewriting config for container %s", ctr.ID())
+ }
+ }
+ }
+
+ for _, ctr := range runningContainers {
+ if err := ctr.Start(r.ctx, true); err != nil {
+ logrus.Errorf("error restarting container %s", ctr.ID())
+ }
+ }
+
+ return nil
+}
diff --git a/libpod/runtime_renumber.go b/libpod/runtime_renumber.go
index 125cf0825..735ffba34 100644
--- a/libpod/runtime_renumber.go
+++ b/libpod/runtime_renumber.go
@@ -1,6 +1,7 @@
package libpod
import (
+ "github.com/containers/libpod/libpod/events"
"github.com/pkg/errors"
)
@@ -53,5 +54,7 @@ func (r *Runtime) renumberLocks() error {
}
}
+ r.newSystemEvent(events.Renumber)
+
return nil
}
diff --git a/pkg/adapter/runtime.go b/pkg/adapter/runtime.go
index 790ed5c89..0d840d65b 100644
--- a/pkg/adapter/runtime.go
+++ b/pkg/adapter/runtime.go
@@ -57,8 +57,8 @@ type Volume struct {
type VolumeFilter func(*Volume) bool
// GetRuntime returns a LocalRuntime struct with the actual runtime embedded in it
-func GetRuntime(c *cliconfig.PodmanCommand) (*LocalRuntime, error) {
- runtime, err := libpodruntime.GetRuntime(c)
+func GetRuntime(ctx context.Context, c *cliconfig.PodmanCommand) (*LocalRuntime, error) {
+ runtime, err := libpodruntime.GetRuntime(ctx, c)
if err != nil {
return nil, err
}
diff --git a/pkg/adapter/runtime_remote.go b/pkg/adapter/runtime_remote.go
index 29ee821e0..6102daccf 100644
--- a/pkg/adapter/runtime_remote.go
+++ b/pkg/adapter/runtime_remote.go
@@ -46,7 +46,7 @@ type LocalRuntime struct {
}
// GetRuntime returns a LocalRuntime struct with the actual runtime embedded in it
-func GetRuntime(c *cliconfig.PodmanCommand) (*LocalRuntime, error) {
+func GetRuntime(ctx context.Context, c *cliconfig.PodmanCommand) (*LocalRuntime, error) {
runtime := RemoteRuntime{}
conn, err := runtime.Connect()
if err != nil {
diff --git a/pkg/inspect/inspect.go b/pkg/inspect/inspect.go
index 270e431ad..6978370ef 100644
--- a/pkg/inspect/inspect.go
+++ b/pkg/inspect/inspect.go
@@ -38,7 +38,8 @@ type HostConfig struct {
PidMode string `json:"PidMode"`
Privileged bool `json:"Privileged"`
PublishAllPorts bool `json:"PublishAllPorts"` //TODO
- ReadonlyRootfs bool `json:"ReadonlyRootfs"`
+ ReadOnlyRootfs bool `json:"ReadonlyRootfs"`
+ ReadOnlyTmpfs bool `json:"ReadonlyTmpfs"`
SecurityOpt []string `json:"SecurityOpt"`
UTSMode string `json:"UTSMode"`
UsernsMode string `json:"UsernsMode"`
diff --git a/pkg/spec/createconfig.go b/pkg/spec/createconfig.go
index e71d9d3db..064dedd45 100644
--- a/pkg/spec/createconfig.go
+++ b/pkg/spec/createconfig.go
@@ -113,6 +113,7 @@ type CreateConfig struct {
PublishAll bool //publish-all
Quiet bool //quiet
ReadOnlyRootfs bool //read-only
+ ReadOnlyTmpfs bool //read-only-tmpfs
Resources CreateResourceConfig
Rm bool //rm
StopSignal syscall.Signal // stop-signal
diff --git a/pkg/spec/spec.go b/pkg/spec/spec.go
index 0371b6d4d..4cbed0ea4 100644
--- a/pkg/spec/spec.go
+++ b/pkg/spec/spec.go
@@ -341,6 +341,31 @@ func CreateConfigToOCISpec(config *CreateConfig) (*spec.Spec, error) { //nolint
}
}
+ if config.ReadOnlyRootfs && config.ReadOnlyTmpfs {
+ options := []string{"rw", "rprivate", "nosuid", "nodev", "tmpcopyup"}
+ for _, i := range []string{"/tmp", "/var/tmp"} {
+ if libpod.MountExists(g.Config.Mounts, i) {
+ continue
+ }
+ // Default options if nothing passed
+ tmpfsMnt := spec.Mount{
+ Destination: i,
+ Type: "tmpfs",
+ Source: "tmpfs",
+ Options: options,
+ }
+ g.AddMount(tmpfsMnt)
+ }
+ if !libpod.MountExists(g.Config.Mounts, "/run") {
+ tmpfsMnt := spec.Mount{
+ Destination: "/run",
+ Type: "tmpfs",
+ Source: "tmpfs",
+ Options: append(options, "noexec", "size=65536k"),
+ }
+ g.AddMount(tmpfsMnt)
+ }
+ }
for name, val := range config.Env {
g.AddProcessEnv(name, val)
}
diff --git a/vendor.conf b/vendor.conf
index 572ae5fdb..02283beb9 100644
--- a/vendor.conf
+++ b/vendor.conf
@@ -19,7 +19,7 @@ github.com/containers/image v1.5.1
github.com/vbauerster/mpb v3.3.4
github.com/mattn/go-isatty v0.0.4
github.com/VividCortex/ewma v1.1.1
-github.com/containers/storage v1.12.3
+github.com/containers/storage v1.12.5
github.com/containers/psgo v1.2.1
github.com/coreos/go-systemd v14
github.com/coreos/pkg v4
@@ -94,7 +94,7 @@ k8s.io/apimachinery kubernetes-1.10.13-beta.0 https://github.com/kubernetes/apim
k8s.io/client-go kubernetes-1.10.13-beta.0 https://github.com/kubernetes/client-go
github.com/mrunalp/fileutils 7d4729fb36185a7c1719923406c9d40e54fb93c7
github.com/varlink/go 3ac79db6fd6aec70924193b090962f92985fe199
-github.com/containers/buildah fcc12bdadf6a5fab77e62e1bd12663bb6fbc3eda
+github.com/containers/buildah v1.8.0
# TODO: Gotty has not been updated since 2012. Can we find replacement?
github.com/Nvveen/Gotty cd527374f1e5bff4938207604a14f2e38a9cf512
github.com/fsouza/go-dockerclient v1.3.0
diff --git a/vendor/github.com/containers/buildah/add.go b/vendor/github.com/containers/buildah/add.go
index d42246d53..d67a481f1 100644
--- a/vendor/github.com/containers/buildah/add.go
+++ b/vendor/github.com/containers/buildah/add.go
@@ -292,7 +292,7 @@ func addHelper(excludes []DockerIgnore, extract bool, dest string, destfi os.Fil
break
}
// combine the filename with the dest directory
- fpath := strings.TrimPrefix(path, options.ContextDir)
+ fpath := strings.TrimPrefix(path, esrc)
if err = copyFileWithTar(path, filepath.Join(dest, fpath)); err != nil {
return errors.Wrapf(err, "error copying %q to %q", path, dest)
}
diff --git a/vendor/github.com/containers/buildah/buildah.go b/vendor/github.com/containers/buildah/buildah.go
index 8b076630f..b6e6545ec 100644
--- a/vendor/github.com/containers/buildah/buildah.go
+++ b/vendor/github.com/containers/buildah/buildah.go
@@ -26,7 +26,7 @@ const (
Package = "buildah"
// Version for the Package. Bump version in contrib/rpm/buildah.spec
// too.
- Version = "1.8-dev"
+ Version = "1.8.0"
// The value we use to identify what type of information, currently a
// serialized Builder structure, we are using as per-container state.
// This should only be changed when we make incompatible changes to
@@ -282,6 +282,8 @@ type CommonBuildOptions struct {
CPUSetCPUs string
// CPUSetMems memory nodes (MEMs) in which to allow execution (0-3, 0,1). Only effective on NUMA systems.
CPUSetMems string
+ // HTTPProxy determines whether *_proxy env vars from the build host are passed into the container.
+ HTTPProxy bool
// Memory is the upper limit (in bytes) on how much memory running containers can use.
Memory int64
// DNSSearch is the list of DNS search domains to add to the build container's /etc/resolv.conf
diff --git a/vendor/github.com/containers/buildah/chroot/run.go b/vendor/github.com/containers/buildah/chroot/run.go
index ff39c2f24..1c3ac65f3 100644
--- a/vendor/github.com/containers/buildah/chroot/run.go
+++ b/vendor/github.com/containers/buildah/chroot/run.go
@@ -512,7 +512,7 @@ func runUsingChroot(spec *specs.Spec, bundlePath string, ctty *os.File, stdin io
logNamespaceDiagnostics(spec)
// If we have configured ID mappings, set them here so that they can apply to the child.
- hostUidmap, hostGidmap, err := util.GetHostIDMappings("")
+ hostUidmap, hostGidmap, err := unshare.GetHostIDMappings("")
if err != nil {
return 1, err
}
diff --git a/vendor/github.com/containers/buildah/chroot/selinux.go b/vendor/github.com/containers/buildah/chroot/selinux.go
index 3e62d743d..08e8f998b 100644
--- a/vendor/github.com/containers/buildah/chroot/selinux.go
+++ b/vendor/github.com/containers/buildah/chroot/selinux.go
@@ -13,7 +13,7 @@ import (
// setSelinuxLabel sets the process label for child processes that we'll start.
func setSelinuxLabel(spec *specs.Spec) error {
logrus.Debugf("setting selinux label")
- if spec.Process.SelinuxLabel != "" && selinux.EnforceMode() != selinux.Disabled {
+ if spec.Process.SelinuxLabel != "" && selinux.GetEnabled() {
if err := label.SetProcessLabel(spec.Process.SelinuxLabel); err != nil {
return errors.Wrapf(err, "error setting process label to %q", spec.Process.SelinuxLabel)
}
diff --git a/vendor/github.com/containers/buildah/commit.go b/vendor/github.com/containers/buildah/commit.go
index 5e73be881..05d1550b3 100644
--- a/vendor/github.com/containers/buildah/commit.go
+++ b/vendor/github.com/containers/buildah/commit.go
@@ -64,12 +64,9 @@ type CommitOptions struct {
// manifest of the new image will reference the blobs rather than
// on-disk layers.
BlobDirectory string
-
- // OnBuild is a list of commands to be run by images based on this image
- OnBuild []string
- // Parent is the base image that this image was created by.
- Parent string
-
+ // EmptyLayer tells the builder to omit the diff for the working
+ // container.
+ EmptyLayer bool
// OmitTimestamp forces epoch 0 as created timestamp to allow for
// deterministic, content-addressable builds.
OmitTimestamp bool
@@ -169,7 +166,7 @@ func (b *Builder) Commit(ctx context.Context, dest types.ImageReference, options
}
}
// Build an image reference from which we can copy the finished image.
- src, err := b.makeImageRef(options.PreferredManifestType, options.Parent, exportBaseLayers, options.Squash, options.BlobDirectory, options.Compression, options.HistoryTimestamp, options.OmitTimestamp)
+ src, err := b.makeImageRef(options, exportBaseLayers)
if err != nil {
return imgID, nil, "", errors.Wrapf(err, "error computing layer digests and building metadata for container %q", b.ContainerID)
}
diff --git a/vendor/github.com/containers/buildah/image.go b/vendor/github.com/containers/buildah/image.go
index 1cd329c85..215920cc3 100644
--- a/vendor/github.com/containers/buildah/image.go
+++ b/vendor/github.com/containers/buildah/image.go
@@ -56,6 +56,7 @@ type containerImageRef struct {
preferredManifestType string
exporting bool
squash bool
+ emptyLayer bool
tarPath func(path string) (io.ReadCloser, error)
parent string
blobDirectory string
@@ -184,7 +185,7 @@ func (i *containerImageRef) createConfigsAndManifests() (v1.Image, v1.Manifest,
if err := json.Unmarshal(i.dconfig, &dimage); err != nil {
return v1.Image{}, v1.Manifest{}, docker.V2Image{}, docker.V2S2Manifest{}, err
}
- dimage.Parent = docker.ID(digest.FromString(i.parent))
+ dimage.Parent = docker.ID(i.parent)
// Always replace this value, since we're newer than our base image.
dimage.Created = created
// Clear the list of diffIDs, since we always repopulate it.
@@ -290,6 +291,11 @@ func (i *containerImageRef) NewImageSource(ctx context.Context, sc *types.System
if err != nil {
return nil, errors.Wrapf(err, "unable to locate layer %q", layerID)
}
+ // If we're up to the final layer, but we don't want to include
+ // a diff for it, we're done.
+ if i.emptyLayer && layerID == i.layerID {
+ continue
+ }
// If we're not re-exporting the data, and we're reusing layers individually, reuse
// the blobsum and diff IDs.
if !i.exporting && !i.squash && layerID != i.layerID {
@@ -433,7 +439,7 @@ func (i *containerImageRef) NewImageSource(ctx context.Context, sc *types.System
CreatedBy: i.createdBy,
Author: oimage.Author,
Comment: i.historyComment,
- EmptyLayer: false,
+ EmptyLayer: i.emptyLayer,
}
oimage.History = append(oimage.History, onews)
dnews := docker.V2S2History{
@@ -441,11 +447,11 @@ func (i *containerImageRef) NewImageSource(ctx context.Context, sc *types.System
CreatedBy: i.createdBy,
Author: dimage.Author,
Comment: i.historyComment,
- EmptyLayer: false,
+ EmptyLayer: i.emptyLayer,
}
dimage.History = append(dimage.History, dnews)
appendHistory(i.postEmptyLayers)
- dimage.Parent = docker.ID(digest.FromString(i.parent))
+ dimage.Parent = docker.ID(i.parent)
// Sanity check that we didn't just create a mismatch between non-empty layers in the
// history and the number of diffIDs.
@@ -636,7 +642,7 @@ func (i *containerImageSource) GetBlob(ctx context.Context, blob types.BlobInfo,
return ioutils.NewReadCloserWrapper(layerFile, closer), size, nil
}
-func (b *Builder) makeImageRef(manifestType, parent string, exporting bool, squash bool, blobDirectory string, compress archive.Compression, historyTimestamp *time.Time, omitTimestamp bool) (types.ImageReference, error) {
+func (b *Builder) makeImageRef(options CommitOptions, exporting bool) (types.ImageReference, error) {
var name reference.Named
container, err := b.store.Container(b.ContainerID)
if err != nil {
@@ -647,6 +653,7 @@ func (b *Builder) makeImageRef(manifestType, parent string, exporting bool, squa
name = parsed
}
}
+ manifestType := options.PreferredManifestType
if manifestType == "" {
manifestType = OCIv1ImageManifest
}
@@ -659,8 +666,8 @@ func (b *Builder) makeImageRef(manifestType, parent string, exporting bool, squa
return nil, errors.Wrapf(err, "error encoding docker-format image configuration %#v", b.Docker)
}
created := time.Now().UTC()
- if historyTimestamp != nil {
- created = historyTimestamp.UTC()
+ if options.HistoryTimestamp != nil {
+ created = options.HistoryTimestamp.UTC()
}
createdBy := b.CreatedBy()
if createdBy == "" {
@@ -670,13 +677,21 @@ func (b *Builder) makeImageRef(manifestType, parent string, exporting bool, squa
}
}
- if omitTimestamp {
+ if options.OmitTimestamp {
created = time.Unix(0, 0)
}
+ parent := ""
+ if b.FromImageID != "" {
+ parentDigest := digest.NewDigestFromEncoded(digest.Canonical, b.FromImageID)
+ if parentDigest.Validate() == nil {
+ parent = parentDigest.String()
+ }
+ }
+
ref := &containerImageRef{
store: b.store,
- compression: compress,
+ compression: options.Compression,
name: name,
names: container.Names,
containerID: container.ID,
@@ -690,10 +705,11 @@ func (b *Builder) makeImageRef(manifestType, parent string, exporting bool, squa
annotations: b.Annotations(),
preferredManifestType: manifestType,
exporting: exporting,
- squash: squash,
+ squash: options.Squash,
+ emptyLayer: options.EmptyLayer,
tarPath: b.tarPath(),
parent: parent,
- blobDirectory: blobDirectory,
+ blobDirectory: options.BlobDirectory,
preEmptyLayers: b.PrependedEmptyLayers,
postEmptyLayers: b.AppendedEmptyLayers,
}
diff --git a/vendor/github.com/containers/buildah/imagebuildah/build.go b/vendor/github.com/containers/buildah/imagebuildah/build.go
index b692d3bcf..d9909cdc8 100644
--- a/vendor/github.com/containers/buildah/imagebuildah/build.go
+++ b/vendor/github.com/containers/buildah/imagebuildah/build.go
@@ -28,7 +28,7 @@ import (
"github.com/containers/storage"
"github.com/containers/storage/pkg/archive"
docker "github.com/fsouza/go-dockerclient"
- "github.com/opencontainers/image-spec/specs-go/v1"
+ v1 "github.com/opencontainers/image-spec/specs-go/v1"
"github.com/opencontainers/runtime-spec/specs-go"
"github.com/openshift/imagebuilder"
"github.com/openshift/imagebuilder/dockerfile/parser"
@@ -215,9 +215,12 @@ type Executor struct {
forceRmIntermediateCtrs bool
imageMap map[string]string // Used to map images that we create to handle the AS construct.
containerMap map[string]*buildah.Builder // Used to map from image names to only-created-for-the-rootfs containers.
+ baseMap map[string]bool // Holds the names of every base image, as given.
+ rootfsMap map[string]bool // Holds the names of every stage whose rootfs is referenced in a COPY or ADD instruction.
blobDirectory string
excludes []string
unusedArgs map[string]struct{}
+ buildArgs map[string]string
}
// StageExecutor bundles up what we need to know when executing one stage of a
@@ -480,6 +483,19 @@ func (s *StageExecutor) volumeCacheRestore() error {
// imagebuilder tells us the instruction was "ADD" and not "COPY".
func (s *StageExecutor) Copy(excludes []string, copies ...imagebuilder.Copy) error {
for _, copy := range copies {
+ // If the file exists, check to see if it's a symlink.
+ // If it is a symlink, convert to it's target otherwise
+ // the symlink will be overwritten.
+ fileDest, _ := os.Lstat(filepath.Join(s.mountPoint, copy.Dest))
+ if fileDest != nil {
+ if fileDest.Mode()&os.ModeSymlink != 0 {
+ if symLink, err := resolveSymlink(s.mountPoint, copy.Dest); err == nil {
+ copy.Dest = symLink
+ } else {
+ return errors.Wrapf(err, "error reading symbolic link to %q", copy.Dest)
+ }
+ }
+ }
if copy.Download {
logrus.Debugf("ADD %#v, %#v", excludes, copy)
} else {
@@ -590,7 +606,7 @@ func (s *StageExecutor) Run(run imagebuilder.Run, config docker.Config) error {
// UnrecognizedInstruction is called when we encounter an instruction that the
// imagebuilder parser didn't understand.
func (s *StageExecutor) UnrecognizedInstruction(step *imagebuilder.Step) error {
- errStr := fmt.Sprintf("Build error: Unknown instruction: %q ", step.Command)
+ errStr := fmt.Sprintf("Build error: Unknown instruction: %q ", strings.ToUpper(step.Command))
err := fmt.Sprintf(errStr+"%#v", step)
if s.executor.ignoreUnrecognizedInstructions {
logrus.Debugf(err)
@@ -610,7 +626,7 @@ func (s *StageExecutor) UnrecognizedInstruction(step *imagebuilder.Step) error {
}
// NewExecutor creates a new instance of the imagebuilder.Executor interface.
-func NewExecutor(store storage.Store, options BuildOptions) (*Executor, error) {
+func NewExecutor(store storage.Store, options BuildOptions, mainNode *parser.Node) (*Executor, error) {
excludes, err := imagebuilder.ParseDockerignore(options.ContextDirectory)
if err != nil {
return nil, err
@@ -656,8 +672,11 @@ func NewExecutor(store storage.Store, options BuildOptions) (*Executor, error) {
forceRmIntermediateCtrs: options.ForceRmIntermediateCtrs,
imageMap: make(map[string]string),
containerMap: make(map[string]*buildah.Builder),
+ baseMap: make(map[string]bool),
+ rootfsMap: make(map[string]bool),
blobDirectory: options.BlobDirectory,
unusedArgs: make(map[string]struct{}),
+ buildArgs: options.Args,
}
if exec.err == nil {
exec.err = os.Stderr
@@ -679,6 +698,25 @@ func NewExecutor(store storage.Store, options BuildOptions) (*Executor, error) {
exec.unusedArgs[arg] = struct{}{}
}
}
+ for _, line := range mainNode.Children {
+ node := line
+ for node != nil { // tokens on this line, though we only care about the first
+ switch strings.ToUpper(node.Value) { // first token - instruction
+ case "ARG":
+ arg := node.Next
+ if arg != nil {
+ // We have to be careful here - it's either an argument
+ // and value, or just an argument, since they can be
+ // separated by either "=" or whitespace.
+ list := strings.SplitN(arg.Value, "=", 2)
+ if _, stillUnused := exec.unusedArgs[list[0]]; stillUnused {
+ delete(exec.unusedArgs, list[0])
+ }
+ }
+ }
+ break
+ }
+ }
return &exec, nil
}
@@ -845,9 +883,9 @@ func (b *Executor) resolveNameToImageRef(output string) (types.ImageReference, e
return imageRef, nil
}
-// stepRequiresCommit indicates whether or not the step should be followed by
-// committing the in-progress container to create an intermediate image.
-func (*StageExecutor) stepRequiresCommit(step *imagebuilder.Step) bool {
+// stepRequiresLayer indicates whether or not the step should be followed by
+// committing a layer container when creating an intermediate image.
+func (*StageExecutor) stepRequiresLayer(step *imagebuilder.Step) bool {
switch strings.ToUpper(step.Command) {
case "ADD", "COPY", "RUN":
return true
@@ -875,6 +913,10 @@ func (s *StageExecutor) getImageRootfs(ctx context.Context, stage imagebuilder.S
func (s *StageExecutor) Execute(ctx context.Context, stage imagebuilder.Stage, base string) (imgID string, ref reference.Canonical, err error) {
ib := stage.Builder
checkForLayers := s.executor.layers && s.executor.useCache
+ moreStages := s.index < s.stages-1
+ lastStage := !moreStages
+ imageIsUsedLater := moreStages && (s.executor.baseMap[stage.Name] || s.executor.baseMap[fmt.Sprintf("%d", stage.Position)])
+ rootfsIsUsedLater := moreStages && (s.executor.rootfsMap[stage.Name] || s.executor.rootfsMap[fmt.Sprintf("%d", stage.Position)])
// If the base image's name corresponds to the result of an earlier
// stage, substitute that image's ID for the base image's name here.
@@ -896,7 +938,8 @@ func (s *StageExecutor) Execute(ctx context.Context, stage imagebuilder.Stage, b
// A helper function to only log "COMMIT" as an explicit step if it's
// the very last step of a (possibly multi-stage) build.
logCommit := func(output string, instruction int) {
- if instruction < len(children)-1 || s.index < s.stages-1 {
+ moreInstructions := instruction < len(children)-1
+ if moreInstructions || moreStages {
return
}
commitMessage := "COMMIT"
@@ -921,7 +964,7 @@ func (s *StageExecutor) Execute(ctx context.Context, stage imagebuilder.Stage, b
// squash the contents of the base image. Whichever is
// the case, we need to commit() to create a new image.
logCommit(s.output, -1)
- if imgID, ref, err = s.commit(ctx, ib, getCreatedBy(nil), s.output); err != nil {
+ if imgID, ref, err = s.commit(ctx, ib, s.executor.getCreatedBy(nil), false, s.output); err != nil {
return "", nil, errors.Wrapf(err, "error committing base container")
}
} else {
@@ -936,6 +979,8 @@ func (s *StageExecutor) Execute(ctx context.Context, stage imagebuilder.Stage, b
}
for i, node := range children {
+ moreInstructions := i < len(children)-1
+ lastInstruction := !moreInstructions
// Resolve any arguments in this instruction.
step := ib.Step()
if err := step.Resolve(node); err != nil {
@@ -946,30 +991,19 @@ func (s *StageExecutor) Execute(ctx context.Context, stage imagebuilder.Stage, b
s.executor.log("%s", step.Original)
}
- // If this instruction declares an argument, remove it from the
- // set of arguments that we were passed but which we haven't
- // yet seen used by the Dockerfile.
- if step.Command == "arg" {
- for _, Arg := range step.Args {
- list := strings.SplitN(Arg, "=", 2)
- if _, stillUnused := s.executor.unusedArgs[list[0]]; stillUnused {
- delete(s.executor.unusedArgs, list[0])
- }
- }
- }
-
// Check if there's a --from if the step command is COPY or
// ADD. Set copyFrom to point to either the context directory
// or the root of the container from the specified stage.
s.copyFrom = s.executor.contextDir
for _, n := range step.Flags {
- if strings.Contains(n, "--from") && (step.Command == "copy" || step.Command == "add") {
+ command := strings.ToUpper(step.Command)
+ if strings.Contains(n, "--from") && (command == "COPY" || command == "ADD") {
var mountPoint string
arr := strings.Split(n, "=")
otherStage, ok := s.executor.stages[arr[1]]
if !ok {
if mountPoint, err = s.getImageRootfs(ctx, stage, arr[1]); err != nil {
- return "", nil, errors.Errorf("%s --from=%s: no stage or image found with that name", step.Command, arr[1])
+ return "", nil, errors.Errorf("%s --from=%s: no stage or image found with that name", command, arr[1])
}
} else {
mountPoint = otherStage.mountPoint
@@ -984,7 +1018,7 @@ func (s *StageExecutor) Execute(ctx context.Context, stage imagebuilder.Stage, b
// contents of any volumes declared between now and when we
// finish.
noRunsRemaining := false
- if i < len(children)-1 {
+ if moreInstructions {
noRunsRemaining = !ib.RequiresStart(&parser.Node{Children: children[i+1:]})
}
@@ -996,24 +1030,29 @@ func (s *StageExecutor) Execute(ctx context.Context, stage imagebuilder.Stage, b
logrus.Debugf("%v", errors.Wrapf(err, "error building at step %+v", *step))
return "", nil, errors.Wrapf(err, "error building at STEP \"%s\"", step.Message)
}
- if i < len(children)-1 {
+ if moreInstructions {
// There are still more instructions to process
// for this stage. Make a note of the
// instruction in the history that we'll write
// for the image when we eventually commit it.
now := time.Now()
- s.builder.AddPrependedEmptyLayer(&now, getCreatedBy(node), "", "")
+ s.builder.AddPrependedEmptyLayer(&now, s.executor.getCreatedBy(node), "", "")
continue
} else {
// This is the last instruction for this stage,
// so we should commit this container to create
- // an image.
- logCommit(s.output, i)
- imgID, ref, err = s.commit(ctx, ib, getCreatedBy(node), s.output)
- if err != nil {
- return "", nil, errors.Wrapf(err, "error committing container for step %+v", *step)
+ // an image, but only if it's the last one, or
+ // if it's used as the basis for a later stage.
+ if lastStage || imageIsUsedLater {
+ logCommit(s.output, i)
+ imgID, ref, err = s.commit(ctx, ib, s.executor.getCreatedBy(node), false, s.output)
+ if err != nil {
+ return "", nil, errors.Wrapf(err, "error committing container for step %+v", *step)
+ }
+ logImageID(imgID)
+ } else {
+ imgID = ""
}
- logImageID(imgID)
break
}
}
@@ -1028,18 +1067,14 @@ func (s *StageExecutor) Execute(ctx context.Context, stage imagebuilder.Stage, b
// If we have to commit for this instruction, only assign the
// stage's configured output name to the last layer.
- if i == len(children)-1 {
+ if lastInstruction {
commitName = s.output
}
// If we're using the cache, and we've managed to stick with
// cached images so far, look for one that matches what we
// expect to produce for this instruction.
- // Only check at steps where we commit, so that we don't
- // abandon the cache at this step just because we can't find an
- // image with a history entry in it that we wouldn't have
- // committed.
- if checkForLayers && (s.stepRequiresCommit(step) || i == len(children)-1) && !(s.executor.squash && i == len(children)-1 && s.index == s.stages-1) {
+ if checkForLayers && !(s.executor.squash && lastInstruction && lastStage) {
cacheID, err = s.layerExists(ctx, node, children[:i])
if err != nil {
return "", nil, errors.Wrap(err, "error checking if cached image exists from a previous build")
@@ -1059,17 +1094,32 @@ func (s *StageExecutor) Execute(ctx context.Context, stage imagebuilder.Stage, b
// the last step in this stage, add the name to the
// image.
imgID = cacheID
- if commitName != "" && (s.stepRequiresCommit(step) || i == len(children)-1) {
- logCommit(s.output, i)
+ if commitName != "" {
+ logCommit(commitName, i)
if imgID, ref, err = s.copyExistingImage(ctx, cacheID, commitName); err != nil {
return "", nil, err
}
logImageID(imgID)
}
// Update our working container to be based off of the
- // cached image, in case we need to read content from
- // its root filesystem.
- rebase = true
+ // cached image, if we might need to use it as a basis
+ // for the next instruction, or if we need the root
+ // filesystem to match the image contents for the sake
+ // of a later stage that wants to copy content from it.
+ rebase = moreInstructions || rootfsIsUsedLater
+ // If the instruction would affect our configuration,
+ // process the configuration change so that, if we fall
+ // off the cache path, the filesystem changes from the
+ // last cache image will be all that we need, since we
+ // still don't want to restart using the image's
+ // configuration blob.
+ if !s.stepRequiresLayer(step) {
+ err := ib.Run(step, s, noRunsRemaining)
+ if err != nil {
+ logrus.Debugf("%v", errors.Wrapf(err, "error building at step %+v", *step))
+ return "", nil, errors.Wrapf(err, "error building at STEP \"%s\"", step.Message)
+ }
+ }
} else {
// If we didn't find a cached image that we could just reuse,
// process the instruction directly.
@@ -1078,36 +1128,20 @@ func (s *StageExecutor) Execute(ctx context.Context, stage imagebuilder.Stage, b
logrus.Debugf("%v", errors.Wrapf(err, "error building at step %+v", *step))
return "", nil, errors.Wrapf(err, "error building at STEP \"%s\"", step.Message)
}
- if s.stepRequiresCommit(step) || i == len(children)-1 {
- // Either this is the last instruction, or
- // there are more instructions and we need to
- // create a layer from this one before
- // continuing.
- // TODO: only commit for the last instruction
- // case if we need to use this stage's image as
- // a base image later, or if we're the final
- // stage.
- logCommit(s.output, i)
- imgID, ref, err = s.commit(ctx, ib, getCreatedBy(node), commitName)
- if err != nil {
- return "", nil, errors.Wrapf(err, "error committing container for step %+v", *step)
- }
- logImageID(imgID)
- // We only need to build a new container rootfs
- // using this image if we plan on making
- // further changes to it. Subsequent stages
- // that just want to use the rootfs as a source
- // for COPY or ADD will be content with what we
- // already have.
- rebase = i < len(children)-1
- } else {
- // There are still more instructions to process
- // for this stage, and we don't need to commit
- // here. Make a note of the instruction in the
- // history for the next commit.
- now := time.Now()
- s.builder.AddPrependedEmptyLayer(&now, getCreatedBy(node), "", "")
+ // Create a new image, maybe with a new layer.
+ logCommit(s.output, i)
+ imgID, ref, err = s.commit(ctx, ib, s.executor.getCreatedBy(node), !s.stepRequiresLayer(step), commitName)
+ if err != nil {
+ return "", nil, errors.Wrapf(err, "error committing container for step %+v", *step)
}
+ logImageID(imgID)
+ // We only need to build a new container rootfs
+ // using this image if we plan on making
+ // further changes to it. Subsequent stages
+ // that just want to use the rootfs as a source
+ // for COPY or ADD will be content with what we
+ // already have.
+ rebase = moreInstructions
}
if rebase {
@@ -1122,8 +1156,6 @@ func (s *StageExecutor) Execute(ctx context.Context, stage imagebuilder.Stage, b
// creating a new working container with the
// just-committed or updated cached image as its new
// base image.
- // TODO: only create a new container if we know that
- // we'll need the updated root filesystem.
if _, err := s.prepare(ctx, stage, imgID, false, true); err != nil {
return "", nil, errors.Wrap(err, "error preparing container for next step")
}
@@ -1195,13 +1227,13 @@ func (s *StageExecutor) layerExists(ctx context.Context, currNode *parser.Node,
// it means that this image is potentially a cached intermediate image from a previous
// build. Next we double check that the history of this image is equivalent to the previous
// lines in the Dockerfile up till the point we are at in the build.
- if layer.Parent == s.executor.topLayers[len(s.executor.topLayers)-1] {
+ if layer.Parent == s.executor.topLayers[len(s.executor.topLayers)-1] || layer.ID == s.executor.topLayers[len(s.executor.topLayers)-1] {
history, err := s.executor.getImageHistory(ctx, image.ID)
if err != nil {
return "", errors.Wrapf(err, "error getting history of %q", image.ID)
}
// children + currNode is the point of the Dockerfile we are currently at.
- if historyMatches(append(children, currNode), history) {
+ if s.executor.historyMatches(append(children, currNode), history) {
// This checks if the files copied during build have been changed if the node is
// a COPY or ADD command.
filesMatch, err := s.copiedFilesMatch(currNode, history[len(history)-1].Created)
@@ -1225,21 +1257,26 @@ func (b *Executor) getImageHistory(ctx context.Context, imageID string) ([]v1.Hi
}
ref, err := imageRef.NewImage(ctx, nil)
if err != nil {
- return nil, errors.Wrap(err, "error creating new image from reference")
+ return nil, errors.Wrapf(err, "error creating new image from reference to image %q", imageID)
}
+ defer ref.Close()
oci, err := ref.OCIConfig(ctx)
if err != nil {
- return nil, errors.Wrapf(err, "error getting oci config of image %q", imageID)
+ return nil, errors.Wrapf(err, "error getting possibly-converted OCI config of image %q", imageID)
}
return oci.History, nil
}
// getCreatedBy returns the command the image at node will be created by.
-func getCreatedBy(node *parser.Node) string {
+func (b *Executor) getCreatedBy(node *parser.Node) string {
if node == nil {
return "/bin/sh"
}
if node.Value == "run" {
+ buildArgs := b.getBuildArgs()
+ if buildArgs != "" {
+ return "|" + strconv.Itoa(len(strings.Split(buildArgs, " "))) + " " + buildArgs + " /bin/sh -c " + node.Original[4:]
+ }
return "/bin/sh -c " + node.Original[4:]
}
return "/bin/sh -c #(nop) " + node.Original
@@ -1249,12 +1286,23 @@ func getCreatedBy(node *parser.Node) string {
// in the Dockerfile till the point of build we are at.
// Used to verify whether a cache of the intermediate image exists and whether
// to run the build again.
-func historyMatches(children []*parser.Node, history []v1.History) bool {
+func (b *Executor) historyMatches(children []*parser.Node, history []v1.History) bool {
i := len(history) - 1
for j := len(children) - 1; j >= 0; j-- {
instruction := children[j].Original
if children[j].Value == "run" {
instruction = instruction[4:]
+ buildArgs := b.getBuildArgs()
+ // If a previous image was built with some build-args but the new build process doesn't have any build-args
+ // specified, so compare the lengths of the old instruction with the current one
+ // 11 is the length of "/bin/sh -c " that is used to run the run commands
+ if buildArgs == "" && len(history[i].CreatedBy) > len(instruction)+11 {
+ return false
+ }
+ // There are build-args, so check if anything with the build-args has changed
+ if buildArgs != "" && !strings.Contains(history[i].CreatedBy, buildArgs) {
+ return false
+ }
}
if !strings.Contains(history[i].CreatedBy, instruction) {
return false
@@ -1264,6 +1312,18 @@ func historyMatches(children []*parser.Node, history []v1.History) bool {
return true
}
+// getBuildArgs returns a string of the build-args specified during the build process
+// it excludes any build-args that were not used in the build process
+func (b *Executor) getBuildArgs() string {
+ var buildArgs []string
+ for k, v := range b.buildArgs {
+ if _, ok := b.unusedArgs[k]; !ok {
+ buildArgs = append(buildArgs, k+"="+v)
+ }
+ }
+ return strings.Join(buildArgs, " ")
+}
+
// getFilesToCopy goes through node to get all the src files that are copied, added or downloaded.
// It is possible for the Dockerfile to have src as hom*, which means all files that have hom as a prefix.
// Another format is hom?.txt, which means all files that have that name format with the ? replaced by another character.
@@ -1348,7 +1408,7 @@ func urlContentModified(url string, historyTime *time.Time) (bool, error) {
// commit writes the container's contents to an image, using a passed-in tag as
// the name if there is one, generating a unique ID-based one otherwise.
-func (s *StageExecutor) commit(ctx context.Context, ib *imagebuilder.Builder, createdBy, output string) (string, reference.Canonical, error) {
+func (s *StageExecutor) commit(ctx context.Context, ib *imagebuilder.Builder, createdBy string, emptyLayer bool, output string) (string, reference.Canonical, error) {
var imageRef types.ImageReference
if output != "" {
imageRef2, err := s.executor.resolveNameToImageRef(output)
@@ -1438,8 +1498,8 @@ func (s *StageExecutor) commit(ctx context.Context, ib *imagebuilder.Builder, cr
PreferredManifestType: s.executor.outputFormat,
SystemContext: s.executor.systemContext,
Squash: s.executor.squash,
+ EmptyLayer: emptyLayer,
BlobDirectory: s.executor.blobDirectory,
- Parent: s.builder.FromImageID,
}
imgID, _, manifestDigest, err := s.builder.Commit(ctx, imageRef, options)
if err != nil {
@@ -1510,6 +1570,46 @@ func (b *Executor) Build(ctx context.Context, stages imagebuilder.Stages) (image
}
defer cleanup()
+ // Build maps of every named base image and every referenced stage root
+ // filesystem. Individual stages can use them to determine whether or
+ // not they can skip certain steps near the end of their stages.
+ for _, stage := range stages {
+ node := stage.Node // first line
+ for node != nil { // each line
+ for _, child := range node.Children { // tokens on this line, though we only care about the first
+ switch strings.ToUpper(child.Value) { // first token - instruction
+ case "FROM":
+ if child.Next != nil { // second token on this line
+ base := child.Next.Value
+ if base != "scratch" {
+ // TODO: this didn't undergo variable and arg
+ // expansion, so if the AS clause in another
+ // FROM instruction uses argument values,
+ // we might not record the right value here.
+ b.baseMap[base] = true
+ logrus.Debugf("base: %q", base)
+ }
+ }
+ case "ADD", "COPY":
+ for _, flag := range child.Flags { // flags for this instruction
+ if strings.HasPrefix(flag, "--from=") {
+ // TODO: this didn't undergo variable and
+ // arg expansion, so if the previous stage
+ // was named using argument values, we might
+ // not record the right value here.
+ rootfs := flag[7:]
+ b.rootfsMap[rootfs] = true
+ logrus.Debugf("rootfs: %q", rootfs)
+ }
+ }
+ }
+ break
+ }
+ node = node.Next // next line
+ }
+ }
+
+ // Run through the build stages, one at a time.
for stageIndex, stage := range stages {
var lastErr error
@@ -1555,7 +1655,7 @@ func (b *Executor) Build(ctx context.Context, stages imagebuilder.Stages) (image
// If this is an intermediate stage, make a note of the ID, so
// that we can look it up later.
- if stageIndex < len(stages)-1 {
+ if stageIndex < len(stages)-1 && imageID != "" {
b.imageMap[stage.Name] = imageID
// We're not populating the cache with intermediate
// images, so add this one to the list of images that
@@ -1671,7 +1771,7 @@ func BuildDockerfiles(ctx context.Context, store storage.Store, options BuildOpt
}
mainNode.Children = append(mainNode.Children, additionalNode.Children...)
}
- exec, err := NewExecutor(store, options)
+ exec, err := NewExecutor(store, options, mainNode)
if err != nil {
return "", nil, errors.Wrapf(err, "error creating build executor")
}
diff --git a/vendor/github.com/containers/buildah/imagebuildah/chroot_symlink.go b/vendor/github.com/containers/buildah/imagebuildah/chroot_symlink.go
index 86bf7653b..0789c2b3c 100644
--- a/vendor/github.com/containers/buildah/imagebuildah/chroot_symlink.go
+++ b/vendor/github.com/containers/buildah/imagebuildah/chroot_symlink.go
@@ -129,20 +129,20 @@ func resolveModifiedTime(rootdir, filename, historyTime string) (bool, error) {
func modTimeIsGreater(rootdir, path string, historyTime string) (bool, error) {
var timeIsGreater bool
- // the Walk below doesn't work if rootdir and path are equal
- if rootdir == path {
- return false, nil
- }
-
// 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)
}
+
+ // Since we are chroot in rootdir, we want a relative path, i.e (path - rootdir)
+ relPath, err := filepath.Rel(rootdir, path)
+ if err != nil {
+ return false, errors.Wrapf(err, "error making path %q relative to %q", path, rootdir)
+ }
+
// 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 {
+ err = filepath.Walk(relPath, func(path string, info os.FileInfo, err error) error {
// If using cached images, it is possible for files that are being copied to come from
// previous build stages. But if using cached images, then the copied file won't exist
// since a container won't have been created for the previous build stage and info will be nil.
@@ -154,6 +154,9 @@ func modTimeIsGreater(rootdir, path string, historyTime string) (bool, error) {
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 && os.IsNotExist(err) {
+ return errors.Wrapf(errDanglingSymlink, "%q", path)
+ }
if err != nil {
return errors.Wrapf(err, "error evaluating symlink %q", path)
}
@@ -169,7 +172,12 @@ func modTimeIsGreater(rootdir, path string, historyTime string) (bool, error) {
}
return nil
})
+
if err != nil {
+ // if error is due to dangling symlink, ignore error and return nil
+ if errors.Cause(err) == errDanglingSymlink {
+ return false, nil
+ }
return false, errors.Wrapf(err, "error walking file tree %q", path)
}
return timeIsGreater, err
diff --git a/vendor/github.com/containers/buildah/imagebuildah/errors.go b/vendor/github.com/containers/buildah/imagebuildah/errors.go
new file mode 100644
index 000000000..cf299656b
--- /dev/null
+++ b/vendor/github.com/containers/buildah/imagebuildah/errors.go
@@ -0,0 +1,7 @@
+package imagebuildah
+
+import "errors"
+
+var (
+ errDanglingSymlink = errors.New("error evaluating dangling symlink")
+)
diff --git a/vendor/github.com/containers/buildah/pkg/cli/common.go b/vendor/github.com/containers/buildah/pkg/cli/common.go
index 6c4d14303..7fa0a7777 100644
--- a/vendor/github.com/containers/buildah/pkg/cli/common.go
+++ b/vendor/github.com/containers/buildah/pkg/cli/common.go
@@ -89,6 +89,7 @@ type FromAndBudResults struct {
DNSSearch []string
DNSServers []string
DNSOptions []string
+ HttpProxy bool
Isolation string
Memory string
MemorySwap string
@@ -182,6 +183,7 @@ func GetFromAndBudFlags(flags *FromAndBudResults, usernsResults *UserNSResults,
fs.StringSliceVar(&flags.DNSSearch, "dns-search", []string{}, "Set custom DNS search domains")
fs.StringSliceVar(&flags.DNSServers, "dns", []string{}, "Set custom DNS servers")
fs.StringSliceVar(&flags.DNSOptions, "dns-option", []string{}, "Set custom DNS options")
+ fs.BoolVar(&flags.HttpProxy, "http-proxy", true, "pass thru HTTP Proxy environment variables")
fs.StringVar(&flags.Isolation, "isolation", DefaultIsolation(), "`type` of process isolation to use. Use BUILDAH_ISOLATION environment variable to override.")
fs.StringVarP(&flags.Memory, "memory", "m", "", "memory limit (format: <number>[<unit>], where unit = b, k, m or g)")
fs.StringVar(&flags.MemorySwap, "memory-swap", "", "swap limit equal to memory plus swap: '-1' to enable unlimited swap")
diff --git a/vendor/github.com/containers/buildah/pkg/parse/parse.go b/vendor/github.com/containers/buildah/pkg/parse/parse.go
index c4e3e4264..cc85136fd 100644
--- a/vendor/github.com/containers/buildah/pkg/parse/parse.go
+++ b/vendor/github.com/containers/buildah/pkg/parse/parse.go
@@ -86,6 +86,7 @@ func CommonBuildOptions(c *cobra.Command) (*buildah.CommonBuildOptions, error) {
cpuPeriod, _ := c.Flags().GetUint64("cpu-period")
cpuQuota, _ := c.Flags().GetInt64("cpu-quota")
cpuShares, _ := c.Flags().GetUint64("cpu-shared")
+ httpProxy, _ := c.Flags().GetBool("http-proxy")
ulimit, _ := c.Flags().GetStringSlice("ulimit")
commonOpts := &buildah.CommonBuildOptions{
AddHost: addHost,
@@ -98,6 +99,7 @@ func CommonBuildOptions(c *cobra.Command) (*buildah.CommonBuildOptions, error) {
DNSSearch: dnsSearch,
DNSServers: dnsServers,
DNSOptions: dnsOptions,
+ HTTPProxy: httpProxy,
Memory: memoryLimit,
MemorySwap: memorySwap,
ShmSize: c.Flag("shm-size").Value.String(),
diff --git a/vendor/github.com/containers/buildah/pkg/unshare/unshare.go b/vendor/github.com/containers/buildah/pkg/unshare/unshare.go
index 5b2e7d7d1..33232740e 100644
--- a/vendor/github.com/containers/buildah/pkg/unshare/unshare.go
+++ b/vendor/github.com/containers/buildah/pkg/unshare/unshare.go
@@ -3,6 +3,7 @@
package unshare
import (
+ "bufio"
"bytes"
"fmt"
"io"
@@ -15,7 +16,7 @@ import (
"sync"
"syscall"
- "github.com/containers/buildah/util"
+ "github.com/containers/storage/pkg/idtools"
"github.com/containers/storage/pkg/reexec"
"github.com/opencontainers/runtime-spec/specs-go"
"github.com/pkg/errors"
@@ -157,7 +158,7 @@ func (c *Cmd) Start() error {
}
if len(c.UidMappings) == 0 || len(c.GidMappings) == 0 {
- uidmap, gidmap, err := util.GetHostIDMappings("")
+ uidmap, gidmap, err := GetHostIDMappings("")
if err != nil {
fmt.Fprintf(continueWrite, "error reading ID mappings in parent: %v", err)
return errors.Wrapf(err, "error reading ID mappings in parent")
@@ -352,7 +353,7 @@ func MaybeReexecUsingUserNamespace(evenForRoot bool) {
// Read the set of ID mappings that we're allowed to use. Each
// range in /etc/subuid and /etc/subgid file is a starting host
// ID and a range size.
- uidmap, gidmap, err = util.GetSubIDMappings(me.Username, me.Username)
+ uidmap, gidmap, err = GetSubIDMappings(me.Username, me.Username)
bailOnError(err, "error reading allowed ID mappings")
if len(uidmap) == 0 {
logrus.Warnf("Found no UID ranges set aside for user %q in /etc/subuid.", me.Username)
@@ -384,7 +385,7 @@ func MaybeReexecUsingUserNamespace(evenForRoot bool) {
return
}
// Read the set of ID mappings that we're currently using.
- uidmap, gidmap, err = util.GetHostIDMappings("")
+ uidmap, gidmap, err = GetHostIDMappings("")
bailOnError(err, "error reading current ID mappings")
// Just reuse them.
for i := range uidmap {
@@ -404,6 +405,16 @@ func MaybeReexecUsingUserNamespace(evenForRoot bool) {
err = os.Setenv(UsernsEnvName, "1")
bailOnError(err, "error setting %s=1 in environment", UsernsEnvName)
+ // Set the default isolation type to use the "rootless" method.
+ if _, present := os.LookupEnv("BUILDAH_ISOLATION"); !present {
+ if err = os.Setenv("BUILDAH_ISOLATION", "rootless"); err != nil {
+ if err := os.Setenv("BUILDAH_ISOLATION", "rootless"); err != nil {
+ logrus.Errorf("error setting BUILDAH_ISOLATION=rootless in environment: %v", err)
+ os.Exit(1)
+ }
+ }
+ }
+
// Reuse our stdio.
cmd.Stdin = os.Stdin
cmd.Stdout = os.Stdout
@@ -446,3 +457,89 @@ func ExecRunnable(cmd Runnable) {
}
os.Exit(0)
}
+
+// getHostIDMappings reads mappings from the named node under /proc.
+func getHostIDMappings(path string) ([]specs.LinuxIDMapping, error) {
+ var mappings []specs.LinuxIDMapping
+ f, err := os.Open(path)
+ if err != nil {
+ return nil, errors.Wrapf(err, "error reading ID mappings from %q", path)
+ }
+ defer f.Close()
+ scanner := bufio.NewScanner(f)
+ for scanner.Scan() {
+ line := scanner.Text()
+ fields := strings.Fields(line)
+ if len(fields) != 3 {
+ return nil, errors.Errorf("line %q from %q has %d fields, not 3", line, path, len(fields))
+ }
+ cid, err := strconv.ParseUint(fields[0], 10, 32)
+ if err != nil {
+ return nil, errors.Wrapf(err, "error parsing container ID value %q from line %q in %q", fields[0], line, path)
+ }
+ hid, err := strconv.ParseUint(fields[1], 10, 32)
+ if err != nil {
+ return nil, errors.Wrapf(err, "error parsing host ID value %q from line %q in %q", fields[1], line, path)
+ }
+ size, err := strconv.ParseUint(fields[2], 10, 32)
+ if err != nil {
+ return nil, errors.Wrapf(err, "error parsing size value %q from line %q in %q", fields[2], line, path)
+ }
+ mappings = append(mappings, specs.LinuxIDMapping{ContainerID: uint32(cid), HostID: uint32(hid), Size: uint32(size)})
+ }
+ return mappings, nil
+}
+
+// GetHostIDMappings reads mappings for the specified process (or the current
+// process if pid is "self" or an empty string) from the kernel.
+func GetHostIDMappings(pid string) ([]specs.LinuxIDMapping, []specs.LinuxIDMapping, error) {
+ if pid == "" {
+ pid = "self"
+ }
+ uidmap, err := getHostIDMappings(fmt.Sprintf("/proc/%s/uid_map", pid))
+ if err != nil {
+ return nil, nil, err
+ }
+ gidmap, err := getHostIDMappings(fmt.Sprintf("/proc/%s/gid_map", pid))
+ if err != nil {
+ return nil, nil, err
+ }
+ return uidmap, gidmap, nil
+}
+
+// GetSubIDMappings reads mappings from /etc/subuid and /etc/subgid.
+func GetSubIDMappings(user, group string) ([]specs.LinuxIDMapping, []specs.LinuxIDMapping, error) {
+ mappings, err := idtools.NewIDMappings(user, group)
+ if err != nil {
+ return nil, nil, errors.Wrapf(err, "error reading subuid mappings for user %q and subgid mappings for group %q", user, group)
+ }
+ var uidmap, gidmap []specs.LinuxIDMapping
+ for _, m := range mappings.UIDs() {
+ uidmap = append(uidmap, specs.LinuxIDMapping{
+ ContainerID: uint32(m.ContainerID),
+ HostID: uint32(m.HostID),
+ Size: uint32(m.Size),
+ })
+ }
+ for _, m := range mappings.GIDs() {
+ gidmap = append(gidmap, specs.LinuxIDMapping{
+ ContainerID: uint32(m.ContainerID),
+ HostID: uint32(m.HostID),
+ Size: uint32(m.Size),
+ })
+ }
+ return uidmap, gidmap, nil
+}
+
+// ParseIDMappings parses mapping triples.
+func ParseIDMappings(uidmap, gidmap []string) ([]idtools.IDMap, []idtools.IDMap, error) {
+ uid, err := idtools.ParseIDMap(uidmap, "userns-uid-map")
+ if err != nil {
+ return nil, nil, err
+ }
+ gid, err := idtools.ParseIDMap(gidmap, "userns-gid-map")
+ if err != nil {
+ return nil, nil, err
+ }
+ return uid, gid, nil
+}
diff --git a/vendor/github.com/containers/buildah/pkg/unshare/unshare_unsupported.go b/vendor/github.com/containers/buildah/pkg/unshare/unshare_unsupported.go
index d8d5f6f7a..bf4d567b8 100644
--- a/vendor/github.com/containers/buildah/pkg/unshare/unshare_unsupported.go
+++ b/vendor/github.com/containers/buildah/pkg/unshare/unshare_unsupported.go
@@ -4,6 +4,9 @@ package unshare
import (
"os"
+
+ "github.com/containers/storage/pkg/idtools"
+ "github.com/opencontainers/runtime-spec/specs-go"
)
const (
@@ -29,3 +32,14 @@ func RootlessEnv() []string {
// MaybeReexecUsingUserNamespace re-exec the process in a new namespace
func MaybeReexecUsingUserNamespace(evenForRoot bool) {
}
+
+// GetHostIDMappings reads mappings for the specified process (or the current
+// process if pid is "self" or an empty string) from the kernel.
+func GetHostIDMappings(pid string) ([]specs.LinuxIDMapping, []specs.LinuxIDMapping, error) {
+ return nil, nil, nil
+}
+
+// ParseIDMappings parses mapping triples.
+func ParseIDMappings(uidmap, gidmap []string) ([]idtools.IDMap, []idtools.IDMap, error) {
+ return nil, nil, nil
+}
diff --git a/vendor/github.com/containers/buildah/run.go b/vendor/github.com/containers/buildah/run.go
index 5d28644d7..00eac8e39 100644
--- a/vendor/github.com/containers/buildah/run.go
+++ b/vendor/github.com/containers/buildah/run.go
@@ -865,7 +865,7 @@ func setupNamespaces(g *generate.Generator, namespaceOptions NamespaceOptions, i
if err := g.AddOrReplaceLinuxNamespace(specs.UserNamespace, ""); err != nil {
return false, nil, false, errors.Wrapf(err, "error adding new %q namespace for run", string(specs.UserNamespace))
}
- hostUidmap, hostGidmap, err := util.GetHostIDMappings("")
+ hostUidmap, hostGidmap, err := unshare.GetHostIDMappings("")
if err != nil {
return false, nil, false, err
}
@@ -983,6 +983,24 @@ func (b *Builder) configureUIDGID(g *generate.Generator, mountPoint string, opti
func (b *Builder) configureEnvironment(g *generate.Generator, options RunOptions) {
g.ClearProcessEnv()
+ if b.CommonBuildOpts.HTTPProxy {
+ for _, envSpec := range []string{
+ "http_proxy",
+ "HTTP_PROXY",
+ "https_proxy",
+ "HTTPS_PROXY",
+ "ftp_proxy",
+ "FTP_PROXY",
+ "no_proxy",
+ "NO_PROXY",
+ } {
+ envVal := os.Getenv(envSpec)
+ if envVal != "" {
+ g.AddProcessEnv(envSpec, envVal)
+ }
+ }
+ }
+
for _, envSpec := range append(b.Env(), options.Env...) {
env := strings.SplitN(envSpec, "=", 2)
if len(env) > 1 {
diff --git a/vendor/github.com/containers/buildah/selinux.go b/vendor/github.com/containers/buildah/selinux.go
index 2b850cf9f..e64eb6112 100644
--- a/vendor/github.com/containers/buildah/selinux.go
+++ b/vendor/github.com/containers/buildah/selinux.go
@@ -4,9 +4,12 @@ package buildah
import (
"github.com/opencontainers/runtime-tools/generate"
+ selinux "github.com/opencontainers/selinux/go-selinux"
)
func setupSelinux(g *generate.Generator, processLabel, mountLabel string) {
- g.SetProcessSelinuxLabel(processLabel)
- g.SetLinuxMountLabel(mountLabel)
+ if processLabel != "" && selinux.GetEnabled() {
+ g.SetProcessSelinuxLabel(processLabel)
+ g.SetLinuxMountLabel(mountLabel)
+ }
}
diff --git a/vendor/github.com/containers/buildah/util/util.go b/vendor/github.com/containers/buildah/util/util.go
index 7f3bbaef4..698d79a81 100644
--- a/vendor/github.com/containers/buildah/util/util.go
+++ b/vendor/github.com/containers/buildah/util/util.go
@@ -1,13 +1,11 @@
package util
import (
- "bufio"
"fmt"
"io"
"net/url"
"os"
"path"
- "strconv"
"strings"
"syscall"
@@ -18,7 +16,6 @@ import (
"github.com/containers/image/transports"
"github.com/containers/image/types"
"github.com/containers/storage"
- "github.com/containers/storage/pkg/idtools"
"github.com/docker/distribution/registry/api/errcode"
specs "github.com/opencontainers/runtime-spec/specs-go"
"github.com/pkg/errors"
@@ -299,92 +296,6 @@ func GetHostRootIDs(spec *specs.Spec) (uint32, uint32, error) {
return GetHostIDs(spec.Linux.UIDMappings, spec.Linux.GIDMappings, 0, 0)
}
-// getHostIDMappings reads mappings from the named node under /proc.
-func getHostIDMappings(path string) ([]specs.LinuxIDMapping, error) {
- var mappings []specs.LinuxIDMapping
- f, err := os.Open(path)
- if err != nil {
- return nil, errors.Wrapf(err, "error reading ID mappings from %q", path)
- }
- defer f.Close()
- scanner := bufio.NewScanner(f)
- for scanner.Scan() {
- line := scanner.Text()
- fields := strings.Fields(line)
- if len(fields) != 3 {
- return nil, errors.Errorf("line %q from %q has %d fields, not 3", line, path, len(fields))
- }
- cid, err := strconv.ParseUint(fields[0], 10, 32)
- if err != nil {
- return nil, errors.Wrapf(err, "error parsing container ID value %q from line %q in %q", fields[0], line, path)
- }
- hid, err := strconv.ParseUint(fields[1], 10, 32)
- if err != nil {
- return nil, errors.Wrapf(err, "error parsing host ID value %q from line %q in %q", fields[1], line, path)
- }
- size, err := strconv.ParseUint(fields[2], 10, 32)
- if err != nil {
- return nil, errors.Wrapf(err, "error parsing size value %q from line %q in %q", fields[2], line, path)
- }
- mappings = append(mappings, specs.LinuxIDMapping{ContainerID: uint32(cid), HostID: uint32(hid), Size: uint32(size)})
- }
- return mappings, nil
-}
-
-// GetHostIDMappings reads mappings for the specified process (or the current
-// process if pid is "self" or an empty string) from the kernel.
-func GetHostIDMappings(pid string) ([]specs.LinuxIDMapping, []specs.LinuxIDMapping, error) {
- if pid == "" {
- pid = "self"
- }
- uidmap, err := getHostIDMappings(fmt.Sprintf("/proc/%s/uid_map", pid))
- if err != nil {
- return nil, nil, err
- }
- gidmap, err := getHostIDMappings(fmt.Sprintf("/proc/%s/gid_map", pid))
- if err != nil {
- return nil, nil, err
- }
- return uidmap, gidmap, nil
-}
-
-// GetSubIDMappings reads mappings from /etc/subuid and /etc/subgid.
-func GetSubIDMappings(user, group string) ([]specs.LinuxIDMapping, []specs.LinuxIDMapping, error) {
- mappings, err := idtools.NewIDMappings(user, group)
- if err != nil {
- return nil, nil, errors.Wrapf(err, "error reading subuid mappings for user %q and subgid mappings for group %q", user, group)
- }
- var uidmap, gidmap []specs.LinuxIDMapping
- for _, m := range mappings.UIDs() {
- uidmap = append(uidmap, specs.LinuxIDMapping{
- ContainerID: uint32(m.ContainerID),
- HostID: uint32(m.HostID),
- Size: uint32(m.Size),
- })
- }
- for _, m := range mappings.GIDs() {
- gidmap = append(gidmap, specs.LinuxIDMapping{
- ContainerID: uint32(m.ContainerID),
- HostID: uint32(m.HostID),
- Size: uint32(m.Size),
- })
- }
- return uidmap, gidmap, nil
-}
-
-// ParseIDMappings parses mapping triples.
-func ParseIDMappings(uidmap, gidmap []string) ([]idtools.IDMap, []idtools.IDMap, error) {
- uid, err := idtools.ParseIDMap(uidmap, "userns-uid-map")
- if err != nil {
- return nil, nil, err
- }
- gid, err := idtools.ParseIDMap(gidmap, "userns-gid-map")
- if err != nil {
- return nil, nil, err
- }
- return uid, gid, nil
-}
-
// GetPolicyContext sets up, initializes and returns a new context for the specified policy
func GetPolicyContext(ctx *types.SystemContext) (*signature.PolicyContext, error) {
policy, err := signature.DefaultPolicy(ctx)
diff --git a/vendor/github.com/containers/buildah/vendor.conf b/vendor/github.com/containers/buildah/vendor.conf
index a77130acb..bec681e5c 100644
--- a/vendor/github.com/containers/buildah/vendor.conf
+++ b/vendor/github.com/containers/buildah/vendor.conf
@@ -8,7 +8,7 @@ github.com/vbauerster/mpb v3.3.4
github.com/mattn/go-isatty v0.0.4
github.com/VividCortex/ewma v1.1.1
github.com/boltdb/bolt v1.3.1
-github.com/containers/storage v1.12.2
+github.com/containers/storage v1.12.3
github.com/docker/distribution 5f6282db7d65e6d72ad7c2cc66310724a57be716
github.com/docker/docker 54dddadc7d5d89fe0be88f76979f6f6ab0dede83
github.com/docker/docker-credential-helpers v0.6.1
diff --git a/vendor/github.com/containers/psgo/go.mod b/vendor/github.com/containers/psgo/go.mod
new file mode 100644
index 000000000..dd671bbb0
--- /dev/null
+++ b/vendor/github.com/containers/psgo/go.mod
@@ -0,0 +1,11 @@
+module github.com/containers/psgo
+
+go 1.12
+
+require (
+ github.com/opencontainers/runc v0.0.0-20190425234816-dae70e8efea4
+ github.com/pkg/errors v0.0.0-20190227000051-27936f6d90f9
+ github.com/sirupsen/logrus v0.0.0-20190403091019-9b3cdde74fbe
+ github.com/stretchr/testify v1.2.2
+ golang.org/x/sys v0.0.0-20190425145619-16072639606e
+)
diff --git a/vendor/github.com/containers/storage/drivers/overlay/overlay.go b/vendor/github.com/containers/storage/drivers/overlay/overlay.go
index 69036a5c1..5d667d8c6 100644
--- a/vendor/github.com/containers/storage/drivers/overlay/overlay.go
+++ b/vendor/github.com/containers/storage/drivers/overlay/overlay.go
@@ -16,7 +16,7 @@ import (
"sync"
"syscall"
- "github.com/containers/storage/drivers"
+ graphdriver "github.com/containers/storage/drivers"
"github.com/containers/storage/drivers/overlayutils"
"github.com/containers/storage/drivers/quota"
"github.com/containers/storage/pkg/archive"
@@ -320,6 +320,8 @@ func supportsOverlay(home string, homeMagic graphdriver.FsMagic, rootUID, rootGI
mergedDir := filepath.Join(layerDir, "merged")
lower1Dir := filepath.Join(layerDir, "lower1")
lower2Dir := filepath.Join(layerDir, "lower2")
+ upperDir := filepath.Join(layerDir, "upper")
+ workDir := filepath.Join(layerDir, "work")
defer func() {
// Permitted to fail, since the various subdirectories
// can be empty or not even there, and the home might
@@ -331,7 +333,9 @@ func supportsOverlay(home string, homeMagic graphdriver.FsMagic, rootUID, rootGI
_ = idtools.MkdirAs(mergedDir, 0700, rootUID, rootGID)
_ = idtools.MkdirAs(lower1Dir, 0700, rootUID, rootGID)
_ = idtools.MkdirAs(lower2Dir, 0700, rootUID, rootGID)
- flags := fmt.Sprintf("lowerdir=%s:%s", lower1Dir, lower2Dir)
+ _ = idtools.MkdirAs(upperDir, 0700, rootUID, rootGID)
+ _ = idtools.MkdirAs(workDir, 0700, rootUID, rootGID)
+ flags := fmt.Sprintf("lowerdir=%s:%s,upperdir=%s,workdir=%s", lower1Dir, lower2Dir, upperDir, workDir)
if len(flags) < unix.Getpagesize() {
err := mountFrom(filepath.Dir(home), "overlay", mergedDir, "overlay", 0, flags)
if err == nil {
@@ -341,7 +345,7 @@ func supportsOverlay(home string, homeMagic graphdriver.FsMagic, rootUID, rootGI
logrus.Debugf("overlay test mount with multiple lowers failed %v", err)
}
}
- flags = fmt.Sprintf("lowerdir=%s", lower1Dir)
+ flags = fmt.Sprintf("lowerdir=%s,upperdir=%s,workdir=%s", lower1Dir, upperDir, workDir)
if len(flags) < unix.Getpagesize() {
err := mountFrom(filepath.Dir(home), "overlay", mergedDir, "overlay", 0, flags)
if err == nil {
@@ -677,6 +681,40 @@ func (d *Driver) Remove(id string) error {
return nil
}
+// recreateSymlinks goes through the driver's home directory and checks if the diff directory
+// under each layer has a symlink created for it under the linkDir. If the symlink does not
+// exist, it creates them
+func (d *Driver) recreateSymlinks() error {
+ // List all the directories under the home directory
+ dirs, err := ioutil.ReadDir(d.home)
+ if err != nil {
+ return fmt.Errorf("error reading driver home directory %q: %v", d.home, err)
+ }
+ for _, dir := range dirs {
+ // Skip over the linkDir
+ if dir.Name() == linkDir || dir.Mode().IsRegular() {
+ continue
+ }
+ // Read the "link" file under each layer to get the name of the symlink
+ data, err := ioutil.ReadFile(path.Join(d.dir(dir.Name()), "link"))
+ if err != nil {
+ return fmt.Errorf("error reading name of symlink for %q: %v", dir, err)
+ }
+ linkPath := path.Join(d.home, linkDir, strings.Trim(string(data), "\n"))
+ // Check if the symlink exists, and if it doesn't create it again with the name we
+ // got from the "link" file
+ _, err = os.Stat(linkPath)
+ if err != nil && os.IsNotExist(err) {
+ if err := os.Symlink(path.Join("..", dir.Name(), "diff"), linkPath); err != nil {
+ return err
+ }
+ } else if err != nil {
+ return fmt.Errorf("error trying to stat %q: %v", linkPath, err)
+ }
+ }
+ return nil
+}
+
// Get creates and mounts the required file system for the given id and returns the mount path.
func (d *Driver) Get(id string, options graphdriver.MountOpts) (_ string, retErr error) {
return d.get(id, false, options)
@@ -732,7 +770,16 @@ func (d *Driver) get(id string, disableShifting bool, options graphdriver.MountO
}
lower = ""
}
- if lower == "" {
+ // if it is a "not found" error, that means the symlinks were lost in a sudden reboot
+ // so call the recreateSymlinks function to go through all the layer dirs and recreate
+ // the symlinks with the name from their respective "link" files
+ if lower == "" && os.IsNotExist(err) {
+ logrus.Warnf("Can't stat lower layer %q because it does not exist. Going through storage to recreate the missing symlinks.", newpath)
+ if err := d.recreateSymlinks(); err != nil {
+ return "", fmt.Errorf("error recreating the missing symlinks: %v", err)
+ }
+ lower = newpath
+ } else if lower == "" {
return "", fmt.Errorf("Can't stat lower layer %q: %v", newpath, err)
}
} else {
diff --git a/vendor/github.com/fsouza/go-dockerclient/go.mod b/vendor/github.com/fsouza/go-dockerclient/go.mod
new file mode 100644
index 000000000..bcf549c21
--- /dev/null
+++ b/vendor/github.com/fsouza/go-dockerclient/go.mod
@@ -0,0 +1,42 @@
+module github.com/fsouza/go-dockerclient
+
+require (
+ github.com/Azure/go-ansiterm v0.0.0-20170929234023-d6e3b3328b78
+ github.com/Microsoft/go-winio v0.4.11
+ github.com/Nvveen/Gotty v0.0.0-20120604004816-cd527374f1e5
+ github.com/containerd/continuity v0.0.0-20180814194400-c7c5070e6f6e // indirect
+ github.com/davecgh/go-spew v1.1.1 // indirect
+ github.com/docker/docker v0.7.3-0.20180827131323-0c5f8d2b9b23
+ github.com/docker/go-connections v0.4.0 // indirect
+ github.com/docker/go-units v0.3.3
+ github.com/docker/libnetwork v0.8.0-dev.2.0.20180608203834-19279f049241 // indirect
+ github.com/fsnotify/fsnotify v1.4.7 // indirect
+ github.com/gogo/protobuf v1.1.1 // indirect
+ github.com/golang/protobuf v1.2.0 // indirect
+ github.com/google/go-cmp v0.2.0
+ github.com/gorilla/context v1.1.1 // indirect
+ github.com/gorilla/mux v1.6.2
+ github.com/hpcloud/tail v1.0.0 // indirect
+ github.com/onsi/ginkgo v1.6.0 // indirect
+ github.com/onsi/gomega v1.4.1 // indirect
+ github.com/opencontainers/go-digest v1.0.0-rc1 // indirect
+ github.com/opencontainers/image-spec v1.0.1 // indirect
+ github.com/opencontainers/runc v0.1.1 // indirect
+ github.com/pkg/errors v0.8.0 // indirect
+ github.com/pmezard/go-difflib v1.0.0 // indirect
+ github.com/sirupsen/logrus v1.0.6
+ github.com/stretchr/testify v1.2.2 // indirect
+ github.com/vishvananda/netlink v1.0.0 // indirect
+ github.com/vishvananda/netns v0.0.0-20180720170159-13995c7128cc // indirect
+ golang.org/x/crypto v0.0.0-20180820150726-614d502a4dac // indirect
+ golang.org/x/net v0.0.0-20180826012351-8a410e7b638d // indirect
+ golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f // indirect
+ golang.org/x/sys v0.0.0-20180824143301-4910a1d54f87
+ golang.org/x/text v0.3.0 // indirect
+ gopkg.in/airbrake/gobrake.v2 v2.0.9 // indirect
+ gopkg.in/fsnotify.v1 v1.4.7 // indirect
+ gopkg.in/gemnasium/logrus-airbrake-hook.v2 v2.1.2 // indirect
+ gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 // indirect
+ gopkg.in/yaml.v2 v2.2.1 // indirect
+ gotest.tools v2.1.0+incompatible // indirect
+)
diff --git a/vendor/github.com/hashicorp/errwrap/go.mod b/vendor/github.com/hashicorp/errwrap/go.mod
new file mode 100644
index 000000000..c9b84022c
--- /dev/null
+++ b/vendor/github.com/hashicorp/errwrap/go.mod
@@ -0,0 +1 @@
+module github.com/hashicorp/errwrap
diff --git a/vendor/github.com/hashicorp/go-multierror/go.mod b/vendor/github.com/hashicorp/go-multierror/go.mod
new file mode 100644
index 000000000..2534331d5
--- /dev/null
+++ b/vendor/github.com/hashicorp/go-multierror/go.mod
@@ -0,0 +1,3 @@
+module github.com/hashicorp/go-multierror
+
+require github.com/hashicorp/errwrap v1.0.0
diff --git a/vendor/github.com/stretchr/testify/go.mod b/vendor/github.com/stretchr/testify/go.mod
new file mode 100644
index 000000000..90e5dbe25
--- /dev/null
+++ b/vendor/github.com/stretchr/testify/go.mod
@@ -0,0 +1,7 @@
+module github.com/stretchr/testify
+
+require (
+ github.com/davecgh/go-spew v1.1.0
+ github.com/pmezard/go-difflib v1.0.0
+ github.com/stretchr/objx v0.1.0
+)
diff --git a/vendor/golang.org/x/text/go.mod b/vendor/golang.org/x/text/go.mod
new file mode 100644
index 000000000..5eb1e8b16
--- /dev/null
+++ b/vendor/golang.org/x/text/go.mod
@@ -0,0 +1,3 @@
+module golang.org/x/text
+
+require golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e
diff --git a/vendor/gopkg.in/yaml.v2/go.mod b/vendor/gopkg.in/yaml.v2/go.mod
new file mode 100644
index 000000000..1934e8769
--- /dev/null
+++ b/vendor/gopkg.in/yaml.v2/go.mod
@@ -0,0 +1,5 @@
+module "gopkg.in/yaml.v2"
+
+require (
+ "gopkg.in/check.v1" v0.0.0-20161208181325-20d25e280405
+)