aboutsummaryrefslogtreecommitdiff
path: root/pkg
diff options
context:
space:
mode:
Diffstat (limited to 'pkg')
-rw-r--r--pkg/api/handlers/libpod/images.go8
-rw-r--r--pkg/api/server/register_images.go6
-rw-r--r--pkg/bindings/connection.go4
-rw-r--r--pkg/bindings/images/build.go3
-rw-r--r--pkg/bindings/images/types.go2
-rw-r--r--pkg/bindings/images/types_prune_options.go15
-rw-r--r--pkg/domain/entities/images.go5
-rw-r--r--pkg/domain/infra/abi/containers.go4
-rw-r--r--pkg/domain/infra/abi/images.go12
-rw-r--r--pkg/domain/infra/abi/secrets.go2
-rw-r--r--pkg/domain/infra/tunnel/images.go2
-rw-r--r--pkg/machine/ignition.go88
-rw-r--r--pkg/specgen/generate/container.go2
-rw-r--r--pkg/specgen/generate/container_create.go3
14 files changed, 139 insertions, 17 deletions
diff --git a/pkg/api/handlers/libpod/images.go b/pkg/api/handlers/libpod/images.go
index 0023479ea..1c6cc917c 100644
--- a/pkg/api/handlers/libpod/images.go
+++ b/pkg/api/handlers/libpod/images.go
@@ -150,7 +150,8 @@ func PruneImages(w http.ResponseWriter, r *http.Request) {
runtime := r.Context().Value(api.RuntimeKey).(*libpod.Runtime)
decoder := r.Context().Value(api.DecoderKey).(*schema.Decoder)
query := struct {
- All bool `schema:"all"`
+ All bool `schema:"all"`
+ External bool `schema:"external"`
}{
// override any golang type defaults
}
@@ -190,8 +191,9 @@ func PruneImages(w http.ResponseWriter, r *http.Request) {
imageEngine := abi.ImageEngine{Libpod: runtime}
pruneOptions := entities.ImagePruneOptions{
- All: query.All,
- Filter: libpodFilters,
+ All: query.All,
+ External: query.External,
+ Filter: libpodFilters,
}
imagePruneReports, err := imageEngine.Prune(r.Context(), pruneOptions)
if err != nil {
diff --git a/pkg/api/server/register_images.go b/pkg/api/server/register_images.go
index 5e0de7def..aa573eaa6 100644
--- a/pkg/api/server/register_images.go
+++ b/pkg/api/server/register_images.go
@@ -1050,6 +1050,12 @@ func (s *APIServer) registerImagesHandlers(r *mux.Router) error {
// description: |
// Remove all images not in use by containers, not just dangling ones
// - in: query
+ // name: external
+ // default: false
+ // type: boolean
+ // description: |
+ // Remove images even when they are used by external containers (e.g, by build containers)
+ // - in: query
// name: filters
// type: string
// description: |
diff --git a/pkg/bindings/connection.go b/pkg/bindings/connection.go
index 4127ad2f0..e2c46e481 100644
--- a/pkg/bindings/connection.go
+++ b/pkg/bindings/connection.go
@@ -112,12 +112,12 @@ func NewConnectionWithIdentity(ctx context.Context, uri string, identity string)
return nil, errors.Errorf("unable to create connection. %q is not a supported schema", _url.Scheme)
}
if err != nil {
- return nil, errors.Wrapf(err, "failed to create %sClient", _url.Scheme)
+ return nil, errors.Wrapf(err, "unable to connect to Podman. failed to create %sClient", _url.Scheme)
}
ctx = context.WithValue(ctx, clientKey, &connection)
if err := pingNewConnection(ctx); err != nil {
- return nil, errors.Wrap(err, "cannot connect to the Podman socket, please verify the connection to the Linux system, or use `podman machine` to create/start a Linux VM.")
+ return nil, errors.Wrap(err, "unable to connect to Podman socket")
}
return ctx, nil
}
diff --git a/pkg/bindings/images/build.go b/pkg/bindings/images/build.go
index ded97d8d6..8cf4532d0 100644
--- a/pkg/bindings/images/build.go
+++ b/pkg/bindings/images/build.go
@@ -230,6 +230,9 @@ func Build(ctx context.Context, containerFiles []string, options entities.BuildO
params.Add("platform", platform)
}
}
+ if contextDir, err := filepath.EvalSymlinks(options.ContextDirectory); err == nil {
+ options.ContextDirectory = contextDir
+ }
params.Set("pullpolicy", options.PullPolicy.String())
diff --git a/pkg/bindings/images/types.go b/pkg/bindings/images/types.go
index 6ff9f18ec..dc6bd91c3 100644
--- a/pkg/bindings/images/types.go
+++ b/pkg/bindings/images/types.go
@@ -74,6 +74,8 @@ type ExportOptions struct {
type PruneOptions struct {
// Prune all images
All *bool
+ // Prune images even when they're used by external containers
+ External *bool
// Filters to apply when pruning images
Filters map[string][]string
}
diff --git a/pkg/bindings/images/types_prune_options.go b/pkg/bindings/images/types_prune_options.go
index 77bef32e3..c9772045e 100644
--- a/pkg/bindings/images/types_prune_options.go
+++ b/pkg/bindings/images/types_prune_options.go
@@ -32,6 +32,21 @@ func (o *PruneOptions) GetAll() bool {
return *o.All
}
+// WithExternal set field External to given value
+func (o *PruneOptions) WithExternal(value bool) *PruneOptions {
+ o.External = &value
+ return o
+}
+
+// GetExternal returns value of field External
+func (o *PruneOptions) GetExternal() bool {
+ if o.External == nil {
+ var z bool
+ return z
+ }
+ return *o.External
+}
+
// WithFilters set field Filters to given value
func (o *PruneOptions) WithFilters(value map[string][]string) *PruneOptions {
o.Filters = value
diff --git a/pkg/domain/entities/images.go b/pkg/domain/entities/images.go
index 80d570764..2822b1ad7 100644
--- a/pkg/domain/entities/images.go
+++ b/pkg/domain/entities/images.go
@@ -251,8 +251,9 @@ type ImageListOptions struct {
}
type ImagePruneOptions struct {
- All bool `json:"all" schema:"all"`
- Filter []string `json:"filter" schema:"filter"`
+ All bool `json:"all" schema:"all"`
+ External bool `json:"external" schema:"external"`
+ Filter []string `json:"filter" schema:"filter"`
}
type ImageTagOptions struct{}
diff --git a/pkg/domain/infra/abi/containers.go b/pkg/domain/infra/abi/containers.go
index 02af214a6..8e7e2d411 100644
--- a/pkg/domain/infra/abi/containers.go
+++ b/pkg/domain/infra/abi/containers.go
@@ -169,6 +169,10 @@ func (ic *ContainerEngine) ContainerStop(ctx context.Context, namesOrIds []strin
logrus.Debugf("Container %s is already stopped", c.ID())
case options.All && errors.Cause(err) == define.ErrCtrStateInvalid:
logrus.Debugf("Container %s is not running, could not stop", c.ID())
+ // container never created in OCI runtime
+ // docker parity: do nothing just return container id
+ case errors.Cause(err) == define.ErrCtrStateInvalid:
+ logrus.Debugf("Container %s is either not created on runtime or is in a invalid state", c.ID())
default:
return err
}
diff --git a/pkg/domain/infra/abi/images.go b/pkg/domain/infra/abi/images.go
index 98d668434..c06059205 100644
--- a/pkg/domain/infra/abi/images.go
+++ b/pkg/domain/infra/abi/images.go
@@ -41,13 +41,21 @@ func (ir *ImageEngine) Exists(_ context.Context, nameOrID string) (*entities.Boo
func (ir *ImageEngine) Prune(ctx context.Context, opts entities.ImagePruneOptions) ([]*reports.PruneReport, error) {
pruneOptions := &libimage.RemoveImagesOptions{
- Filters: append(opts.Filter, "containers=false", "readonly=false"),
- WithSize: true,
+ RemoveContainerFunc: ir.Libpod.RemoveContainersForImageCallback(ctx),
+ IsExternalContainerFunc: ir.Libpod.IsExternalContainerCallback(ctx),
+ ExternalContainers: opts.External,
+ Filters: append(opts.Filter, "readonly=false"),
+ WithSize: true,
}
if !opts.All {
pruneOptions.Filters = append(pruneOptions.Filters, "dangling=true")
}
+ if opts.External {
+ pruneOptions.Filters = append(pruneOptions.Filters, "containers=external")
+ } else {
+ pruneOptions.Filters = append(pruneOptions.Filters, "containers=false")
+ }
var pruneReports []*reports.PruneReport
diff --git a/pkg/domain/infra/abi/secrets.go b/pkg/domain/infra/abi/secrets.go
index 2bf8eaae3..34c230e75 100644
--- a/pkg/domain/infra/abi/secrets.go
+++ b/pkg/domain/infra/abi/secrets.go
@@ -21,7 +21,7 @@ func (ic *ContainerEngine) SecretCreate(ctx context.Context, name string, reader
// set defaults from config for the case they are not set by an upper layer
// (-> i.e. tests that talk directly to the api)
- cfg, err := ic.Libpod.GetConfig()
+ cfg, err := ic.Libpod.GetConfigNoCopy()
if err != nil {
return nil, err
}
diff --git a/pkg/domain/infra/tunnel/images.go b/pkg/domain/infra/tunnel/images.go
index 282770613..d41a20348 100644
--- a/pkg/domain/infra/tunnel/images.go
+++ b/pkg/domain/infra/tunnel/images.go
@@ -95,7 +95,7 @@ func (ir *ImageEngine) Prune(ctx context.Context, opts entities.ImagePruneOption
f := strings.Split(filter, "=")
filters[f[0]] = f[1:]
}
- options := new(images.PruneOptions).WithAll(opts.All).WithFilters(filters)
+ options := new(images.PruneOptions).WithAll(opts.All).WithFilters(filters).WithExternal(opts.External)
reports, err := images.Prune(ir.ClientCtx, options)
if err != nil {
return nil, err
diff --git a/pkg/machine/ignition.go b/pkg/machine/ignition.go
index 89b556b14..e211f5ea6 100644
--- a/pkg/machine/ignition.go
+++ b/pkg/machine/ignition.go
@@ -6,6 +6,7 @@ import (
"encoding/json"
"fmt"
"io/ioutil"
+ "net/url"
)
/*
@@ -80,6 +81,7 @@ func NewIgnitionFile(ign DynamicIgnition) error {
// so a listening host knows it can being interacting with it
ready := `[Unit]
Requires=dev-virtio\\x2dports-%s.device
+After=remove-moby.service
OnFailure=emergency.target
OnFailureJobMode=isolate
[Service]
@@ -89,6 +91,23 @@ ExecStart=/bin/sh -c '/usr/bin/echo Ready >/dev/%s'
[Install]
RequiredBy=multi-user.target
`
+ deMoby := `[Unit]
+Description=Remove moby-engine
+# Run once for the machine
+After=systemd-machine-id-commit.service
+Before=zincati.service
+ConditionPathExists=!/var/lib/%N.stamp
+
+[Service]
+Type=oneshot
+RemainAfterExit=yes
+ExecStart=/usr/bin/rpm-ostree override remove moby-engine
+ExecStart=/usr/bin/rpm-ostree ex apply-live --allow-replacement
+ExecStartPost=/bin/touch /var/lib/%N.stamp
+
+[Install]
+WantedBy=multi-user.target
+ `
_ = ready
ignSystemd := Systemd{
Units: []Unit{
@@ -101,6 +120,21 @@ RequiredBy=multi-user.target
Name: "ready.service",
Contents: strToPtr(fmt.Sprintf(ready, "vport1p1", "vport1p1")),
},
+ {
+ Enabled: boolToPtr(false),
+ Name: "docker.service",
+ Mask: boolToPtr(true),
+ },
+ {
+ Enabled: boolToPtr(false),
+ Name: "docker.socket",
+ Mask: boolToPtr(true),
+ },
+ {
+ Enabled: boolToPtr(true),
+ Name: "remove-moby.service",
+ Contents: &deMoby,
+ },
}}
ignConfig := Config{
Ignition: ignVersion,
@@ -161,6 +195,22 @@ func getFiles(usrName string) []File {
var (
files []File
)
+
+ lingerExample := `[Unit]
+Description=A systemd user unit demo
+After=network-online.target
+Wants=network-online.target podman.socket
+[Service]
+ExecStart=/usr/bin/sleep infinity
+`
+ containers := `[containers]
+netns="bridge"
+rootless_networking="cni"
+`
+ rootContainers := `[engine]
+machine_enabled=true
+`
+
// Add a fake systemd service to get the user socket rolling
files = append(files, File{
Node: Node{
@@ -171,7 +221,7 @@ func getFiles(usrName string) []File {
FileEmbedded1: FileEmbedded1{
Append: nil,
Contents: Resource{
- Source: strToPtr("data:,%5BUnit%5D%0ADescription%3DA%20systemd%20user%20unit%20demo%0AAfter%3Dnetwork-online.target%0AWants%3Dnetwork-online.target%20podman.socket%0A%5BService%5D%0AExecStart%3D%2Fusr%2Fbin%2Fsleep%20infinity%0A"),
+ Source: encodeDataURLPtr(lingerExample),
},
Mode: intToPtr(0744),
},
@@ -188,7 +238,7 @@ func getFiles(usrName string) []File {
FileEmbedded1: FileEmbedded1{
Append: nil,
Contents: Resource{
- Source: strToPtr("data:,%5Bcontainers%5D%0D%0Anetns%3D%22bridge%22%0D%0Arootless_networking%3D%22cni%22"),
+ Source: encodeDataURLPtr(containers),
},
Mode: intToPtr(0744),
},
@@ -213,7 +263,7 @@ func getFiles(usrName string) []File {
FileEmbedded1: FileEmbedded1{
Append: nil,
Contents: Resource{
- Source: strToPtr("data:,%5Bengine%5D%0Amachine_enabled%3Dtrue%0A"),
+ Source: encodeDataURLPtr(rootContainers),
},
Mode: intToPtr(0644),
},
@@ -233,7 +283,22 @@ func getFiles(usrName string) []File {
FileEmbedded1: FileEmbedded1{
Append: nil,
Contents: Resource{
- Source: strToPtr("data:,unqualified-search-registries%3D%5B%22docker.io%22%5D"),
+ Source: encodeDataURLPtr("unqualified-search-registries=[\"docker.io\"]\n"),
+ },
+ Mode: intToPtr(0644),
+ },
+ })
+
+ files = append(files, File{
+ Node: Node{
+ Path: "/etc/tmpfiles.d/podman-docker.conf",
+ },
+ FileEmbedded1: FileEmbedded1{
+ Append: nil,
+ // Create a symlink from the docker socket to the podman socket.
+ // Taken from https://github.com/containers/podman/blob/main/contrib/systemd/system/podman-docker.conf
+ Contents: Resource{
+ Source: encodeDataURLPtr("L+ /run/docker.sock - - - - /run/podman/podman.sock\n"),
},
Mode: intToPtr(0644),
},
@@ -253,5 +318,20 @@ func getLinks(usrName string) []Link {
Hard: boolToPtr(false),
Target: "/home/" + usrName + "/.config/systemd/user/linger-example.service",
},
+ }, {
+ Node: Node{
+ Group: getNodeGrp("root"),
+ Path: "/usr/local/bin/docker",
+ Overwrite: boolToPtr(true),
+ User: getNodeUsr("root"),
+ },
+ LinkEmbedded1: LinkEmbedded1{
+ Hard: boolToPtr(false),
+ Target: "/usr/bin/podman",
+ },
}}
}
+
+func encodeDataURLPtr(contents string) *string {
+ return strToPtr(fmt.Sprintf("data:,%s", url.PathEscape(contents)))
+}
diff --git a/pkg/specgen/generate/container.go b/pkg/specgen/generate/container.go
index ae26807a9..71b882510 100644
--- a/pkg/specgen/generate/container.go
+++ b/pkg/specgen/generate/container.go
@@ -54,7 +54,7 @@ func CompleteSpec(ctx context.Context, r *libpod.Runtime, s *specgen.SpecGenerat
}
}
- rtc, err := r.GetConfig()
+ rtc, err := r.GetConfigNoCopy()
if err != nil {
return nil, err
}
diff --git a/pkg/specgen/generate/container_create.go b/pkg/specgen/generate/container_create.go
index fefa9b4a9..6100e7a5b 100644
--- a/pkg/specgen/generate/container_create.go
+++ b/pkg/specgen/generate/container_create.go
@@ -23,7 +23,7 @@ import (
// Returns the created, container and any warnings resulting from creating the
// container, or an error.
func MakeContainer(ctx context.Context, rt *libpod.Runtime, s *specgen.SpecGenerator) (*spec.Spec, *specgen.SpecGenerator, []libpod.CtrCreateOption, error) {
- rtc, err := rt.GetConfig()
+ rtc, err := rt.GetConfigNoCopy()
if err != nil {
return nil, nil, nil, err
}
@@ -498,6 +498,7 @@ func CreateExitCommandArgs(storageConfig types.StoreOptions, config *config.Conf
"--log-level", logrus.GetLevel().String(),
"--cgroup-manager", config.Engine.CgroupManager,
"--tmpdir", config.Engine.TmpDir,
+ "--cni-config-dir", config.Network.NetworkConfigDir,
}
if config.Engine.OCIRuntime != "" {
command = append(command, []string{"--runtime", config.Engine.OCIRuntime}...)