summaryrefslogtreecommitdiff
path: root/pkg
diff options
context:
space:
mode:
Diffstat (limited to 'pkg')
-rw-r--r--pkg/api/handlers/compat/containers_stats.go43
-rw-r--r--pkg/api/handlers/compat/images.go6
-rw-r--r--pkg/api/handlers/compat/images_build.go20
-rw-r--r--pkg/api/handlers/compat/images_save.go2
-rw-r--r--pkg/api/handlers/libpod/containers.go4
-rw-r--r--pkg/api/handlers/libpod/containers_stats.go2
-rw-r--r--pkg/api/handlers/libpod/images.go2
-rw-r--r--pkg/api/handlers/utils/containers.go1
-rw-r--r--pkg/api/handlers/utils/images.go2
-rw-r--r--pkg/api/server/listener_api.go2
-rw-r--r--pkg/api/server/server.go2
-rw-r--r--pkg/bindings/connection.go9
-rw-r--r--pkg/bindings/containers/attach.go4
-rw-r--r--pkg/bindings/containers/containers.go6
-rw-r--r--pkg/bindings/images/build.go7
-rw-r--r--pkg/bindings/images/build_unix.go2
-rw-r--r--pkg/bindings/manifests/types.go22
-rw-r--r--pkg/bindings/manifests/types_modify_options.go8
-rw-r--r--pkg/criu/criu.go43
-rw-r--r--pkg/criu/criu_linux.go44
-rw-r--r--pkg/criu/criu_unsupported.go8
-rw-r--r--pkg/ctime/ctime_linux.go2
-rw-r--r--pkg/domain/entities/containers.go32
-rw-r--r--pkg/domain/entities/engine_container.go1
-rw-r--r--pkg/domain/entities/images.go12
-rw-r--r--pkg/domain/entities/network.go2
-rw-r--r--pkg/domain/entities/pods.go38
-rw-r--r--pkg/domain/entities/reports/containers.go2
-rw-r--r--pkg/domain/entities/reports/prune.go2
-rw-r--r--pkg/domain/entities/system.go1
-rw-r--r--pkg/domain/entities/types.go2
-rw-r--r--pkg/domain/entities/volumes.go6
-rw-r--r--pkg/domain/infra/abi/containers.go45
-rw-r--r--pkg/domain/infra/abi/images.go2
-rw-r--r--pkg/domain/infra/abi/network.go86
-rw-r--r--pkg/domain/infra/abi/play.go6
-rw-r--r--pkg/domain/infra/abi/pods.go89
-rw-r--r--pkg/domain/infra/abi/system.go54
-rw-r--r--pkg/domain/infra/abi/terminal/sigproxy_linux.go2
-rw-r--r--pkg/domain/infra/abi/volumes.go2
-rw-r--r--pkg/domain/infra/runtime_libpod.go4
-rw-r--r--pkg/domain/infra/tunnel/containers.go4
-rw-r--r--pkg/domain/infra/tunnel/helpers.go4
-rw-r--r--pkg/domain/infra/tunnel/pods.go4
-rw-r--r--pkg/errorhandling/errorhandling.go2
-rw-r--r--pkg/hooks/exec/runtimeconfigfilter_test.go2
-rw-r--r--pkg/k8s.io/apimachinery/pkg/api/resource/quantity.go9
-rw-r--r--pkg/machine/e2e/list_test.go23
-rw-r--r--pkg/machine/fcos.go2
-rw-r--r--pkg/machine/ignition.go4
-rw-r--r--pkg/machine/keys.go11
-rw-r--r--pkg/machine/qemu/machine.go26
-rw-r--r--pkg/machine/qemu/options_darwin_arm64.go23
-rw-r--r--pkg/namespaces/namespaces.go2
-rw-r--r--pkg/rootless/rootless.go2
-rw-r--r--pkg/rootless/rootless_linux.c24
-rw-r--r--pkg/rootless/rootless_linux.go39
-rw-r--r--pkg/signal/signal_common.go17
-rw-r--r--pkg/signal/signal_linux.go17
-rw-r--r--pkg/signal/signal_linux_mipsx.go17
-rw-r--r--pkg/signal/signal_unix.go11
-rw-r--r--pkg/signal/signal_unsupported.go11
-rw-r--r--pkg/specgen/generate/config_linux.go2
-rw-r--r--pkg/specgen/generate/container.go19
-rw-r--r--pkg/specgen/generate/container_create.go18
-rw-r--r--pkg/specgen/generate/oci.go25
-rw-r--r--pkg/specgen/generate/pod_create.go90
-rw-r--r--pkg/specgen/podspecgen.go4
-rw-r--r--pkg/specgen/volumes.go16
-rw-r--r--pkg/specgenutil/specgen.go2
-rw-r--r--pkg/systemd/generate/containers.go2
-rw-r--r--pkg/util/utils_linux.go2
72 files changed, 682 insertions, 381 deletions
diff --git a/pkg/api/handlers/compat/containers_stats.go b/pkg/api/handlers/compat/containers_stats.go
index 77b16b03e..12c5283fc 100644
--- a/pkg/api/handlers/compat/containers_stats.go
+++ b/pkg/api/handlers/compat/containers_stats.go
@@ -12,6 +12,7 @@ import (
api "github.com/containers/podman/v4/pkg/api/types"
docker "github.com/docker/docker/api/types"
"github.com/gorilla/schema"
+ runccgroups "github.com/opencontainers/runc/libcontainer/cgroups"
"github.com/pkg/errors"
"github.com/sirupsen/logrus"
)
@@ -44,18 +45,6 @@ func StatsContainer(w http.ResponseWriter, r *http.Request) {
return
}
- // If the container isn't running, then let's not bother and return
- // immediately.
- state, err := ctnr.State()
- if err != nil {
- utils.InternalServerError(w, err)
- return
- }
- if state != define.ContainerStateRunning {
- utils.Error(w, http.StatusConflict, define.ErrCtrStateInvalid)
- return
- }
-
stats, err := ctnr.GetContainerStats(nil)
if err != nil {
utils.InternalServerError(w, errors.Wrapf(err, "failed to obtain Container %s stats", name))
@@ -70,7 +59,7 @@ func StatsContainer(w http.ResponseWriter, r *http.Request) {
flusher.Flush()
}
- // Setup JSON encoder for streaming.
+ // Set up JSON encoder for streaming.
coder.SetEscapeHTML(true)
var preRead time.Time
var preCPUStats CPUStats
@@ -144,17 +133,23 @@ streamLabel: // A label to flatten the scope
InstanceID: "",
}
+ cfg := ctnr.Config()
+ memoryLimit := cgroupStat.MemoryStats.Usage.Limit
+ if cfg.Spec.Linux != nil && cfg.Spec.Linux.Resources != nil && cfg.Spec.Linux.Resources.Memory != nil && *cfg.Spec.Linux.Resources.Memory.Limit > 0 {
+ memoryLimit = uint64(*cfg.Spec.Linux.Resources.Memory.Limit)
+ }
+
systemUsage, _ := cgroups.GetSystemCPUUsage()
s := StatsJSON{
Stats: Stats{
Read: time.Now(),
PreRead: preRead,
PidsStats: docker.PidsStats{
- Current: cgroupStat.Pids.Current,
+ Current: cgroupStat.PidsStats.Current,
Limit: 0,
},
BlkioStats: docker.BlkioStats{
- IoServiceBytesRecursive: toBlkioStatEntry(cgroupStat.Blkio.IoServiceBytesRecursive),
+ IoServiceBytesRecursive: toBlkioStatEntry(cgroupStat.BlkioStats.IoServiceBytesRecursive),
IoServicedRecursive: nil,
IoQueuedRecursive: nil,
IoServiceTimeRecursive: nil,
@@ -165,14 +160,14 @@ streamLabel: // A label to flatten the scope
},
CPUStats: CPUStats{
CPUUsage: docker.CPUUsage{
- TotalUsage: cgroupStat.CPU.Usage.Total,
- PercpuUsage: cgroupStat.CPU.Usage.PerCPU,
- UsageInKernelmode: cgroupStat.CPU.Usage.Kernel,
- UsageInUsermode: cgroupStat.CPU.Usage.Total - cgroupStat.CPU.Usage.Kernel,
+ TotalUsage: cgroupStat.CpuStats.CpuUsage.TotalUsage,
+ PercpuUsage: cgroupStat.CpuStats.CpuUsage.PercpuUsage,
+ UsageInKernelmode: cgroupStat.CpuStats.CpuUsage.UsageInKernelmode,
+ UsageInUsermode: cgroupStat.CpuStats.CpuUsage.TotalUsage - cgroupStat.CpuStats.CpuUsage.UsageInKernelmode,
},
CPU: stats.CPU,
SystemUsage: systemUsage,
- OnlineCPUs: uint32(len(cgroupStat.CPU.Usage.PerCPU)),
+ OnlineCPUs: uint32(len(cgroupStat.CpuStats.CpuUsage.PercpuUsage)),
ThrottlingData: docker.ThrottlingData{
Periods: 0,
ThrottledPeriods: 0,
@@ -181,11 +176,11 @@ streamLabel: // A label to flatten the scope
},
PreCPUStats: preCPUStats,
MemoryStats: docker.MemoryStats{
- Usage: cgroupStat.Memory.Usage.Usage,
- MaxUsage: cgroupStat.Memory.Usage.Limit,
+ Usage: cgroupStat.MemoryStats.Usage.Usage,
+ MaxUsage: cgroupStat.MemoryStats.Usage.Limit,
Stats: nil,
Failcnt: 0,
- Limit: cgroupStat.Memory.Usage.Limit,
+ Limit: memoryLimit,
Commit: 0,
CommitPeak: 0,
PrivateWorkingSet: 0,
@@ -222,7 +217,7 @@ streamLabel: // A label to flatten the scope
}
}
-func toBlkioStatEntry(entries []cgroups.BlkIOEntry) []docker.BlkioStatEntry {
+func toBlkioStatEntry(entries []runccgroups.BlkioStatEntry) []docker.BlkioStatEntry {
results := make([]docker.BlkioStatEntry, len(entries))
for i, e := range entries {
bits, err := json.Marshal(e)
diff --git a/pkg/api/handlers/compat/images.go b/pkg/api/handlers/compat/images.go
index 76a28fadf..981a38c35 100644
--- a/pkg/api/handlers/compat/images.go
+++ b/pkg/api/handlers/compat/images.go
@@ -165,7 +165,7 @@ func CommitContainer(w http.ResponseWriter, r *http.Request) {
utils.Error(w, http.StatusInternalServerError, errors.Wrapf(err, "CommitFailure"))
return
}
- utils.WriteResponse(w, http.StatusCreated, entities.IDResponse{ID: commitImage.ID()}) // nolint
+ utils.WriteResponse(w, http.StatusCreated, entities.IDResponse{ID: commitImage.ID()})
}
func CreateImageFromSrc(w http.ResponseWriter, r *http.Request) {
@@ -237,7 +237,7 @@ func CreateImageFromSrc(w http.ResponseWriter, r *http.Request) {
Status string `json:"status"`
Progress string `json:"progress"`
ProgressDetail map[string]string `json:"progressDetail"`
- Id string `json:"id"` // nolint
+ Id string `json:"id"` //nolint:revive,stylecheck
}{
Status: report.Id,
ProgressDetail: map[string]string{},
@@ -333,7 +333,7 @@ loop: // break out of for/select infinite loop
Total int64 `json:"total,omitempty"`
} `json:"progressDetail,omitempty"`
Error string `json:"error,omitempty"`
- Id string `json:"id,omitempty"` // nolint
+ Id string `json:"id,omitempty"` //nolint:revive,stylecheck
}
select {
case e := <-progress:
diff --git a/pkg/api/handlers/compat/images_build.go b/pkg/api/handlers/compat/images_build.go
index fe17aa1d4..80fc17f56 100644
--- a/pkg/api/handlers/compat/images_build.go
+++ b/pkg/api/handlers/compat/images_build.go
@@ -78,15 +78,15 @@ func BuildImage(w http.ResponseWriter, r *http.Request) {
AppArmor string `schema:"apparmor"`
BuildArgs string `schema:"buildargs"`
CacheFrom string `schema:"cachefrom"`
- CgroupParent string `schema:"cgroupparent"` // nolint
+ CgroupParent string `schema:"cgroupparent"`
Compression uint64 `schema:"compression"`
ConfigureNetwork string `schema:"networkmode"`
CPPFlags string `schema:"cppflags"`
- CpuPeriod uint64 `schema:"cpuperiod"` // nolint
- CpuQuota int64 `schema:"cpuquota"` // nolint
- CpuSetCpus string `schema:"cpusetcpus"` // nolint
- CpuSetMems string `schema:"cpusetmems"` // nolint
- CpuShares uint64 `schema:"cpushares"` // nolint
+ CpuPeriod uint64 `schema:"cpuperiod"` //nolint:revive,stylecheck
+ CpuQuota int64 `schema:"cpuquota"` //nolint:revive,stylecheck
+ CpuSetCpus string `schema:"cpusetcpus"` //nolint:revive,stylecheck
+ CpuSetMems string `schema:"cpusetmems"` //nolint:revive,stylecheck
+ CpuShares uint64 `schema:"cpushares"` //nolint:revive,stylecheck
DNSOptions string `schema:"dnsoptions"`
DNSSearch string `schema:"dnssearch"`
DNSServers string `schema:"dnsservers"`
@@ -101,7 +101,7 @@ func BuildImage(w http.ResponseWriter, r *http.Request) {
IdentityLabel bool `schema:"identitylabel"`
Ignore bool `schema:"ignore"`
Isolation string `schema:"isolation"`
- Jobs int `schema:"jobs"` // nolint
+ Jobs int `schema:"jobs"`
LabelOpts string `schema:"labelopts"`
Labels string `schema:"labels"`
Layers bool `schema:"layers"`
@@ -111,6 +111,7 @@ func BuildImage(w http.ResponseWriter, r *http.Request) {
Memory int64 `schema:"memory"`
NamespaceOptions string `schema:"nsoptions"`
NoCache bool `schema:"nocache"`
+ OmitHistory bool `schema:"omithistory"`
OSFeatures []string `schema:"osfeature"`
OSVersion string `schema:"osversion"`
OutputFormat string `schema:"outputformat"`
@@ -366,7 +367,7 @@ func BuildImage(w http.ResponseWriter, r *http.Request) {
}
}
}
- var additionalTags []string // nolint
+ var additionalTags []string
for i := 1; i < len(tags); i++ {
possiblyNormalizedTag, err := utils.NormalizeToDockerHub(r, tags[i])
if err != nil {
@@ -595,6 +596,7 @@ func BuildImage(w http.ResponseWriter, r *http.Request) {
LabelOpts: labelOpts,
Memory: query.Memory,
MemorySwap: query.MemSwap,
+ OmitHistory: query.OmitHistory,
SeccompProfilePath: seccomp,
ShmSize: strconv.Itoa(query.ShmSize),
Ulimit: ulimits,
@@ -799,7 +801,7 @@ func parseNetworkConfigurationPolicy(network string) buildah.NetworkConfiguratio
}
}
-func parseLibPodIsolation(isolation string) (buildah.Isolation, error) { // nolint
+func parseLibPodIsolation(isolation string) (buildah.Isolation, error) {
if val, err := strconv.Atoi(isolation); err == nil {
return buildah.Isolation(val), nil
}
diff --git a/pkg/api/handlers/compat/images_save.go b/pkg/api/handlers/compat/images_save.go
index b39c719a0..6314756f6 100644
--- a/pkg/api/handlers/compat/images_save.go
+++ b/pkg/api/handlers/compat/images_save.go
@@ -6,7 +6,7 @@ import (
"os"
)
-func SaveFromBody(f *os.File, r *http.Request) error { // nolint
+func SaveFromBody(f *os.File, r *http.Request) error {
if _, err := io.Copy(f, r.Body); err != nil {
return err
}
diff --git a/pkg/api/handlers/libpod/containers.go b/pkg/api/handlers/libpod/containers.go
index 6b5bee403..deddcaf93 100644
--- a/pkg/api/handlers/libpod/containers.go
+++ b/pkg/api/handlers/libpod/containers.go
@@ -115,10 +115,6 @@ func ListContainers(w http.ResponseWriter, r *http.Request) {
utils.InternalServerError(w, err)
return
}
- if len(pss) == 0 {
- utils.WriteResponse(w, http.StatusOK, "[]")
- return
- }
utils.WriteResponse(w, http.StatusOK, pss)
}
diff --git a/pkg/api/handlers/libpod/containers_stats.go b/pkg/api/handlers/libpod/containers_stats.go
index d34254fd7..46d722a3d 100644
--- a/pkg/api/handlers/libpod/containers_stats.go
+++ b/pkg/api/handlers/libpod/containers_stats.go
@@ -66,7 +66,7 @@ func StatsContainer(w http.ResponseWriter, r *http.Request) {
flusher.Flush()
}
- // Setup JSON encoder for streaming.
+ // Set up JSON encoder for streaming.
coder := json.NewEncoder(w)
coder.SetEscapeHTML(true)
diff --git a/pkg/api/handlers/libpod/images.go b/pkg/api/handlers/libpod/images.go
index 60ed5feb3..a8a50ae58 100644
--- a/pkg/api/handlers/libpod/images.go
+++ b/pkg/api/handlers/libpod/images.go
@@ -562,7 +562,7 @@ func CommitContainer(w http.ResponseWriter, r *http.Request) {
utils.Error(w, http.StatusInternalServerError, errors.Wrapf(err, "CommitFailure"))
return
}
- utils.WriteResponse(w, http.StatusOK, entities.IDResponse{ID: commitImage.ID()}) // nolint
+ utils.WriteResponse(w, http.StatusOK, entities.IDResponse{ID: commitImage.ID()})
}
func UntagImage(w http.ResponseWriter, r *http.Request) {
diff --git a/pkg/api/handlers/utils/containers.go b/pkg/api/handlers/utils/containers.go
index 8588b49ba..1795f6ce1 100644
--- a/pkg/api/handlers/utils/containers.go
+++ b/pkg/api/handlers/utils/containers.go
@@ -191,7 +191,6 @@ func waitDockerCondition(ctx context.Context, containerName string, interval tim
var notRunningStates = []define.ContainerStatus{
define.ContainerStateCreated,
define.ContainerStateRemoving,
- define.ContainerStateStopped,
define.ContainerStateExited,
define.ContainerStateConfigured,
}
diff --git a/pkg/api/handlers/utils/images.go b/pkg/api/handlers/utils/images.go
index 433231f59..77f6dcf1d 100644
--- a/pkg/api/handlers/utils/images.go
+++ b/pkg/api/handlers/utils/images.go
@@ -68,7 +68,7 @@ func IsRegistryReference(name string) error {
imageRef, err := alltransports.ParseImageName(name)
if err != nil {
// No supported transport -> assume a docker-stype reference.
- return nil // nolint: nilerr
+ return nil //nolint: nilerr
}
if imageRef.Transport().Name() == docker.Transport.Name() {
return nil
diff --git a/pkg/api/server/listener_api.go b/pkg/api/server/listener_api.go
index 2d02df7dc..aaaf6688e 100644
--- a/pkg/api/server/listener_api.go
+++ b/pkg/api/server/listener_api.go
@@ -11,7 +11,7 @@ import (
// ListenUnix follows stdlib net.Listen() API, providing a unix listener for given path
// ListenUnix will delete and create files/directories as needed
func ListenUnix(network string, path string) (net.Listener, error) {
- // setup custom listener for API server
+ // set up custom listener for API server
err := os.MkdirAll(filepath.Dir(path), 0770)
if err != nil {
return nil, errors.Wrapf(err, "api.ListenUnix() failed to create %s", filepath.Dir(path))
diff --git a/pkg/api/server/server.go b/pkg/api/server/server.go
index 7a7e35e8e..5482a8ec2 100644
--- a/pkg/api/server/server.go
+++ b/pkg/api/server/server.go
@@ -148,7 +148,7 @@ func newServer(runtime *libpod.Runtime, listener net.Listener, opts entities.Ser
if logrus.IsLevelEnabled(logrus.TraceLevel) {
// If in trace mode log request and response bodies
router.Use(loggingHandler())
- router.Walk(func(route *mux.Route, r *mux.Router, ancestors []*mux.Route) error { // nolint
+ _ = router.Walk(func(route *mux.Route, r *mux.Router, ancestors []*mux.Route) error {
path, err := route.GetPathTemplate()
if err != nil {
path = "<N/A>"
diff --git a/pkg/bindings/connection.go b/pkg/bindings/connection.go
index 3739ec404..6b3576f31 100644
--- a/pkg/bindings/connection.go
+++ b/pkg/bindings/connection.go
@@ -95,7 +95,7 @@ func NewConnectionWithIdentity(ctx context.Context, uri string, identity string)
return nil, errors.Wrapf(err, "Value of CONTAINER_HOST is not a valid url: %s", uri)
}
- // Now we setup the http Client to use the connection above
+ // Now we set up the http Client to use the connection above
var connection Connection
switch _url.Scheme {
case "ssh":
@@ -164,7 +164,7 @@ func pingNewConnection(ctx context.Context) (*semver.Version, error) {
if response.StatusCode == http.StatusOK {
versionHdr := response.Header.Get("Libpod-API-Version")
if versionHdr == "" {
- logrus.Info("Service did not provide Libpod-API-Version Header")
+ logrus.Warn("Service did not provide Libpod-API-Version Header")
return new(semver.Version), nil
}
versionSrv, err := semver.ParseTolerant(versionHdr)
@@ -315,7 +315,8 @@ func unixClient(_url *url.URL) Connection {
return connection
}
-// DoRequest assembles the http request and returns the response
+// DoRequest assembles the http request and returns the response.
+// The caller must close the response body.
func (c *Connection) DoRequest(ctx context.Context, httpBody io.Reader, httpMethod, endpoint string, queryParams url.Values, headers http.Header, pathValues ...string) (*APIResponse, error) {
var (
err error
@@ -361,7 +362,7 @@ func (c *Connection) DoRequest(ctx context.Context, httpBody io.Reader, httpMeth
// Give the Do three chances in the case of a comm/service hiccup
for i := 1; i <= 3; i++ {
- response, err = c.Client.Do(req) // nolint
+ response, err = c.Client.Do(req) //nolint:bodyclose // The caller has to close the body.
if err == nil {
break
}
diff --git a/pkg/bindings/containers/attach.go b/pkg/bindings/containers/attach.go
index d84b47052..303fc65bd 100644
--- a/pkg/bindings/containers/attach.go
+++ b/pkg/bindings/containers/attach.go
@@ -54,8 +54,6 @@ func Attach(ctx context.Context, nameOrID string, stdin io.Reader, stdout io.Wri
stderr = (io.Writer)(nil)
}
- logrus.Infof("Going to attach to container %q", nameOrID)
-
conn, err := bindings.GetClient(ctx)
if err != nil {
return err
@@ -357,7 +355,7 @@ func attachHandleResize(ctx, winCtx context.Context, winChange chan os.Signal, i
resizeErr = ResizeContainerTTY(ctx, id, new(ResizeTTYOptions).WithHeight(h).WithWidth(w))
}
if resizeErr != nil {
- logrus.Infof("Failed to resize TTY: %v", resizeErr)
+ logrus.Debugf("Failed to resize TTY: %v", resizeErr)
}
}
diff --git a/pkg/bindings/containers/containers.go b/pkg/bindings/containers/containers.go
index be421cc8b..ea01bc7d9 100644
--- a/pkg/bindings/containers/containers.go
+++ b/pkg/bindings/containers/containers.go
@@ -13,7 +13,6 @@ import (
"github.com/containers/podman/v4/pkg/domain/entities"
"github.com/containers/podman/v4/pkg/domain/entities/reports"
"github.com/pkg/errors"
- "github.com/sirupsen/logrus"
)
var (
@@ -25,7 +24,7 @@ var (
// the most recent number of containers. The pod and size booleans indicate that pod information and rootfs
// size information should also be included. Finally, the sync bool synchronizes the OCI runtime and
// container state.
-func List(ctx context.Context, options *ListOptions) ([]entities.ListContainer, error) { // nolint:typecheck
+func List(ctx context.Context, options *ListOptions) ([]entities.ListContainer, error) {
if options == nil {
options = new(ListOptions)
}
@@ -201,7 +200,6 @@ func Start(ctx context.Context, nameOrID string, options *StartOptions) error {
if options == nil {
options = new(StartOptions)
}
- logrus.Infof("Going to start container %q", nameOrID)
conn, err := bindings.GetClient(ctx)
if err != nil {
return err
@@ -339,7 +337,7 @@ func Unpause(ctx context.Context, nameOrID string, options *UnpauseOptions) erro
// Wait blocks until the given container reaches a condition. If not provided, the condition will
// default to stopped. If the condition is stopped, an exit code for the container will be provided. The
// nameOrID can be a container name or a partial/full ID.
-func Wait(ctx context.Context, nameOrID string, options *WaitOptions) (int32, error) { // nolint
+func Wait(ctx context.Context, nameOrID string, options *WaitOptions) (int32, error) {
if options == nil {
options = new(WaitOptions)
}
diff --git a/pkg/bindings/images/build.go b/pkg/bindings/images/build.go
index fe81dc662..f14f866dd 100644
--- a/pkg/bindings/images/build.go
+++ b/pkg/bindings/images/build.go
@@ -170,6 +170,11 @@ func Build(ctx context.Context, containerFiles []string, options entities.BuildO
} else {
params.Set("rm", "0")
}
+ if options.CommonBuildOpts.OmitHistory {
+ params.Set("omithistory", "1")
+ } else {
+ params.Set("omithistory", "0")
+ }
if len(options.From) > 0 {
params.Set("from", options.From)
}
@@ -616,7 +621,7 @@ func nTar(excludes []string, sources ...string) (io.ReadCloser, error) {
}
name := filepath.ToSlash(strings.TrimPrefix(path, s+string(filepath.Separator)))
- excluded, err := pm.Matches(name) // nolint:staticcheck
+ excluded, err := pm.Matches(name) //nolint:staticcheck
if err != nil {
return errors.Wrapf(err, "error checking if %q is excluded", name)
}
diff --git a/pkg/bindings/images/build_unix.go b/pkg/bindings/images/build_unix.go
index 32e2ba9af..07bb8cbcd 100644
--- a/pkg/bindings/images/build_unix.go
+++ b/pkg/bindings/images/build_unix.go
@@ -11,7 +11,7 @@ import (
func checkHardLink(fi os.FileInfo) (devino, bool) {
st := fi.Sys().(*syscall.Stat_t)
return devino{
- Dev: uint64(st.Dev), // nolint: unconvert
+ Dev: uint64(st.Dev), //nolint: unconvert
Ino: st.Ino,
}, st.Nlink > 1
}
diff --git a/pkg/bindings/manifests/types.go b/pkg/bindings/manifests/types.go
index d0b0b2e71..e23ef798d 100644
--- a/pkg/bindings/manifests/types.go
+++ b/pkg/bindings/manifests/types.go
@@ -44,16 +44,18 @@ type RemoveOptions struct {
type ModifyOptions struct {
// Operation values are "update", "remove" and "annotate". This allows the service to
// efficiently perform each update on a manifest list.
- Operation *string
- All *bool // All when true, operate on all images in a manifest list that may be included in Images
- Annotations map[string]string // Annotations to add to manifest list
- Arch *string // Arch overrides the architecture for the image
- Features []string // Feature list for the image
- Images []string // Images is an optional list of images to add/remove to/from manifest list depending on operation
- OS *string // OS overrides the operating system for the image
- OSFeatures []string // OS features for the image
- OSVersion *string // OSVersion overrides the operating system for the image
- Variant *string // Variant overrides the operating system variant for the image
+ Operation *string
+ All *bool // All when true, operate on all images in a manifest list that may be included in Images
+ Annotations map[string]string // Annotations to add to manifest list
+ Arch *string // Arch overrides the architecture for the image
+ Features []string // Feature list for the image
+ Images []string // Images is an optional list of images to add/remove to/from manifest list depending on operation
+ OS *string // OS overrides the operating system for the image
+ // OS features for the image
+ OSFeatures []string `json:"os_features" schema:"os_features"`
+ // OSVersion overrides the operating system for the image
+ OSVersion *string `json:"os_version" schema:"os_version"`
+ Variant *string // Variant overrides the operating system variant for the image
Authfile *string
Password *string
Username *string
diff --git a/pkg/bindings/manifests/types_modify_options.go b/pkg/bindings/manifests/types_modify_options.go
index 9d2ed2613..ab00cb2c5 100644
--- a/pkg/bindings/manifests/types_modify_options.go
+++ b/pkg/bindings/manifests/types_modify_options.go
@@ -122,13 +122,13 @@ func (o *ModifyOptions) GetOS() string {
return *o.OS
}
-// WithOSFeatures set oS features for the image
+// WithOSFeatures set field OSFeatures to given value
func (o *ModifyOptions) WithOSFeatures(value []string) *ModifyOptions {
o.OSFeatures = value
return o
}
-// GetOSFeatures returns value of oS features for the image
+// GetOSFeatures returns value of field OSFeatures
func (o *ModifyOptions) GetOSFeatures() []string {
if o.OSFeatures == nil {
var z []string
@@ -137,13 +137,13 @@ func (o *ModifyOptions) GetOSFeatures() []string {
return o.OSFeatures
}
-// WithOSVersion set oSVersion overrides the operating system for the image
+// WithOSVersion set field OSVersion to given value
func (o *ModifyOptions) WithOSVersion(value string) *ModifyOptions {
o.OSVersion = &value
return o
}
-// GetOSVersion returns value of oSVersion overrides the operating system for the image
+// GetOSVersion returns value of field OSVersion
func (o *ModifyOptions) GetOSVersion() string {
if o.OSVersion == nil {
var z string
diff --git a/pkg/criu/criu.go b/pkg/criu/criu.go
index 6570159d7..0b0bbff5d 100644
--- a/pkg/criu/criu.go
+++ b/pkg/criu/criu.go
@@ -1,51 +1,8 @@
-//go:build linux
-// +build linux
-
package criu
-import (
- "github.com/checkpoint-restore/go-criu/v5"
- "github.com/checkpoint-restore/go-criu/v5/rpc"
-
- "google.golang.org/protobuf/proto"
-)
-
// MinCriuVersion for Podman at least CRIU 3.11 is required
const MinCriuVersion = 31100
// PodCriuVersion is the version of CRIU needed for
// checkpointing and restoring containers out of and into Pods.
const PodCriuVersion = 31600
-
-// CheckForCriu uses CRIU's go bindings to check if the CRIU
-// binary exists and if it at least the version Podman needs.
-func CheckForCriu(version int) bool {
- c := criu.MakeCriu()
- result, err := c.IsCriuAtLeast(version)
- if err != nil {
- return false
- }
- return result
-}
-
-func GetCriuVestion() (int, error) {
- c := criu.MakeCriu()
- return c.GetCriuVersion()
-}
-
-func MemTrack() bool {
- features, err := criu.MakeCriu().FeatureCheck(
- &rpc.CriuFeatures{
- MemTrack: proto.Bool(true),
- },
- )
- if err != nil {
- return false
- }
-
- if features == nil || features.MemTrack == nil {
- return false
- }
-
- return *features.MemTrack
-}
diff --git a/pkg/criu/criu_linux.go b/pkg/criu/criu_linux.go
new file mode 100644
index 000000000..c28e23fd7
--- /dev/null
+++ b/pkg/criu/criu_linux.go
@@ -0,0 +1,44 @@
+//go:build linux
+// +build linux
+
+package criu
+
+import (
+ "github.com/checkpoint-restore/go-criu/v5"
+ "github.com/checkpoint-restore/go-criu/v5/rpc"
+
+ "google.golang.org/protobuf/proto"
+)
+
+// CheckForCriu uses CRIU's go bindings to check if the CRIU
+// binary exists and if it at least the version Podman needs.
+func CheckForCriu(version int) bool {
+ c := criu.MakeCriu()
+ result, err := c.IsCriuAtLeast(version)
+ if err != nil {
+ return false
+ }
+ return result
+}
+
+func MemTrack() bool {
+ features, err := criu.MakeCriu().FeatureCheck(
+ &rpc.CriuFeatures{
+ MemTrack: proto.Bool(true),
+ },
+ )
+ if err != nil {
+ return false
+ }
+
+ if features == nil || features.MemTrack == nil {
+ return false
+ }
+
+ return *features.MemTrack
+}
+
+func GetCriuVersion() (int, error) {
+ c := criu.MakeCriu()
+ return c.GetCriuVersion()
+}
diff --git a/pkg/criu/criu_unsupported.go b/pkg/criu/criu_unsupported.go
index 3e3ed9c6c..437482a0e 100644
--- a/pkg/criu/criu_unsupported.go
+++ b/pkg/criu/criu_unsupported.go
@@ -3,6 +3,14 @@
package criu
+func CheckForCriu(version int) bool {
+ return false
+}
+
func MemTrack() bool {
return false
}
+
+func GetCriuVersion() (int, error) {
+ return MinCriuVersion, nil
+}
diff --git a/pkg/ctime/ctime_linux.go b/pkg/ctime/ctime_linux.go
index 7eb3caa6d..bf3cd5752 100644
--- a/pkg/ctime/ctime_linux.go
+++ b/pkg/ctime/ctime_linux.go
@@ -11,6 +11,6 @@ import (
func created(fi os.FileInfo) time.Time {
st := fi.Sys().(*syscall.Stat_t)
- //nolint
+ //nolint:unconvert // need to type cast on some cpu architectures
return time.Unix(int64(st.Ctim.Sec), int64(st.Ctim.Nsec))
}
diff --git a/pkg/domain/entities/containers.go b/pkg/domain/entities/containers.go
index 750f49590..17408f12f 100644
--- a/pkg/domain/entities/containers.go
+++ b/pkg/domain/entities/containers.go
@@ -56,7 +56,7 @@ type WaitOptions struct {
}
type WaitReport struct {
- Id string //nolint
+ Id string //nolint:revive,stylecheck
Error error
ExitCode int32
}
@@ -76,7 +76,7 @@ type PauseUnPauseOptions struct {
type PauseUnpauseReport struct {
Err error
- Id string //nolint
+ Id string //nolint:revive,stylecheck
}
type StopOptions struct {
@@ -88,7 +88,7 @@ type StopOptions struct {
type StopReport struct {
Err error
- Id string //nolint
+ Id string //nolint:revive,stylecheck
RawInput string
}
@@ -110,7 +110,7 @@ type KillOptions struct {
type KillReport struct {
Err error
- Id string //nolint
+ Id string //nolint:revive,stylecheck
RawInput string
}
@@ -123,7 +123,7 @@ type RestartOptions struct {
type RestartReport struct {
Err error
- Id string //nolint
+ Id string //nolint:revive,stylecheck
}
type RmOptions struct {
@@ -170,7 +170,7 @@ type CopyOptions struct {
}
type CommitReport struct {
- Id string //nolint
+ Id string //nolint:revive,stylecheck
}
type ContainerExportOptions struct {
@@ -196,7 +196,7 @@ type CheckpointOptions struct {
type CheckpointReport struct {
Err error `json:"-"`
- Id string `json:"Id` //nolint
+ Id string `json:"Id"` //nolint:revive,stylecheck
RuntimeDuration int64 `json:"runtime_checkpoint_duration"`
CRIUStatistics *define.CRIUCheckpointRestoreStatistics `json:"criu_statistics"`
}
@@ -222,13 +222,13 @@ type RestoreOptions struct {
type RestoreReport struct {
Err error `json:"-"`
- Id string `json:"Id` //nolint
+ Id string `json:"Id"` //nolint:revive,stylecheck
RuntimeDuration int64 `json:"runtime_restore_duration"`
CRIUStatistics *define.CRIUCheckpointRestoreStatistics `json:"criu_statistics"`
}
type ContainerCreateReport struct {
- Id string //nolint
+ Id string //nolint:revive,stylecheck
}
// AttachOptions describes the cli and other values
@@ -307,7 +307,7 @@ type ContainerStartOptions struct {
// ContainerStartReport describes the response from starting
// containers from the cli
type ContainerStartReport struct {
- Id string //nolint
+ Id string //nolint:revive,stylecheck
RawInput string
Err error
ExitCode int
@@ -351,7 +351,7 @@ type ContainerRunOptions struct {
// a container
type ContainerRunReport struct {
ExitCode int
- Id string //nolint
+ Id string //nolint:revive,stylecheck
}
// ContainerCleanupOptions are the CLI values for the
@@ -368,7 +368,7 @@ type ContainerCleanupOptions struct {
// container cleanup
type ContainerCleanupReport struct {
CleanErr error
- Id string //nolint
+ Id string //nolint:revive,stylecheck
RmErr error
RmiErr error
}
@@ -384,7 +384,7 @@ type ContainerInitOptions struct {
// container init
type ContainerInitReport struct {
Err error
- Id string //nolint
+ Id string //nolint:revive,stylecheck
}
// ContainerMountOptions describes the input values for mounting containers
@@ -406,7 +406,7 @@ type ContainerUnmountOptions struct {
// ContainerMountReport describes the response from container mount
type ContainerMountReport struct {
Err error
- Id string //nolint
+ Id string //nolint:revive,stylecheck
Name string
Path string
}
@@ -414,7 +414,7 @@ type ContainerMountReport struct {
// ContainerUnmountReport describes the response from umounting a container
type ContainerUnmountReport struct {
Err error
- Id string //nolint
+ Id string //nolint:revive,stylecheck
}
// ContainerPruneOptions describes the options needed
@@ -433,7 +433,7 @@ type ContainerPortOptions struct {
// ContainerPortReport describes the output needed for
// the CLI to output ports
type ContainerPortReport struct {
- Id string //nolint
+ Id string //nolint:revive,stylecheck
Ports []nettypes.PortMapping
}
diff --git a/pkg/domain/entities/engine_container.go b/pkg/domain/entities/engine_container.go
index 6b70a3452..df42876f6 100644
--- a/pkg/domain/entities/engine_container.go
+++ b/pkg/domain/entities/engine_container.go
@@ -71,6 +71,7 @@ type ContainerEngine interface {
PlayKube(ctx context.Context, body io.Reader, opts PlayKubeOptions) (*PlayKubeReport, error)
PlayKubeDown(ctx context.Context, body io.Reader, opts PlayKubeDownOptions) (*PlayKubeReport, error)
PodCreate(ctx context.Context, specg PodSpec) (*PodCreateReport, error)
+ PodClone(ctx context.Context, podClone PodCloneOptions) (*PodCloneReport, error)
PodExists(ctx context.Context, nameOrID string) (*BoolReport, error)
PodInspect(ctx context.Context, options PodInspectOptions) (*PodInspectReport, error)
PodKill(ctx context.Context, namesOrIds []string, options PodKillOptions) ([]*PodKillReport, error)
diff --git a/pkg/domain/entities/images.go b/pkg/domain/entities/images.go
index 2bb4ceb5b..11f6e8687 100644
--- a/pkg/domain/entities/images.go
+++ b/pkg/domain/entities/images.go
@@ -46,14 +46,14 @@ type Image struct {
HealthCheck *manifest.Schema2HealthConfig `json:",omitempty"`
}
-func (i *Image) Id() string { // nolint
+func (i *Image) Id() string { //nolint:revive,stylecheck
return i.ID
}
// swagger:model LibpodImageSummary
type ImageSummary struct {
ID string `json:"Id"`
- ParentId string // nolint
+ ParentId string //nolint:revive,stylecheck
RepoTags []string
RepoDigests []string
Created int64
@@ -71,7 +71,7 @@ type ImageSummary struct {
History []string `json:",omitempty"`
}
-func (i *ImageSummary) Id() string { // nolint
+func (i *ImageSummary) Id() string { //nolint:revive,stylecheck
return i.ID
}
@@ -290,7 +290,7 @@ type ImageImportOptions struct {
}
type ImageImportReport struct {
- Id string // nolint
+ Id string //nolint:revive,stylecheck
}
// ImageSaveOptions provide options for saving images.
@@ -397,7 +397,7 @@ type ImageUnmountOptions struct {
// ImageMountReport describes the response from image mount
type ImageMountReport struct {
- Id string // nolint
+ Id string //nolint:revive,stylecheck
Name string
Repositories []string
Path string
@@ -406,5 +406,5 @@ type ImageMountReport struct {
// ImageUnmountReport describes the response from umounting an image
type ImageUnmountReport struct {
Err error
- Id string // nolint
+ Id string //nolint:revive,stylecheck
}
diff --git a/pkg/domain/entities/network.go b/pkg/domain/entities/network.go
index 0f901c7f1..d375c2e20 100644
--- a/pkg/domain/entities/network.go
+++ b/pkg/domain/entities/network.go
@@ -22,7 +22,7 @@ type NetworkReloadOptions struct {
// NetworkReloadReport describes the results of reloading a container network.
type NetworkReloadReport struct {
- // nolint:stylecheck,revive
+ //nolint:stylecheck,revive
Id string
Err error
}
diff --git a/pkg/domain/entities/pods.go b/pkg/domain/entities/pods.go
index 9cbbe2bf1..14ce370c1 100644
--- a/pkg/domain/entities/pods.go
+++ b/pkg/domain/entities/pods.go
@@ -20,15 +20,15 @@ type PodKillOptions struct {
type PodKillReport struct {
Errs []error
- Id string // nolint
+ Id string //nolint:revive,stylecheck
}
type ListPodsReport struct {
Cgroup string
Containers []*ListPodContainer
Created time.Time
- Id string // nolint
- InfraId string // nolint
+ Id string //nolint:revive,stylecheck
+ InfraId string //nolint:revive,stylecheck
Name string
Namespace string
// Network names connected to infra container
@@ -38,7 +38,7 @@ type ListPodsReport struct {
}
type ListPodContainer struct {
- Id string // nolint
+ Id string //nolint:revive,stylecheck
Names string
Status string
}
@@ -50,7 +50,7 @@ type PodPauseOptions struct {
type PodPauseReport struct {
Errs []error
- Id string // nolint
+ Id string //nolint:revive,stylecheck
}
type PodunpauseOptions struct {
@@ -60,7 +60,7 @@ type PodunpauseOptions struct {
type PodUnpauseReport struct {
Errs []error
- Id string // nolint
+ Id string //nolint:revive,stylecheck
}
type PodStopOptions struct {
@@ -72,7 +72,7 @@ type PodStopOptions struct {
type PodStopReport struct {
Errs []error
- Id string // nolint
+ Id string //nolint:revive,stylecheck
}
type PodRestartOptions struct {
@@ -82,7 +82,7 @@ type PodRestartOptions struct {
type PodRestartReport struct {
Errs []error
- Id string // nolint
+ Id string //nolint:revive,stylecheck
}
type PodStartOptions struct {
@@ -92,7 +92,7 @@ type PodStartOptions struct {
type PodStartReport struct {
Errs []error
- Id string // nolint
+ Id string //nolint:revive,stylecheck
}
type PodRmOptions struct {
@@ -105,7 +105,7 @@ type PodRmOptions struct {
type PodRmReport struct {
Err error
- Id string // nolint
+ Id string //nolint:revive,stylecheck
}
// PddSpec is an abstracted version of PodSpecGen designed to eventually accept options
@@ -154,6 +154,16 @@ type PodLogsOptions struct {
Color bool
}
+// PodCloneOptions contains options for cloning an existing pod
+type PodCloneOptions struct {
+ ID string
+ Destroy bool
+ CreateOpts PodCreateOptions
+ InfraOptions ContainerCreateOptions
+ PerContainerOptions ContainerCreateOptions
+ Start bool
+}
+
type ContainerCreateOptions struct {
Annotation []string
Attach []string
@@ -287,7 +297,11 @@ func NewInfraContainerCreateOptions() ContainerCreateOptions {
}
type PodCreateReport struct {
- Id string // nolint
+ Id string //nolint:revive,stylecheck
+}
+
+type PodCloneReport struct {
+ Id string //nolint:revive,stylecheck
}
func (p *PodCreateOptions) CPULimits() *specs.LinuxCPU {
@@ -389,7 +403,7 @@ type PodPruneOptions struct {
type PodPruneReport struct {
Err error
- Id string // nolint
+ Id string //nolint:revive,stylecheck
}
type PodTopOptions struct {
diff --git a/pkg/domain/entities/reports/containers.go b/pkg/domain/entities/reports/containers.go
index 54bcd092b..db9a66012 100644
--- a/pkg/domain/entities/reports/containers.go
+++ b/pkg/domain/entities/reports/containers.go
@@ -1,7 +1,7 @@
package reports
type RmReport struct {
- Id string `json:"Id"` //nolint
+ Id string `json:"Id"` //nolint:revive,stylecheck
Err error `json:"Err,omitempty"`
}
diff --git a/pkg/domain/entities/reports/prune.go b/pkg/domain/entities/reports/prune.go
index 497e5d606..ac3d8e7ce 100644
--- a/pkg/domain/entities/reports/prune.go
+++ b/pkg/domain/entities/reports/prune.go
@@ -1,7 +1,7 @@
package reports
type PruneReport struct {
- Id string `json:"Id"` //nolint
+ Id string `json:"Id"` //nolint:revive,stylecheck
Err error `json:"Err,omitempty"`
Size uint64 `json:"Size"`
}
diff --git a/pkg/domain/entities/system.go b/pkg/domain/entities/system.go
index 21026477d..331d2bcdc 100644
--- a/pkg/domain/entities/system.go
+++ b/pkg/domain/entities/system.go
@@ -28,6 +28,7 @@ type SystemPruneReport struct {
PodPruneReport []*PodPruneReport
ContainerPruneReports []*reports.PruneReport
ImagePruneReports []*reports.PruneReport
+ NetworkPruneReports []*reports.PruneReport
VolumePruneReports []*reports.PruneReport
ReclaimedSpace uint64
}
diff --git a/pkg/domain/entities/types.go b/pkg/domain/entities/types.go
index 3e6e54e7d..44df66498 100644
--- a/pkg/domain/entities/types.go
+++ b/pkg/domain/entities/types.go
@@ -21,7 +21,7 @@ type Volume struct {
}
type Report struct {
- Id []string // nolint
+ Id []string //nolint:revive,stylecheck
Err map[string]error
}
diff --git a/pkg/domain/entities/volumes.go b/pkg/domain/entities/volumes.go
index 84f85b83f..556df16c1 100644
--- a/pkg/domain/entities/volumes.go
+++ b/pkg/domain/entities/volumes.go
@@ -33,7 +33,7 @@ type VolumeRmOptions struct {
type VolumeRmReport struct {
Err error
- Id string // nolint
+ Id string //nolint:revive,stylecheck
}
type VolumeInspectReport struct {
@@ -61,7 +61,7 @@ type VolumeListReport struct {
// VolumeMountReport describes the response from volume mount
type VolumeMountReport struct {
Err error
- Id string // nolint
+ Id string //nolint:revive,stylecheck
Name string
Path string
}
@@ -69,5 +69,5 @@ type VolumeMountReport struct {
// VolumeUnmountReport describes the response from umounting a volume
type VolumeUnmountReport struct {
Err error
- Id string // nolint
+ Id string //nolint:revive,stylecheck
}
diff --git a/pkg/domain/infra/abi/containers.go b/pkg/domain/infra/abi/containers.go
index 8bd84a310..281e448f6 100644
--- a/pkg/domain/infra/abi/containers.go
+++ b/pkg/domain/infra/abi/containers.go
@@ -16,7 +16,6 @@ import (
"github.com/containers/image/v5/manifest"
"github.com/containers/podman/v4/libpod"
"github.com/containers/podman/v4/libpod/define"
- "github.com/containers/podman/v4/libpod/events"
"github.com/containers/podman/v4/libpod/logs"
"github.com/containers/podman/v4/pkg/checkpoint"
"github.com/containers/podman/v4/pkg/domain/entities"
@@ -38,7 +37,7 @@ import (
)
// getContainersAndInputByContext gets containers whether all, latest, or a slice of names/ids
-// is specified. It also returns a list of the corresponding input name used to lookup each container.
+// is specified. It also returns a list of the corresponding input name used to look up each container.
func getContainersAndInputByContext(all, latest bool, names []string, runtime *libpod.Runtime) (ctrs []*libpod.Container, rawInput []string, err error) {
var ctr *libpod.Container
ctrs = []*libpod.Container{}
@@ -183,7 +182,7 @@ func (ic *ContainerEngine) ContainerStop(ctx context.Context, namesOrIds []strin
if err != nil {
// Issue #7384 and #11384: If the container is configured for
// auto-removal, it might already have been removed at this point.
- // We still need to to cleanup since we do not know if the other cleanup process is successful
+ // We still need to clean up since we do not know if the other cleanup process is successful
if c.AutoRemove() && (errors.Is(err, define.ErrNoSuchCtr) || errors.Is(err, define.ErrCtrRemoved)) {
return nil
}
@@ -488,7 +487,7 @@ func (ic *ContainerEngine) ContainerTop(ctx context.Context, options entities.To
container, err = ic.Libpod.LookupContainer(options.NameOrID)
}
if err != nil {
- return nil, errors.Wrap(err, "unable to lookup requested container")
+ return nil, errors.Wrap(err, "unable to look up requested container")
}
// Run Top.
@@ -635,13 +634,13 @@ func (ic *ContainerEngine) ContainerRestore(ctx context.Context, namesOrIds []st
containers, err = getContainersByContext(false, options.Latest, namesOrIds, ic.Libpod)
default:
for _, nameOrID := range namesOrIds {
- logrus.Debugf("lookup container: %q", nameOrID)
+ logrus.Debugf("look up container: %q", nameOrID)
ctr, err := ic.Libpod.LookupContainer(nameOrID)
if err == nil {
containers = append(containers, ctr)
} else {
// If container was not found, check if this is a checkpoint image
- logrus.Debugf("lookup image: %q", nameOrID)
+ logrus.Debugf("look up image: %q", nameOrID)
img, _, err := ic.Libpod.LibimageRuntime().LookupImage(nameOrID, nil)
if err != nil {
return nil, fmt.Errorf("no such container or image: %s", nameOrID)
@@ -939,6 +938,7 @@ func (ic *ContainerEngine) ContainerStart(ctx context.Context, namesOrIds []stri
}
return reports, errors.Wrapf(err, "unable to start container %s", ctr.ID())
}
+
exitCode = ic.GetContainerExitCode(ctx, ctr)
reports = append(reports, &entities.ContainerStartReport{
Id: ctr.ID(),
@@ -1099,25 +1099,11 @@ func (ic *ContainerEngine) ContainerRun(ctx context.Context, opts entities.Conta
func (ic *ContainerEngine) GetContainerExitCode(ctx context.Context, ctr *libpod.Container) int {
exitCode, err := ctr.Wait(ctx)
- if err == nil {
- return int(exitCode)
- }
- if errors.Cause(err) != define.ErrNoSuchCtr {
- logrus.Errorf("Could not retrieve exit code: %v", err)
+ if err != nil {
+ logrus.Errorf("Waiting for container %s: %v", ctr.ID(), err)
return define.ExecErrorCodeNotFound
}
- // Make 4 attempt with 0.25s backoff between each for 1 second total
- var event *events.Event
- for i := 0; i < 4; i++ {
- event, err = ic.Libpod.GetLastContainerEvent(ctx, ctr.ID(), events.Exited)
- if err != nil {
- time.Sleep(250 * time.Millisecond)
- continue
- }
- return event.ContainerExitCode
- }
- logrus.Errorf("Could not retrieve exit code from event: %v", err)
- return define.ExecErrorCodeNotFound
+ return int(exitCode)
}
func (ic *ContainerEngine) ContainerLogs(ctx context.Context, containers []string, options entities.ContainerLogsOptions) error {
@@ -1194,12 +1180,12 @@ func (ic *ContainerEngine) ContainerCleanup(ctx context.Context, namesOrIds []st
var timeout *uint
err = ic.Libpod.RemoveContainer(ctx, ctr, false, true, timeout)
if err != nil {
- report.RmErr = errors.Wrapf(err, "failed to cleanup and remove container %v", ctr.ID())
+ report.RmErr = errors.Wrapf(err, "failed to clean up and remove container %v", ctr.ID())
}
} else {
err := ctr.Cleanup(ctx)
if err != nil {
- report.CleanErr = errors.Wrapf(err, "failed to cleanup container %v", ctr.ID())
+ report.CleanErr = errors.Wrapf(err, "failed to clean up container %v", ctr.ID())
}
}
@@ -1593,6 +1579,11 @@ func (ic *ContainerEngine) ContainerClone(ctx context.Context, ctrCloneOpts enti
return nil, err
}
+ conf := c.Config()
+ if conf.Spec != nil && conf.Spec.Process != nil && conf.Spec.Process.Terminal { // if we do not pass term, running ctrs exit
+ spec.Terminal = true
+ }
+
// Print warnings
if len(out) > 0 {
for _, w := range out {
@@ -1612,8 +1603,8 @@ func (ic *ContainerEngine) ContainerClone(ctx context.Context, ctrCloneOpts enti
switch {
case strings.Contains(n, "-clone"):
ind := strings.Index(n, "-clone") + 6
- num, _ := strconv.Atoi(n[ind:])
- if num == 0 { // clone1 is hard to get with this logic, just check for it here.
+ num, err := strconv.Atoi(n[ind:])
+ if num == 0 && err != nil { // clone1 is hard to get with this logic, just check for it here.
_, err = ic.Libpod.LookupContainer(n + "1")
if err != nil {
spec.Name = n + "1"
diff --git a/pkg/domain/infra/abi/images.go b/pkg/domain/infra/abi/images.go
index d469fa0ca..d63de2424 100644
--- a/pkg/domain/infra/abi/images.go
+++ b/pkg/domain/infra/abi/images.go
@@ -593,7 +593,7 @@ func (ir *ImageEngine) Remove(ctx context.Context, images []string, opts entitie
rmErrors = libimageErrors
- return //nolint
+ return
}
// Shutdown Libpod engine
diff --git a/pkg/domain/infra/abi/network.go b/pkg/domain/infra/abi/network.go
index 47f7917f4..8b95607f4 100644
--- a/pkg/domain/infra/abi/network.go
+++ b/pkg/domain/infra/abi/network.go
@@ -2,6 +2,7 @@ package abi
import (
"context"
+ "strconv"
"github.com/containers/common/libnetwork/types"
netutil "github.com/containers/common/libnetwork/util"
@@ -12,10 +13,39 @@ import (
)
func (ic *ContainerEngine) NetworkList(ctx context.Context, options entities.NetworkListOptions) ([]types.Network, error) {
+ // dangling filter is not provided by netutil
+ var wantDangling bool
+
+ val, filterDangling := options.Filters["dangling"]
+ if filterDangling {
+ switch len(val) {
+ case 0:
+ return nil, errors.Errorf("got no values for filter key \"dangling\"")
+ case 1:
+ var err error
+ wantDangling, err = strconv.ParseBool(val[0])
+ if err != nil {
+ return nil, errors.Errorf("invalid dangling filter value \"%v\"", val[0])
+ }
+ delete(options.Filters, "dangling")
+ default:
+ return nil, errors.Errorf("got more than one value for filter key \"dangling\"")
+ }
+ }
+
filters, err := netutil.GenerateNetworkFilters(options.Filters)
if err != nil {
return nil, err
}
+
+ if filterDangling {
+ danglingFilterFunc, err := ic.createDanglingFilterFunc(wantDangling)
+ if err != nil {
+ return nil, err
+ }
+
+ filters = append(filters, danglingFilterFunc)
+ }
nets, err := ic.Libpod.Network().NetworkList(filters...)
return nets, err
}
@@ -142,8 +172,35 @@ func (ic *ContainerEngine) NetworkExists(ctx context.Context, networkname string
}, nil
}
-// Network prune removes unused cni networks
+// Network prune removes unused networks
func (ic *ContainerEngine) NetworkPrune(ctx context.Context, options entities.NetworkPruneOptions) ([]*entities.NetworkPruneReport, error) {
+ // get all filters
+ filters, err := netutil.GenerateNetworkPruneFilters(options.Filters)
+ if err != nil {
+ return nil, err
+ }
+ danglingFilterFunc, err := ic.createDanglingFilterFunc(true)
+ if err != nil {
+ return nil, err
+ }
+ filters = append(filters, danglingFilterFunc)
+ nets, err := ic.Libpod.Network().NetworkList(filters...)
+ if err != nil {
+ return nil, err
+ }
+
+ pruneReport := make([]*entities.NetworkPruneReport, 0, len(nets))
+ for _, net := range nets {
+ pruneReport = append(pruneReport, &entities.NetworkPruneReport{
+ Name: net.Name,
+ Error: ic.Libpod.Network().NetworkRemove(net.Name),
+ })
+ }
+ return pruneReport, nil
+}
+
+// danglingFilter function is special and not implemented in libnetwork filters
+func (ic *ContainerEngine) createDanglingFilterFunc(wantDangling bool) (types.FilterFunc, error) {
cons, err := ic.Libpod.GetAllContainers()
if err != nil {
return nil, err
@@ -163,31 +220,12 @@ func (ic *ContainerEngine) NetworkPrune(ctx context.Context, options entities.Ne
// ignore the default network, this one cannot be deleted
networksToKeep[ic.Libpod.GetDefaultNetworkName()] = true
- // get all filters
- filters, err := netutil.GenerateNetworkPruneFilters(options.Filters)
- if err != nil {
- return nil, err
- }
- danglingFilterFunc := func(net types.Network) bool {
+ return func(net types.Network) bool {
for network := range networksToKeep {
if network == net.Name {
- return false
+ return !wantDangling
}
}
- return true
- }
- filters = append(filters, danglingFilterFunc)
- nets, err := ic.Libpod.Network().NetworkList(filters...)
- if err != nil {
- return nil, err
- }
-
- pruneReport := make([]*entities.NetworkPruneReport, 0, len(nets))
- for _, net := range nets {
- pruneReport = append(pruneReport, &entities.NetworkPruneReport{
- Name: net.Name,
- Error: ic.Libpod.Network().NetworkRemove(net.Name),
- })
- }
- return pruneReport, nil
+ return wantDangling
+ }, nil
}
diff --git a/pkg/domain/infra/abi/play.go b/pkg/domain/infra/abi/play.go
index e04ab3a1a..e14a819fa 100644
--- a/pkg/domain/infra/abi/play.go
+++ b/pkg/domain/infra/abi/play.go
@@ -31,7 +31,7 @@ import (
"github.com/opencontainers/go-digest"
"github.com/pkg/errors"
"github.com/sirupsen/logrus"
- yamlv2 "gopkg.in/yaml.v2"
+ yamlv3 "gopkg.in/yaml.v3"
)
// createServiceContainer creates a container that can later on
@@ -790,7 +790,7 @@ func readConfigMapFromFile(r io.Reader) (v1.ConfigMap, error) {
func splitMultiDocYAML(yamlContent []byte) ([][]byte, error) {
var documentList [][]byte
- d := yamlv2.NewDecoder(bytes.NewReader(yamlContent))
+ d := yamlv3.NewDecoder(bytes.NewReader(yamlContent))
for {
var o interface{}
// read individual document
@@ -804,7 +804,7 @@ func splitMultiDocYAML(yamlContent []byte) ([][]byte, error) {
if o != nil {
// back to bytes
- document, err := yamlv2.Marshal(o)
+ document, err := yamlv3.Marshal(o)
if err != nil {
return nil, errors.Wrapf(err, "individual doc yaml could not be marshalled")
}
diff --git a/pkg/domain/infra/abi/pods.go b/pkg/domain/infra/abi/pods.go
index 32deb20e0..3e9cb7f5e 100644
--- a/pkg/domain/infra/abi/pods.go
+++ b/pkg/domain/infra/abi/pods.go
@@ -2,12 +2,15 @@ package abi
import (
"context"
+ "strconv"
+ "strings"
"github.com/containers/podman/v4/libpod"
"github.com/containers/podman/v4/libpod/define"
"github.com/containers/podman/v4/pkg/domain/entities"
dfilters "github.com/containers/podman/v4/pkg/domain/filters"
"github.com/containers/podman/v4/pkg/signal"
+ "github.com/containers/podman/v4/pkg/specgen"
"github.com/containers/podman/v4/pkg/specgen/generate"
"github.com/pkg/errors"
"github.com/sirupsen/logrus"
@@ -295,6 +298,88 @@ func (ic *ContainerEngine) PodCreate(ctx context.Context, specg entities.PodSpec
return &entities.PodCreateReport{Id: pod.ID()}, nil
}
+func (ic *ContainerEngine) PodClone(ctx context.Context, podClone entities.PodCloneOptions) (*entities.PodCloneReport, error) {
+ spec := specgen.NewPodSpecGenerator()
+ p, err := generate.PodConfigToSpec(ic.Libpod, spec, &podClone.InfraOptions, podClone.ID)
+ if err != nil {
+ return nil, err
+ }
+
+ if len(podClone.CreateOpts.Name) > 0 {
+ spec.Name = podClone.CreateOpts.Name
+ } else {
+ n := p.Name()
+ _, err := ic.Libpod.LookupPod(n + "-clone")
+ if err == nil {
+ n += "-clone"
+ }
+ switch {
+ case strings.Contains(n, "-clone"): // meaning this name is taken!
+ ind := strings.Index(n, "-clone") + 6
+ num, err := strconv.Atoi(n[ind:])
+ if num == 0 && err != nil { // meaning invalid
+ _, err = ic.Libpod.LookupPod(n + "1")
+ if err != nil {
+ spec.Name = n + "1"
+ break
+ }
+ } else { // else we already have a number
+ n = n[0:ind]
+ }
+ err = nil
+ count := num
+ for err == nil { // until we cannot find a pod w/ this name, increment num and try again
+ count++
+ tempN := n + strconv.Itoa(count)
+ _, err = ic.Libpod.LookupPod(tempN)
+ }
+ n += strconv.Itoa(count)
+ spec.Name = n
+ default:
+ spec.Name = p.Name() + "-clone"
+ }
+ }
+
+ podSpec := entities.PodSpec{PodSpecGen: *spec}
+ pod, err := generate.MakePod(&podSpec, ic.Libpod)
+ if err != nil {
+ return nil, err
+ }
+
+ ctrs, err := p.AllContainers()
+ if err != nil {
+ return nil, err
+ }
+ for _, ctr := range ctrs {
+ if ctr.IsInfra() {
+ continue // already copied infra
+ }
+
+ podClone.PerContainerOptions.Pod = pod.ID()
+ _, err := ic.ContainerClone(ctx, entities.ContainerCloneOptions{ID: ctr.ID(), CreateOpts: podClone.PerContainerOptions})
+ if err != nil {
+ return nil, err
+ }
+ }
+
+ if podClone.Destroy {
+ var timeout *uint
+ err = ic.Libpod.RemovePod(ctx, p, true, true, timeout)
+ if err != nil {
+ return &entities.PodCloneReport{Id: pod.ID()}, err
+ }
+ }
+
+ if podClone.Start {
+ _, err := ic.PodStart(ctx, []string{pod.ID()}, entities.PodStartOptions{})
+ if err != nil {
+ return &entities.PodCloneReport{Id: pod.ID()}, err
+ }
+ }
+
+ return &entities.PodCloneReport{Id: pod.ID()}, nil
+}
+
func (ic *ContainerEngine) PodTop(ctx context.Context, options entities.PodTopOptions) (*entities.StringSliceReport, error) {
var (
pod *libpod.Pod
@@ -308,7 +393,7 @@ func (ic *ContainerEngine) PodTop(ctx context.Context, options entities.PodTopOp
pod, err = ic.Libpod.LookupPod(options.NameOrID)
}
if err != nil {
- return nil, errors.Wrap(err, "unable to lookup requested container")
+ return nil, errors.Wrap(err, "unable to look up requested container")
}
// Run Top.
@@ -409,7 +494,7 @@ func (ic *ContainerEngine) PodInspect(ctx context.Context, options entities.PodI
pod, err = ic.Libpod.LookupPod(options.NameOrID)
}
if err != nil {
- return nil, errors.Wrap(err, "unable to lookup requested container")
+ return nil, errors.Wrap(err, "unable to look up requested container")
}
inspect, err := pod.Inspect()
if err != nil {
diff --git a/pkg/domain/infra/abi/system.go b/pkg/domain/infra/abi/system.go
index 762f0d79a..6e26026d4 100644
--- a/pkg/domain/infra/abi/system.go
+++ b/pkg/domain/infra/abi/system.go
@@ -125,8 +125,14 @@ func (ic *ContainerEngine) SetupRootless(_ context.Context, noMoveProcess bool)
paths = append(paths, ctr.Config().ConmonPidFile)
}
- became, ret, err = rootless.TryJoinFromFilePaths(pausePidPath, true, paths)
- utils.MovePauseProcessToScope(pausePidPath)
+ if len(paths) > 0 {
+ became, ret, err = rootless.TryJoinFromFilePaths(pausePidPath, true, paths)
+ } else {
+ became, ret, err = rootless.BecomeRootInUserNS(pausePidPath)
+ if err == nil {
+ utils.MovePauseProcessToScope(pausePidPath)
+ }
+ }
if err != nil {
logrus.Error(errors.Wrapf(err, "invalid internal status, try resetting the pause process with %q", os.Args[0]+" system migrate"))
os.Exit(1)
@@ -137,7 +143,7 @@ func (ic *ContainerEngine) SetupRootless(_ context.Context, noMoveProcess bool)
return nil
}
-// SystemPrune removes unused data from the system. Pruning pods, containers, volumes and images.
+// SystemPrune removes unused data from the system. Pruning pods, containers, networks, volumes and images.
func (ic *ContainerEngine) SystemPrune(ctx context.Context, options entities.SystemPruneOptions) (*entities.SystemPruneReport, error) {
var systemPruneReport = new(entities.SystemPruneReport)
filters := []string{}
@@ -148,6 +154,9 @@ func (ic *ContainerEngine) SystemPrune(ctx context.Context, options entities.Sys
found := true
for found {
found = false
+
+ // TODO: Figure out cleaner way to handle all of the different PruneOptions
+ // Remove all unused pods.
podPruneReport, err := ic.prunePodHelper(ctx)
if err != nil {
return nil, err
@@ -155,9 +164,10 @@ func (ic *ContainerEngine) SystemPrune(ctx context.Context, options entities.Sys
if len(podPruneReport) > 0 {
found = true
}
+
systemPruneReport.PodPruneReport = append(systemPruneReport.PodPruneReport, podPruneReport...)
- // TODO: Figure out cleaner way to handle all of the different PruneOptions
+ // Remove all unused containers.
containerPruneOptions := entities.ContainerPruneOptions{}
containerPruneOptions.Filters = (url.Values)(options.Filters)
@@ -165,16 +175,18 @@ func (ic *ContainerEngine) SystemPrune(ctx context.Context, options entities.Sys
if err != nil {
return nil, err
}
+
reclaimedSpace += reports.PruneReportsSize(containerPruneReports)
systemPruneReport.ContainerPruneReports = append(systemPruneReport.ContainerPruneReports, containerPruneReports...)
+
+ // Remove all unused images.
imagePruneOptions := entities.ImagePruneOptions{
All: options.All,
Filter: filters,
}
+
imageEngine := ImageEngine{Libpod: ic.Libpod}
imagePruneReports, err := imageEngine.Prune(ctx, imagePruneOptions)
- reclaimedSpace += reports.PruneReportsSize(imagePruneReports)
-
if err != nil {
return nil, err
}
@@ -182,10 +194,33 @@ func (ic *ContainerEngine) SystemPrune(ctx context.Context, options entities.Sys
found = true
}
+ reclaimedSpace += reports.PruneReportsSize(imagePruneReports)
systemPruneReport.ImagePruneReports = append(systemPruneReport.ImagePruneReports, imagePruneReports...)
+
+ // Remove all unused networks.
+ networkPruneOptions := entities.NetworkPruneOptions{}
+ networkPruneOptions.Filters = options.Filters
+
+ networkPruneReport, err := ic.NetworkPrune(ctx, networkPruneOptions)
+ if err != nil {
+ return nil, err
+ }
+ if len(networkPruneReport) > 0 {
+ found = true
+ }
+ for _, net := range networkPruneReport {
+ systemPruneReport.NetworkPruneReports = append(systemPruneReport.NetworkPruneReports, &reports.PruneReport{
+ Id: net.Name,
+ Err: net.Error,
+ Size: 0,
+ })
+ }
+
+ // Remove unused volume data.
if options.Volume {
volumePruneOptions := entities.VolumePruneOptions{}
volumePruneOptions.Filters = (url.Values)(options.Filters)
+
volumePruneReport, err := ic.VolumePrune(ctx, volumePruneOptions)
if err != nil {
return nil, err
@@ -193,6 +228,7 @@ func (ic *ContainerEngine) SystemPrune(ctx context.Context, options entities.Sys
if len(volumePruneReport) > 0 {
found = true
}
+
reclaimedSpace += reports.PruneReportsSize(volumePruneReport)
systemPruneReport.VolumePruneReports = append(systemPruneReport.VolumePruneReports, volumePruneReport...)
}
@@ -368,9 +404,9 @@ func (ic *ContainerEngine) Unshare(ctx context.Context, args []string, options e
}
// Make sure to unlock, unshare can run for a long time.
rootlessNetNS.Lock.Unlock()
- // We do not want to cleanup the netns after unshare.
- // The problem is that we cannot know if we need to cleanup and
- // secondly unshare should allow user to setup the namespace with
+ // We do not want to clean up the netns after unshare.
+ // The problem is that we cannot know if we need to clean up and
+ // secondly unshare should allow user to set up the namespace with
// special things, e.g. potentially macvlan or something like that.
return rootlessNetNS.Do(unshare)
}
diff --git a/pkg/domain/infra/abi/terminal/sigproxy_linux.go b/pkg/domain/infra/abi/terminal/sigproxy_linux.go
index fe2c268c0..e02c0532c 100644
--- a/pkg/domain/infra/abi/terminal/sigproxy_linux.go
+++ b/pkg/domain/infra/abi/terminal/sigproxy_linux.go
@@ -20,7 +20,7 @@ const signalBufferSize = 2048
func ProxySignals(ctr *libpod.Container) {
// Stop catching the shutdown signals (SIGINT, SIGTERM) - they're going
// to the container now.
- shutdown.Stop() // nolint: errcheck
+ shutdown.Stop() //nolint: errcheck
sigBuffer := make(chan os.Signal, signalBufferSize)
signal.CatchAll(sigBuffer)
diff --git a/pkg/domain/infra/abi/volumes.go b/pkg/domain/infra/abi/volumes.go
index f59f11e20..a9c53c140 100644
--- a/pkg/domain/infra/abi/volumes.go
+++ b/pkg/domain/infra/abi/volumes.go
@@ -172,7 +172,7 @@ func (ic *ContainerEngine) VolumeMounted(ctx context.Context, nameOrID string) (
mountCount, err := vol.MountCount()
if err != nil {
// FIXME: this error should probably be returned
- return &entities.BoolReport{Value: false}, nil // nolint: nilerr
+ return &entities.BoolReport{Value: false}, nil //nolint: nilerr
}
if mountCount > 0 {
return &entities.BoolReport{Value: true}, nil
diff --git a/pkg/domain/infra/runtime_libpod.go b/pkg/domain/infra/runtime_libpod.go
index 03e7ffb5d..162025969 100644
--- a/pkg/domain/infra/runtime_libpod.go
+++ b/pkg/domain/infra/runtime_libpod.go
@@ -342,7 +342,7 @@ func ParseIDMapping(mode namespaces.UsernsMode, uidMapSlice, gidMapSlice []strin
options.HostUIDMapping = false
options.HostGIDMapping = false
- // Simply ignore the setting and do not setup an inner namespace for root as it is a no-op
+ // Simply ignore the setting and do not set up an inner namespace for root as it is a no-op
return &options, nil
}
@@ -394,7 +394,7 @@ func ParseIDMapping(mode namespaces.UsernsMode, uidMapSlice, gidMapSlice []strin
// StartWatcher starts a new SIGHUP go routine for the current config.
func StartWatcher(rt *libpod.Runtime) {
- // Setup the signal notifier
+ // Set up the signal notifier
ch := make(chan os.Signal, 1)
signal.Notify(ch, syscall.SIGHUP)
diff --git a/pkg/domain/infra/tunnel/containers.go b/pkg/domain/infra/tunnel/containers.go
index b68bc46d4..fb0be629c 100644
--- a/pkg/domain/infra/tunnel/containers.go
+++ b/pkg/domain/infra/tunnel/containers.go
@@ -570,7 +570,7 @@ func (ic *ContainerEngine) ContainerExecDetached(ctx context.Context, nameOrID s
return sessionID, nil
}
-func startAndAttach(ic *ContainerEngine, name string, detachKeys *string, input, output, errput *os.File) error { //nolint
+func startAndAttach(ic *ContainerEngine, name string, detachKeys *string, input, output, errput *os.File) error {
attachErr := make(chan error)
attachReady := make(chan bool)
options := new(containers.AttachOptions).WithStream(true)
@@ -863,7 +863,7 @@ func (ic *ContainerEngine) ContainerRun(ctx context.Context, opts entities.Conta
if eventsErr != nil || lastEvent == nil {
logrus.Errorf("Cannot get exit code: %v", err)
report.ExitCode = define.ExecErrorCodeNotFound
- return &report, nil // nolint: nilerr
+ return &report, nil //nolint: nilerr
}
report.ExitCode = lastEvent.ContainerExitCode
diff --git a/pkg/domain/infra/tunnel/helpers.go b/pkg/domain/infra/tunnel/helpers.go
index 5b14fac37..6c043465c 100644
--- a/pkg/domain/infra/tunnel/helpers.go
+++ b/pkg/domain/infra/tunnel/helpers.go
@@ -20,7 +20,7 @@ func getContainersByContext(contextWithConnection context.Context, all, ignore b
func getContainersAndInputByContext(contextWithConnection context.Context, all, ignore bool, namesOrIDs []string) ([]entities.ListContainer, []string, error) {
if all && len(namesOrIDs) > 0 {
- return nil, nil, errors.New("cannot lookup containers and all")
+ return nil, nil, errors.New("cannot look up containers and all")
}
options := new(containers.ListOptions).WithAll(true).WithSync(true)
allContainers, err := containers.List(contextWithConnection, options)
@@ -77,7 +77,7 @@ func getContainersAndInputByContext(contextWithConnection context.Context, all,
func getPodsByContext(contextWithConnection context.Context, all bool, namesOrIDs []string) ([]*entities.ListPodsReport, error) {
if all && len(namesOrIDs) > 0 {
- return nil, errors.New("cannot lookup specific pods and all")
+ return nil, errors.New("cannot look up specific pods and all")
}
allPods, err := pods.List(contextWithConnection, nil)
diff --git a/pkg/domain/infra/tunnel/pods.go b/pkg/domain/infra/tunnel/pods.go
index 2dbdfcf80..7b1fa231f 100644
--- a/pkg/domain/infra/tunnel/pods.go
+++ b/pkg/domain/infra/tunnel/pods.go
@@ -195,6 +195,10 @@ func (ic *ContainerEngine) PodCreate(ctx context.Context, specg entities.PodSpec
return pods.CreatePodFromSpec(ic.ClientCtx, &specg)
}
+func (ic *ContainerEngine) PodClone(ctx context.Context, podClone entities.PodCloneOptions) (*entities.PodCloneReport, error) {
+ return nil, nil
+}
+
func (ic *ContainerEngine) PodTop(ctx context.Context, opts entities.PodTopOptions) (*entities.StringSliceReport, error) {
switch {
case opts.Latest:
diff --git a/pkg/errorhandling/errorhandling.go b/pkg/errorhandling/errorhandling.go
index 6ee1e7e86..fc6772c08 100644
--- a/pkg/errorhandling/errorhandling.go
+++ b/pkg/errorhandling/errorhandling.go
@@ -86,7 +86,7 @@ func Contains(err error, sub error) bool {
// PodConflictErrorModel is used in remote connections with podman
type PodConflictErrorModel struct {
Errs []string
- Id string // nolint
+ Id string //nolint:revive,stylecheck
}
// ErrorModel is used in remote connections with podman
diff --git a/pkg/hooks/exec/runtimeconfigfilter_test.go b/pkg/hooks/exec/runtimeconfigfilter_test.go
index f4b6cf86a..5c13a76e1 100644
--- a/pkg/hooks/exec/runtimeconfigfilter_test.go
+++ b/pkg/hooks/exec/runtimeconfigfilter_test.go
@@ -13,7 +13,7 @@ import (
)
func TestRuntimeConfigFilter(t *testing.T) {
- unexpectedEndOfJSONInput := json.Unmarshal([]byte("{\n"), nil) //nolint
+ unexpectedEndOfJSONInput := json.Unmarshal([]byte("{\n"), nil) //nolint:govet // this should force the error
fileMode := os.FileMode(0600)
rootUint32 := uint32(0)
binUser := int(1)
diff --git a/pkg/k8s.io/apimachinery/pkg/api/resource/quantity.go b/pkg/k8s.io/apimachinery/pkg/api/resource/quantity.go
index dcc5df219..588a189bf 100644
--- a/pkg/k8s.io/apimachinery/pkg/api/resource/quantity.go
+++ b/pkg/k8s.io/apimachinery/pkg/api/resource/quantity.go
@@ -138,7 +138,6 @@ const (
var (
// Errors that could happen while parsing a string.
- //nolint:revive
ErrFormatWrong = errors.New("quantities must match the regular expression '" + splitREString + "'")
ErrNumeric = errors.New("unable to parse numeric part of quantity")
ErrSuffix = errors.New("unable to parse quantity's suffix")
@@ -258,7 +257,7 @@ Suffix:
// we encountered a non decimal in the Suffix loop, but the last character
// was not a valid exponent
err = ErrFormatWrong
- // nolint:nakedret
+ //nolint:nakedret
return
}
@@ -579,9 +578,9 @@ func (q Quantity) MarshalJSON() ([]byte, error) {
// if CanonicalizeBytes needed more space than our slice provided, we may need to allocate again so use
// append
result = result[:1]
- result = append(result, number...) // nolint: makezero
- result = append(result, suffix...) // nolint: makezero
- result = append(result, '"') // nolint: makezero
+ result = append(result, number...) //nolint: makezero
+ result = append(result, suffix...) //nolint: makezero
+ result = append(result, '"') //nolint: makezero
return result, nil
}
diff --git a/pkg/machine/e2e/list_test.go b/pkg/machine/e2e/list_test.go
index 1c8c6ac81..e2121e7bf 100644
--- a/pkg/machine/e2e/list_test.go
+++ b/pkg/machine/e2e/list_test.go
@@ -29,7 +29,7 @@ var _ = Describe("podman machine list", func() {
firstList, err := mb.setCmd(list).run()
Expect(err).NotTo(HaveOccurred())
Expect(firstList).Should(Exit(0))
- Expect(len(firstList.outputToStringSlice())).To(Equal(1)) // just the header
+ Expect(firstList.outputToStringSlice()).To(HaveLen(1)) // just the header
i := new(initMachine)
session, err := mb.setCmd(i.withImagePath(mb.imagePath)).run()
@@ -39,7 +39,7 @@ var _ = Describe("podman machine list", func() {
secondList, err := mb.setCmd(list).run()
Expect(err).NotTo(HaveOccurred())
Expect(secondList).To(Exit(0))
- Expect(len(secondList.outputToStringSlice())).To(Equal(2)) // one machine and the header
+ Expect(secondList.outputToStringSlice()).To(HaveLen(2)) // one machine and the header
})
It("list machines with quiet or noheading", func() {
@@ -51,12 +51,12 @@ var _ = Describe("podman machine list", func() {
firstList, err := mb.setCmd(list.withQuiet()).run()
Expect(err).NotTo(HaveOccurred())
Expect(firstList).Should(Exit(0))
- Expect(len(firstList.outputToStringSlice())).To(Equal(0)) // No header with quiet
+ Expect(firstList.outputToStringSlice()).To(HaveLen(0)) // No header with quiet
noheaderSession, err := mb.setCmd(list.withNoHeading()).run() // noheader
Expect(err).NotTo(HaveOccurred())
Expect(noheaderSession).Should(Exit(0))
- Expect(len(noheaderSession.outputToStringSlice())).To(Equal(0))
+ Expect(noheaderSession.outputToStringSlice()).To(HaveLen(0))
i := new(initMachine)
session, err := mb.setName(name1).setCmd(i.withImagePath(mb.imagePath)).run()
@@ -70,7 +70,7 @@ var _ = Describe("podman machine list", func() {
secondList, err := mb.setCmd(list.withQuiet()).run()
Expect(err).NotTo(HaveOccurred())
Expect(secondList).To(Exit(0))
- Expect(len(secondList.outputToStringSlice())).To(Equal(2)) // two machines, no header
+ Expect(secondList.outputToStringSlice()).To(HaveLen(2)) // two machines, no header
listNames := secondList.outputToStringSlice()
stripAsterisk(listNames)
@@ -116,10 +116,10 @@ var _ = Describe("podman machine list", func() {
// go format
list := new(listMachine)
- listSession, err := mb.setCmd(list.withFormat("{{.Name}}").withNoHeading()).run()
+ listSession, err := mb.setCmd(list.withFormat("{{.Name}}")).run()
Expect(err).NotTo(HaveOccurred())
Expect(listSession).To(Exit(0))
- Expect(len(listSession.outputToStringSlice())).To(Equal(1))
+ Expect(listSession.outputToStringSlice()).To(HaveLen(1))
listNames := listSession.outputToStringSlice()
stripAsterisk(listNames)
@@ -135,6 +135,15 @@ var _ = Describe("podman machine list", func() {
var listResponse []*machine.ListReporter
err = jsoniter.Unmarshal(listSession.Bytes(), &listResponse)
Expect(err).To(BeNil())
+
+ // table format includes the header
+ list = new(listMachine)
+ listSession3, err3 := mb.setCmd(list.withFormat("table {{.Name}}")).run()
+ Expect(err3).NotTo(HaveOccurred())
+ Expect(listSession3).To(Exit(0))
+ listNames3 := listSession3.outputToStringSlice()
+ Expect(listNames3).To(HaveLen(2))
+ Expect(listNames3).To(ContainSubstring("NAME"))
})
})
diff --git a/pkg/machine/fcos.go b/pkg/machine/fcos.go
index 77427139a..59ef6d975 100644
--- a/pkg/machine/fcos.go
+++ b/pkg/machine/fcos.go
@@ -139,7 +139,7 @@ func getStreamURL(streamType string) url2.URL {
// This should get Exported and stay put as it will apply to all fcos downloads
// getFCOS parses fedoraCoreOS's stream and returns the image download URL and the release version
-func GetFCOSDownload(imageStream string) (*FcosDownloadInfo, error) { //nolint:staticcheck
+func GetFCOSDownload(imageStream string) (*FcosDownloadInfo, error) {
var (
fcosstable stream.Stream
altMeta release.Release
diff --git a/pkg/machine/ignition.go b/pkg/machine/ignition.go
index 35a9a30cb..f4602cc95 100644
--- a/pkg/machine/ignition.go
+++ b/pkg/machine/ignition.go
@@ -93,7 +93,7 @@ func NewIgnitionFile(ign DynamicIgnition) error {
tz string
)
// local means the same as the host
- // lookup where it is pointing to on the host
+ // look up where it is pointing to on the host
if ign.TimeZone == "local" {
tz, err = getLocalTimeZone()
if err != nil {
@@ -348,7 +348,7 @@ Delegate=memory pids cpu io
},
})
- // Setup /etc/subuid and /etc/subgid
+ // Set up /etc/subuid and /etc/subgid
for _, sub := range []string{"/etc/subuid", "/etc/subgid"} {
files = append(files, File{
Node: Node{
diff --git a/pkg/machine/keys.go b/pkg/machine/keys.go
index 15c1f73d8..45d9801cc 100644
--- a/pkg/machine/keys.go
+++ b/pkg/machine/keys.go
@@ -59,7 +59,16 @@ func generatekeysPrefix(dir string, file string, passThru bool, prefix ...string
args := append([]string{}, prefix[1:]...)
args = append(args, sshCommand...)
args = append(args, file)
- cmd := exec.Command(prefix[0], args...)
+
+ binary, err := exec.LookPath(prefix[0])
+ if err != nil {
+ return err
+ }
+ binary, err = filepath.Abs(binary)
+ if err != nil {
+ return err
+ }
+ cmd := exec.Command(binary, args...)
cmd.Dir = dir
if passThru {
cmd.Stdin = os.Stdin
diff --git a/pkg/machine/qemu/machine.go b/pkg/machine/qemu/machine.go
index 1b0d63986..5094345ea 100644
--- a/pkg/machine/qemu/machine.go
+++ b/pkg/machine/qemu/machine.go
@@ -16,9 +16,11 @@ import (
"net/url"
"os"
"os/exec"
+ "os/signal"
"path/filepath"
"strconv"
"strings"
+ "syscall"
"time"
"github.com/containers/common/pkg/config"
@@ -207,7 +209,7 @@ func migrateVM(configPath string, config []byte, vm *MachineVM) error {
vm.Rootful = old.Rootful
vm.UID = old.UID
- // Backup the original config file
+ // Back up the original config file
if err := os.Rename(configPath, configPath+".orig"); err != nil {
return err
}
@@ -484,12 +486,26 @@ func (v *MachineVM) Start(name string, _ machine.StartOptions) error {
if err := v.writeConfig(); err != nil {
return fmt.Errorf("writing JSON file: %w", err)
}
- defer func() {
+ doneStarting := func() {
v.Starting = false
if err := v.writeConfig(); err != nil {
logrus.Errorf("Writing JSON file: %v", err)
}
+ }
+ defer doneStarting()
+
+ c := make(chan os.Signal, 1)
+ signal.Notify(c, os.Interrupt, syscall.SIGTERM)
+ go func() {
+ _, ok := <-c
+ if !ok {
+ return
+ }
+ doneStarting()
+ os.Exit(1)
}()
+ defer close(c)
+
if v.isIncompatible() {
logrus.Errorf("machine %q is incompatible with this release of podman and needs to be recreated, starting for recovery only", v.Name)
}
@@ -564,7 +580,7 @@ func (v *MachineVM) Start(name string, _ machine.StartOptions) error {
if !errors.Is(err, os.ErrNotExist) {
return err
}
- // lookup qemu again maybe the path was changed, https://github.com/containers/podman/issues/13394
+ // look up qemu again maybe the path was changed, https://github.com/containers/podman/issues/13394
cfg, err := config.Default()
if err != nil {
return err
@@ -770,7 +786,7 @@ func (v *MachineVM) Stop(_ string, _ machine.StopOptions) error {
if err := qmpMonitor.Disconnect(); err != nil {
// FIXME: this error should probably be returned
- return nil // nolint: nilerr
+ return nil //nolint: nilerr
}
disconnected = true
@@ -1126,7 +1142,7 @@ func (p *Provider) CheckExclusiveActiveVM() (bool, string, error) {
}
// startHostNetworking runs a binary on the host system that allows users
-// to setup port forwarding to the podman virtual machine
+// to set up port forwarding to the podman virtual machine
func (v *MachineVM) startHostNetworking() (string, apiForwardingState, error) {
cfg, err := config.Default()
if err != nil {
diff --git a/pkg/machine/qemu/options_darwin_arm64.go b/pkg/machine/qemu/options_darwin_arm64.go
index 4c954af00..d75237938 100644
--- a/pkg/machine/qemu/options_darwin_arm64.go
+++ b/pkg/machine/qemu/options_darwin_arm64.go
@@ -4,6 +4,8 @@ import (
"os"
"os/exec"
"path/filepath"
+
+ "github.com/containers/common/pkg/config"
)
var (
@@ -15,8 +17,8 @@ func (v *MachineVM) addArchOptions() []string {
opts := []string{
"-accel", "hvf",
"-accel", "tcg",
- "-cpu", "cortex-a57",
- "-M", "virt,highmem=off",
+ "-cpu", "host",
+ "-M", "virt,highmem=on",
"-drive", "file=" + getEdk2CodeFd("edk2-aarch64-code.fd") + ",if=pflash,format=raw,readonly=on",
"-drive", "file=" + ovmfDir + ",if=pflash,format=raw"}
return opts
@@ -38,6 +40,22 @@ func getOvmfDir(imagePath, vmName string) string {
}
/*
+ * When QEmu is installed in a non-default location in the system
+ * we can use the qemu-system-* binary path to figure the install
+ * location for Qemu and use it to look for edk2-code-fd
+ */
+func getEdk2CodeFdPathFromQemuBinaryPath() string {
+ cfg, err := config.Default()
+ if err == nil {
+ execPath, err := cfg.FindHelperBinary(QemuCommand, true)
+ if err == nil {
+ return filepath.Clean(filepath.Join(filepath.Dir(execPath), "..", "share", "qemu"))
+ }
+ }
+ return ""
+}
+
+/*
* QEmu can be installed in multiple locations on MacOS, especially on
* Apple Silicon systems. A build from source will likely install it in
* /usr/local/bin, whereas Homebrew package management standard is to
@@ -45,6 +63,7 @@ func getOvmfDir(imagePath, vmName string) string {
*/
func getEdk2CodeFd(name string) string {
dirs := []string{
+ getEdk2CodeFdPathFromQemuBinaryPath(),
"/opt/homebrew/opt/podman/libexec/share/qemu",
"/usr/local/share/qemu",
"/opt/homebrew/share/qemu",
diff --git a/pkg/namespaces/namespaces.go b/pkg/namespaces/namespaces.go
index c95f8e275..8eacb8da7 100644
--- a/pkg/namespaces/namespaces.go
+++ b/pkg/namespaces/namespaces.go
@@ -112,7 +112,7 @@ func (n UsernsMode) IsDefaultValue() bool {
return n == "" || n == defaultType
}
-// GetAutoOptions returns a AutoUserNsOptions with the settings to setup automatically
+// GetAutoOptions returns a AutoUserNsOptions with the settings to automatically set up
// a user namespace.
func (n UsernsMode) GetAutoOptions() (*types.AutoUserNsOptions, error) {
parts := strings.SplitN(string(n), ":", 2)
diff --git a/pkg/rootless/rootless.go b/pkg/rootless/rootless.go
index d7143f549..94535f45e 100644
--- a/pkg/rootless/rootless.go
+++ b/pkg/rootless/rootless.go
@@ -50,7 +50,7 @@ func TryJoinPauseProcess(pausePidPath string) (bool, int, error) {
if err != nil {
// It is still failing. We can safely remove it.
os.Remove(pausePidPath)
- return false, -1, nil // nolint: nilerr
+ return false, -1, nil //nolint: nilerr
}
return became, ret, err
}
diff --git a/pkg/rootless/rootless_linux.c b/pkg/rootless/rootless_linux.c
index 94bd40f86..3588313c6 100644
--- a/pkg/rootless/rootless_linux.c
+++ b/pkg/rootless/rootless_linux.c
@@ -178,7 +178,7 @@ get_cmd_line_args ()
char *tmp = realloc (buffer, allocated);
if (tmp == NULL)
return NULL;
- buffer = tmp;
+ buffer = tmp;
}
}
@@ -243,7 +243,7 @@ can_use_shortcut ()
}
if (argv[argc+1] != NULL && (strcmp (argv[argc], "container") == 0 ||
- strcmp (argv[argc], "image") == 0) &&
+ strcmp (argv[argc], "image") == 0) &&
(strcmp (argv[argc+1], "mount") == 0 || strcmp (argv[argc+1], "scp") == 0))
{
ret = false;
@@ -512,7 +512,9 @@ create_pause_process (const char *pause_pid_file_path, char **argv)
r = TEMP_FAILURE_RETRY (read (p[0], &b, 1));
close (p[0]);
- reexec_in_user_namespace_wait (pid, 0);
+ r = reexec_in_user_namespace_wait (pid, 0);
+ if (r != 0)
+ return -1;
return r == 1 && b == '0' ? 0 : -1;
}
@@ -757,6 +759,7 @@ reexec_userns_join (int pid_to_join, char *pause_pid_file_path)
}
execvp (argv[0], argv);
+ fprintf (stderr, "failed to execvp %s: %m\n", argv[0]);
_exit (EXIT_FAILURE);
}
@@ -788,7 +791,10 @@ copy_file_to_fd (const char *file_to_read, int outfd)
fd = open (file_to_read, O_RDONLY);
if (fd < 0)
- return fd;
+ {
+ fprintf (stderr, "open `%s`: %m\n", file_to_read);
+ return fd;
+ }
for (;;)
{
@@ -796,7 +802,10 @@ copy_file_to_fd (const char *file_to_read, int outfd)
r = TEMP_FAILURE_RETRY (read (fd, buf, sizeof buf));
if (r < 0)
- return r;
+ {
+ fprintf (stderr, "read from `%s`: %m\n", file_to_read);
+ return r;
+ }
if (r == 0)
break;
@@ -805,7 +814,10 @@ copy_file_to_fd (const char *file_to_read, int outfd)
{
w = TEMP_FAILURE_RETRY (write (outfd, &buf[t], r - t));
if (w < 0)
- return w;
+ {
+ fprintf (stderr, "write file to output fd `%s`: %m\n", file_to_read);
+ return w;
+ }
t += w;
}
}
diff --git a/pkg/rootless/rootless_linux.go b/pkg/rootless/rootless_linux.go
index 5af9a978b..fde621b72 100644
--- a/pkg/rootless/rootless_linux.go
+++ b/pkg/rootless/rootless_linux.go
@@ -154,7 +154,7 @@ func tryMappingTool(uid bool, pid int, hostID int, mappings []idtools.IDMap) err
if output, err := cmd.CombinedOutput(); err != nil {
logrus.Errorf("running `%s`: %s", strings.Join(args, " "), output)
- errorStr := fmt.Sprintf("cannot setup namespace using %q", path)
+ errorStr := fmt.Sprintf("cannot set up namespace using %q", path)
if isSet, err := unshare.IsSetID(cmd.Path, mode, cap); err != nil {
logrus.Errorf("Failed to check for %s on %s: %v", idtype, path, err)
} else if !isSet {
@@ -182,7 +182,7 @@ func joinUserAndMountNS(pid uint, pausePid string) (bool, int, error) {
pidC := C.reexec_userns_join(C.int(pid), cPausePid)
if int(pidC) < 0 {
- return false, -1, errors.Errorf("cannot re-exec process")
+ return false, -1, errors.Errorf("cannot re-exec process to join the existing user namespace")
}
ret := C.reexec_in_user_namespace_wait(pidC, 0)
@@ -303,7 +303,7 @@ func becomeRootInUserNS(pausePid, fileToRead string, fileOutput *os.File) (_ boo
if retErr != nil && pid > 0 {
if err := unix.Kill(pid, unix.SIGKILL); err != nil {
if err != unix.ESRCH {
- logrus.Errorf("Failed to cleanup process %d: %v", pid, err)
+ logrus.Errorf("Failed to clean up process %d: %v", pid, err)
}
}
C.reexec_in_user_namespace_wait(C.int(pid), 0)
@@ -461,13 +461,8 @@ func BecomeRootInUserNS(pausePid string) (bool, int, error) {
// different uidmap and the unprivileged user has no way to read the
// file owned by the root in the container.
func TryJoinFromFilePaths(pausePidPath string, needNewNamespace bool, paths []string) (bool, int, error) {
- if len(paths) == 0 {
- return BecomeRootInUserNS(pausePidPath)
- }
-
var lastErr error
var pausePid int
- foundProcess := false
for _, path := range paths {
if !needNewNamespace {
@@ -479,12 +474,9 @@ func TryJoinFromFilePaths(pausePidPath string, needNewNamespace bool, paths []st
pausePid, err = strconv.Atoi(string(data))
if err != nil {
- lastErr = errors.Wrapf(err, "cannot parse file %s", path)
+ lastErr = errors.Wrapf(err, "cannot parse file %q", path)
continue
}
-
- lastErr = nil
- break
} else {
r, w, err := os.Pipe()
if err != nil {
@@ -511,26 +503,29 @@ func TryJoinFromFilePaths(pausePidPath string, needNewNamespace bool, paths []st
n, err := r.Read(b)
if err != nil {
- lastErr = errors.Wrapf(err, "cannot read %s\n", path)
+ lastErr = errors.Wrapf(err, "cannot read %q", path)
continue
}
pausePid, err = strconv.Atoi(string(b[:n]))
- if err == nil && unix.Kill(pausePid, 0) == nil {
- foundProcess = true
- lastErr = nil
- break
+ if err != nil {
+ lastErr = err
+ continue
}
}
- }
- if !foundProcess && pausePidPath != "" {
- return BecomeRootInUserNS(pausePidPath)
+
+ if pausePid > 0 && unix.Kill(pausePid, 0) == nil {
+ joined, pid, err := joinUserAndMountNS(uint(pausePid), pausePidPath)
+ if err == nil {
+ return joined, pid, nil
+ }
+ lastErr = err
+ }
}
if lastErr != nil {
return false, 0, lastErr
}
-
- return joinUserAndMountNS(uint(pausePid), pausePidPath)
+ return false, 0, errors.Wrapf(unix.ESRCH, "could not find any running process")
}
// ReadMappingsProc parses and returns the ID mappings at the specified path.
diff --git a/pkg/signal/signal_common.go b/pkg/signal/signal_common.go
index fe5a76dae..fc1ecc04d 100644
--- a/pkg/signal/signal_common.go
+++ b/pkg/signal/signal_common.go
@@ -2,6 +2,8 @@ package signal
import (
"fmt"
+ "os"
+ "os/signal"
"strconv"
"strings"
"syscall"
@@ -39,3 +41,18 @@ func ParseSignalNameOrNumber(rawSignal string) (syscall.Signal, error) {
}
return -1, fmt.Errorf("invalid signal: %s", basename)
}
+
+// CatchAll catches all signals and relays them to the specified channel.
+func CatchAll(sigc chan os.Signal) {
+ handledSigs := make([]os.Signal, 0, len(SignalMap))
+ for _, s := range SignalMap {
+ handledSigs = append(handledSigs, s)
+ }
+ signal.Notify(sigc, handledSigs...)
+}
+
+// StopCatch stops catching the signals and closes the specified channel.
+func StopCatch(sigc chan os.Signal) {
+ signal.Stop(sigc)
+ close(sigc)
+}
diff --git a/pkg/signal/signal_linux.go b/pkg/signal/signal_linux.go
index a114ea019..5103b6033 100644
--- a/pkg/signal/signal_linux.go
+++ b/pkg/signal/signal_linux.go
@@ -9,8 +9,6 @@ package signal
// NOTE: this package has originally been copied from github.com/docker/docker.
import (
- "os"
- "os/signal"
"syscall"
"golang.org/x/sys/unix"
@@ -91,18 +89,3 @@ var SignalMap = map[string]syscall.Signal{
"RTMAX-1": sigrtmax - 1,
"RTMAX": sigrtmax,
}
-
-// CatchAll catches all signals and relays them to the specified channel.
-func CatchAll(sigc chan os.Signal) {
- handledSigs := make([]os.Signal, 0, len(SignalMap))
- for _, s := range SignalMap {
- handledSigs = append(handledSigs, s)
- }
- signal.Notify(sigc, handledSigs...)
-}
-
-// StopCatch stops catching the signals and closes the specified channel.
-func StopCatch(sigc chan os.Signal) {
- signal.Stop(sigc)
- close(sigc)
-}
diff --git a/pkg/signal/signal_linux_mipsx.go b/pkg/signal/signal_linux_mipsx.go
index 9021a10e7..cdf9ad4c5 100644
--- a/pkg/signal/signal_linux_mipsx.go
+++ b/pkg/signal/signal_linux_mipsx.go
@@ -10,8 +10,6 @@ package signal
// NOTE: this package has originally been copied from github.com/docker/docker.
import (
- "os"
- "os/signal"
"syscall"
"golang.org/x/sys/unix"
@@ -92,18 +90,3 @@ var SignalMap = map[string]syscall.Signal{
"RTMAX-1": sigrtmax - 1,
"RTMAX": sigrtmax,
}
-
-// CatchAll catches all signals and relays them to the specified channel.
-func CatchAll(sigc chan os.Signal) {
- handledSigs := make([]os.Signal, 0, len(SignalMap))
- for _, s := range SignalMap {
- handledSigs = append(handledSigs, s)
- }
- signal.Notify(sigc, handledSigs...)
-}
-
-// StopCatch stops catching the signals and closes the specified channel.
-func StopCatch(sigc chan os.Signal) {
- signal.Stop(sigc)
- close(sigc)
-}
diff --git a/pkg/signal/signal_unix.go b/pkg/signal/signal_unix.go
index 0f43e21b7..7919e3670 100644
--- a/pkg/signal/signal_unix.go
+++ b/pkg/signal/signal_unix.go
@@ -5,7 +5,6 @@
package signal
import (
- "os"
"syscall"
)
@@ -88,13 +87,3 @@ var SignalMap = map[string]syscall.Signal{
"RTMAX-1": sigrtmax - 1,
"RTMAX": sigrtmax,
}
-
-// CatchAll catches all signals and relays them to the specified channel.
-func CatchAll(sigc chan os.Signal) {
- panic("Unsupported on non-linux platforms")
-}
-
-// StopCatch stops catching the signals and closes the specified channel.
-func StopCatch(sigc chan os.Signal) {
- panic("Unsupported on non-linux platforms")
-}
diff --git a/pkg/signal/signal_unsupported.go b/pkg/signal/signal_unsupported.go
index 9d0cee317..19ae93a61 100644
--- a/pkg/signal/signal_unsupported.go
+++ b/pkg/signal/signal_unsupported.go
@@ -5,7 +5,6 @@
package signal
import (
- "os"
"syscall"
)
@@ -88,13 +87,3 @@ var SignalMap = map[string]syscall.Signal{
"RTMAX-1": sigrtmax - 1,
"RTMAX": sigrtmax,
}
-
-// CatchAll catches all signals and relays them to the specified channel.
-func CatchAll(sigc chan os.Signal) {
- panic("Unsupported on non-linux platforms")
-}
-
-// StopCatch stops catching the signals and closes the specified channel.
-func StopCatch(sigc chan os.Signal) {
- panic("Unsupported on non-linux platforms")
-}
diff --git a/pkg/specgen/generate/config_linux.go b/pkg/specgen/generate/config_linux.go
index 4c3748e67..60d87a8fd 100644
--- a/pkg/specgen/generate/config_linux.go
+++ b/pkg/specgen/generate/config_linux.go
@@ -164,7 +164,7 @@ func addDevice(g *generate.Generator, device string) error {
}
// ParseDevice parses device mapping string to a src, dest & permissions string
-func ParseDevice(device string) (string, string, string, error) { //nolint
+func ParseDevice(device string) (string, string, string, error) {
var src string
var dst string
permissions := "rwm"
diff --git a/pkg/specgen/generate/container.go b/pkg/specgen/generate/container.go
index cc376125f..30c759495 100644
--- a/pkg/specgen/generate/container.go
+++ b/pkg/specgen/generate/container.go
@@ -303,8 +303,8 @@ func FinishThrottleDevices(s *specgen.SpecGenerator) error {
if err := unix.Stat(k, &statT); err != nil {
return err
}
- v.Major = (int64(unix.Major(uint64(statT.Rdev)))) // nolint: unconvert
- v.Minor = (int64(unix.Minor(uint64(statT.Rdev)))) // nolint: unconvert
+ v.Major = (int64(unix.Major(uint64(statT.Rdev)))) //nolint: unconvert
+ v.Minor = (int64(unix.Minor(uint64(statT.Rdev)))) //nolint: unconvert
if s.ResourceLimits.BlockIO == nil {
s.ResourceLimits.BlockIO = new(spec.LinuxBlockIO)
}
@@ -317,8 +317,8 @@ func FinishThrottleDevices(s *specgen.SpecGenerator) error {
if err := unix.Stat(k, &statT); err != nil {
return err
}
- v.Major = (int64(unix.Major(uint64(statT.Rdev)))) // nolint: unconvert
- v.Minor = (int64(unix.Minor(uint64(statT.Rdev)))) // nolint: unconvert
+ v.Major = (int64(unix.Major(uint64(statT.Rdev)))) //nolint: unconvert
+ v.Minor = (int64(unix.Minor(uint64(statT.Rdev)))) //nolint: unconvert
s.ResourceLimits.BlockIO.ThrottleWriteBpsDevice = append(s.ResourceLimits.BlockIO.ThrottleWriteBpsDevice, v)
}
}
@@ -328,8 +328,8 @@ func FinishThrottleDevices(s *specgen.SpecGenerator) error {
if err := unix.Stat(k, &statT); err != nil {
return err
}
- v.Major = (int64(unix.Major(uint64(statT.Rdev)))) // nolint: unconvert
- v.Minor = (int64(unix.Minor(uint64(statT.Rdev)))) // nolint: unconvert
+ v.Major = (int64(unix.Major(uint64(statT.Rdev)))) //nolint: unconvert
+ v.Minor = (int64(unix.Minor(uint64(statT.Rdev)))) //nolint: unconvert
s.ResourceLimits.BlockIO.ThrottleReadIOPSDevice = append(s.ResourceLimits.BlockIO.ThrottleReadIOPSDevice, v)
}
}
@@ -339,8 +339,8 @@ func FinishThrottleDevices(s *specgen.SpecGenerator) error {
if err := unix.Stat(k, &statT); err != nil {
return err
}
- v.Major = (int64(unix.Major(uint64(statT.Rdev)))) // nolint: unconvert
- v.Minor = (int64(unix.Minor(uint64(statT.Rdev)))) // nolint: unconvert
+ v.Major = (int64(unix.Major(uint64(statT.Rdev)))) //nolint: unconvert
+ v.Minor = (int64(unix.Minor(uint64(statT.Rdev)))) //nolint: unconvert
s.ResourceLimits.BlockIO.ThrottleWriteIOPSDevice = append(s.ResourceLimits.BlockIO.ThrottleWriteIOPSDevice, v)
}
}
@@ -450,7 +450,7 @@ func ConfigToSpec(rt *libpod.Runtime, specg *specgen.SpecGenerator, contaierID s
specg.IpcNS = specgen.Namespace{NSMode: specgen.Default} // default
}
case "uts":
- specg.UtsNS = specgen.Namespace{NSMode: specgen.Default} // default
+ specg.UtsNS = specgen.Namespace{NSMode: specgen.Private} // default
case "user":
if conf.AddCurrentUserPasswdEntry {
specg.UserNS = specgen.Namespace{NSMode: specgen.KeepID}
@@ -506,6 +506,7 @@ func ConfigToSpec(rt *libpod.Runtime, specg *specgen.SpecGenerator, contaierID s
specg.Mounts = mounts
specg.HostDeviceList = conf.DeviceHostSrc
specg.Networks = conf.Networks
+ specg.ShmSize = &conf.ShmSize
mapSecurityConfig(conf, specg)
diff --git a/pkg/specgen/generate/container_create.go b/pkg/specgen/generate/container_create.go
index 7faf13465..6b2e90b22 100644
--- a/pkg/specgen/generate/container_create.go
+++ b/pkg/specgen/generate/container_create.go
@@ -180,10 +180,23 @@ func MakeContainer(ctx context.Context, rt *libpod.Runtime, s *specgen.SpecGener
if err != nil {
return nil, nil, nil, err
}
+ resources := runtimeSpec.Linux.Resources
+
+ // resources get overwrritten similarly to pod inheritance, manually assign here if there is a new value
+ marshalRes, err := json.Marshal(resources)
+ if err != nil {
+ return nil, nil, nil, err
+ }
+
err = json.Unmarshal(out, runtimeSpec.Linux)
if err != nil {
return nil, nil, nil, err
}
+
+ err = json.Unmarshal(marshalRes, runtimeSpec.Linux.Resources)
+ if err != nil {
+ return nil, nil, nil, err
+ }
}
if s.ResourceLimits != nil {
switch {
@@ -564,5 +577,10 @@ func Inherit(infra libpod.Container, s *specgen.SpecGenerator, rt *libpod.Runtim
if err != nil {
return nil, nil, nil, err
}
+
+ // this causes errors when shmSize is the default value, it will still get passed down unless we manually override.
+ if s.IpcNS.NSMode == specgen.Host && (compatibleOptions.ShmSize != nil && compatibleOptions.IsDefaultShmSize()) {
+ s.ShmSize = nil
+ }
return options, infraSpec, compatibleOptions, nil
}
diff --git a/pkg/specgen/generate/oci.go b/pkg/specgen/generate/oci.go
index 716960024..1044854f4 100644
--- a/pkg/specgen/generate/oci.go
+++ b/pkg/specgen/generate/oci.go
@@ -298,8 +298,7 @@ func SpecGenToOCI(ctx context.Context, s *specgen.SpecGenerator, rt *libpod.Runt
g.AddAnnotation(key, val)
}
- switch {
- case compatibleOptions.InfraResources == nil && s.ResourceLimits != nil:
+ if s.ResourceLimits != nil {
out, err := json.Marshal(s.ResourceLimits)
if err != nil {
return nil, err
@@ -308,29 +307,9 @@ func SpecGenToOCI(ctx context.Context, s *specgen.SpecGenerator, rt *libpod.Runt
if err != nil {
return nil, err
}
- case s.ResourceLimits != nil: // if we have predefined resource limits we need to make sure we keep the infra and container limits
- originalResources, err := json.Marshal(s.ResourceLimits)
- if err != nil {
- return nil, err
- }
- infraResources, err := json.Marshal(compatibleOptions.InfraResources)
- if err != nil {
- return nil, err
- }
- err = json.Unmarshal(infraResources, s.ResourceLimits) // put infra's resource limits in the container
- if err != nil {
- return nil, err
- }
- err = json.Unmarshal(originalResources, s.ResourceLimits) // make sure we did not override anything
- if err != nil {
- return nil, err
- }
g.Config.Linux.Resources = s.ResourceLimits
- default:
- g.Config.Linux.Resources = compatibleOptions.InfraResources
}
// Devices
-
// set the default rule at the beginning of device configuration
if !inUserNS && !s.Privileged {
g.AddLinuxResourcesDevice(false, "", nil, nil, "rwm")
@@ -371,7 +350,7 @@ func SpecGenToOCI(ctx context.Context, s *specgen.SpecGenerator, rt *libpod.Runt
if err := unix.Stat(k, &statT); err != nil {
return nil, errors.Wrapf(err, "failed to inspect '%s' in --blkio-weight-device", k)
}
- g.AddLinuxResourcesBlockIOWeightDevice((int64(unix.Major(uint64(statT.Rdev)))), (int64(unix.Minor(uint64(statT.Rdev)))), *v.Weight) // nolint: unconvert
+ g.AddLinuxResourcesBlockIOWeightDevice((int64(unix.Major(uint64(statT.Rdev)))), (int64(unix.Minor(uint64(statT.Rdev)))), *v.Weight) //nolint: unconvert
}
BlockAccessToKernelFilesystems(s.Privileged, s.PidNS.IsHost(), s.Mask, s.Unmask, &g)
diff --git a/pkg/specgen/generate/pod_create.go b/pkg/specgen/generate/pod_create.go
index d4f281a11..4ac8a0aa2 100644
--- a/pkg/specgen/generate/pod_create.go
+++ b/pkg/specgen/generate/pod_create.go
@@ -2,12 +2,17 @@ package generate
import (
"context"
+ "fmt"
"net"
+ "os"
+ "strconv"
+ "strings"
"github.com/containers/podman/v4/libpod"
"github.com/containers/podman/v4/libpod/define"
"github.com/containers/podman/v4/pkg/domain/entities"
"github.com/containers/podman/v4/pkg/specgen"
+ "github.com/containers/podman/v4/pkg/specgenutil"
"github.com/pkg/errors"
"github.com/sirupsen/logrus"
)
@@ -210,3 +215,88 @@ func MapSpec(p *specgen.PodSpecGenerator) (*specgen.SpecGenerator, error) {
p.InfraContainerSpec.Image = p.InfraImage
return p.InfraContainerSpec, nil
}
+
+func PodConfigToSpec(rt *libpod.Runtime, spec *specgen.PodSpecGenerator, infraOptions *entities.ContainerCreateOptions, id string) (p *libpod.Pod, err error) {
+ pod, err := rt.LookupPod(id)
+ if err != nil {
+ return nil, err
+ }
+
+ infraSpec := &specgen.SpecGenerator{}
+ if pod.HasInfraContainer() {
+ infraID, err := pod.InfraContainerID()
+ if err != nil {
+ return nil, err
+ }
+ _, _, err = ConfigToSpec(rt, infraSpec, infraID)
+ if err != nil {
+ return nil, err
+ }
+
+ infraSpec.Hostname = ""
+ infraSpec.CgroupParent = ""
+ infraSpec.Pod = "" // remove old pod...
+ infraOptions.IsClone = true
+ infraOptions.IsInfra = true
+
+ n := infraSpec.Name
+ _, err = rt.LookupContainer(n + "-clone")
+ if err == nil { // if we found a ctr with this name, set it so the below switch can tell
+ n += "-clone"
+ }
+
+ switch {
+ case strings.Contains(n, "-clone"):
+ ind := strings.Index(n, "-clone") + 6
+ num, err := strconv.Atoi(n[ind:])
+ if num == 0 && err != nil { // clone1 is hard to get with this logic, just check for it here.
+ _, err = rt.LookupContainer(n + "1")
+ if err != nil {
+ infraSpec.Name = n + "1"
+ break
+ }
+ } else {
+ n = n[0:ind]
+ }
+ err = nil
+ count := num
+ for err == nil {
+ count++
+ tempN := n + strconv.Itoa(count)
+ _, err = rt.LookupContainer(tempN)
+ }
+ n += strconv.Itoa(count)
+ infraSpec.Name = n
+ default:
+ infraSpec.Name = n + "-clone"
+ }
+
+ err = specgenutil.FillOutSpecGen(infraSpec, infraOptions, []string{})
+ if err != nil {
+ return nil, err
+ }
+
+ out, err := CompleteSpec(context.Background(), rt, infraSpec)
+ if err != nil {
+ return nil, err
+ }
+
+ // Print warnings
+ if len(out) > 0 {
+ for _, w := range out {
+ fmt.Println("Could not properly complete the spec as expected:")
+ fmt.Fprintf(os.Stderr, "%s\n", w)
+ }
+ }
+
+ spec.InfraContainerSpec = infraSpec
+ }
+
+ // need to reset hostname, name etc of both pod and infra
+ spec.Hostname = ""
+
+ if len(spec.InfraContainerSpec.Image) > 0 {
+ spec.InfraImage = spec.InfraContainerSpec.Image
+ }
+ return pod, nil
+}
diff --git a/pkg/specgen/podspecgen.go b/pkg/specgen/podspecgen.go
index 777097ac5..02ba06be1 100644
--- a/pkg/specgen/podspecgen.go
+++ b/pkg/specgen/podspecgen.go
@@ -183,6 +183,10 @@ type PodStorageConfig struct {
// comma-separated options. Valid options are 'ro', 'rw', and 'z'.
// Options will be used for all volumes sourced from the container.
VolumesFrom []string `json:"volumes_from,omitempty"`
+ // ShmSize is the size of the tmpfs to mount in at /dev/shm, in bytes.
+ // Conflicts with ShmSize if IpcNS is not private.
+ // Optional.
+ ShmSize *int64 `json:"shm_size,omitempty"`
}
// PodCgroupConfig contains configuration options about a pod's cgroups.
diff --git a/pkg/specgen/volumes.go b/pkg/specgen/volumes.go
index a7a1022b0..f272a5c11 100644
--- a/pkg/specgen/volumes.go
+++ b/pkg/specgen/volumes.go
@@ -1,6 +1,7 @@
package specgen
import (
+ "path/filepath"
"strings"
"github.com/containers/common/pkg/parse"
@@ -56,7 +57,6 @@ func GenVolumeMounts(volumeFlag []string) (map[string]spec.Mount, map[string]*Na
overlayVolumes := make(map[string]*OverlayVolume)
volumeFormatErr := errors.Errorf("incorrect volume format, should be [host-dir:]ctr-dir[:option]")
-
for _, vol := range volumeFlag {
var (
options []string
@@ -71,6 +71,20 @@ func GenVolumeMounts(volumeFlag []string) (map[string]spec.Mount, map[string]*Na
}
src = splitVol[0]
+
+ // Support relative paths beginning with ./
+ if strings.HasPrefix(src, "./") {
+ path, err := filepath.EvalSymlinks(src)
+ if err != nil {
+ return nil, nil, nil, err
+ }
+ src, err = filepath.Abs(path)
+ if err != nil {
+ return nil, nil, nil, err
+ }
+ splitVol[0] = src
+ }
+
if len(splitVol) == 1 {
// This is an anonymous named volume. Only thing given
// is destination.
diff --git a/pkg/specgenutil/specgen.go b/pkg/specgenutil/specgen.go
index 6d70af106..ab45a8d47 100644
--- a/pkg/specgenutil/specgen.go
+++ b/pkg/specgenutil/specgen.go
@@ -312,7 +312,7 @@ func FillOutSpecGen(s *specgen.SpecGenerator, c *entities.ContainerCreateOptions
s.PublishExposedPorts = c.PublishAll
}
- if len(s.Pod) == 0 {
+ if len(s.Pod) == 0 || len(c.Pod) > 0 {
s.Pod = c.Pod
}
diff --git a/pkg/systemd/generate/containers.go b/pkg/systemd/generate/containers.go
index d552e21ed..e953a1f1f 100644
--- a/pkg/systemd/generate/containers.go
+++ b/pkg/systemd/generate/containers.go
@@ -204,7 +204,7 @@ func generateContainerInfo(ctr *libpod.Container, options entities.GenerateSyste
} else {
runRoot = ctr.Runtime().RunRoot()
if runRoot == "" {
- return nil, errors.Errorf("could not lookup container's runroot: got empty string")
+ return nil, errors.Errorf("could not look up container's runroot: got empty string")
}
}
diff --git a/pkg/util/utils_linux.go b/pkg/util/utils_linux.go
index 871303f64..bc522361f 100644
--- a/pkg/util/utils_linux.go
+++ b/pkg/util/utils_linux.go
@@ -176,7 +176,7 @@ func DeviceFromPath(path string) (*spec.LinuxDevice, error) {
var (
devType string
mode = stat.Mode
- devNumber = uint64(stat.Rdev) // nolint: unconvert
+ devNumber = uint64(stat.Rdev) //nolint: unconvert
m = os.FileMode(mode)
)