summaryrefslogtreecommitdiff
path: root/pkg
diff options
context:
space:
mode:
Diffstat (limited to 'pkg')
-rw-r--r--pkg/api/handlers/libpod/containers.go28
-rw-r--r--pkg/api/handlers/libpod/generate.go34
-rw-r--r--pkg/api/handlers/libpod/pods.go6
-rw-r--r--pkg/api/server/register_containers.go8
-rw-r--r--pkg/bindings/connection.go6
-rw-r--r--pkg/bindings/containers/archive.go6
-rw-r--r--pkg/bindings/containers/attach.go8
-rw-r--r--pkg/bindings/containers/checkpoint.go4
-rw-r--r--pkg/bindings/containers/commit.go2
-rw-r--r--pkg/bindings/containers/containers.go34
-rw-r--r--pkg/bindings/containers/create.go2
-rw-r--r--pkg/bindings/containers/diff.go2
-rw-r--r--pkg/bindings/containers/exec.go6
-rw-r--r--pkg/bindings/containers/healthcheck.go2
-rw-r--r--pkg/bindings/containers/logs.go2
-rw-r--r--pkg/bindings/containers/mount.go6
-rw-r--r--pkg/bindings/containers/rename.go2
-rw-r--r--pkg/bindings/generate/generate.go4
-rw-r--r--pkg/bindings/generate/types.go2
-rw-r--r--pkg/bindings/generate/types_systemd_options.go15
-rw-r--r--pkg/bindings/images/build.go2
-rw-r--r--pkg/bindings/images/diff.go2
-rw-r--r--pkg/bindings/images/images.go26
-rw-r--r--pkg/bindings/images/pull.go2
-rw-r--r--pkg/bindings/images/rm.go2
-rw-r--r--pkg/bindings/manifests/manifests.go14
-rw-r--r--pkg/bindings/network/network.go16
-rw-r--r--pkg/bindings/play/play.go4
-rw-r--r--pkg/bindings/pods/pods.go28
-rw-r--r--pkg/bindings/secrets/secrets.go8
-rw-r--r--pkg/bindings/system/info.go2
-rw-r--r--pkg/bindings/system/system.go8
-rw-r--r--pkg/bindings/test/connection_test.go68
-rw-r--r--pkg/bindings/volumes/volumes.go12
-rw-r--r--pkg/domain/entities/containers.go14
-rw-r--r--pkg/domain/entities/generate.go2
-rw-r--r--pkg/domain/entities/pods.go9
-rw-r--r--pkg/domain/infra/abi/containers.go18
-rw-r--r--pkg/domain/infra/abi/play.go2
-rw-r--r--pkg/domain/infra/tunnel/generate.go2
-rw-r--r--pkg/specgenutil/specgen.go2
-rw-r--r--pkg/systemd/generate/common.go4
-rw-r--r--pkg/systemd/generate/containers.go52
-rw-r--r--pkg/systemd/generate/containers_test.go119
-rw-r--r--pkg/systemd/generate/pods.go5
45 files changed, 455 insertions, 147 deletions
diff --git a/pkg/api/handlers/libpod/containers.go b/pkg/api/handlers/libpod/containers.go
index 343c0d0b3..3aeebc334 100644
--- a/pkg/api/handlers/libpod/containers.go
+++ b/pkg/api/handlers/libpod/containers.go
@@ -214,6 +214,7 @@ func Checkpoint(w http.ResponseWriter, r *http.Request) {
TCPEstablished bool `schema:"tcpEstablished"`
Export bool `schema:"export"`
IgnoreRootFS bool `schema:"ignoreRootFS"`
+ PrintStats bool `schema:"printStats"`
}{
// override any golang type defaults
}
@@ -248,11 +249,12 @@ func Checkpoint(w http.ResponseWriter, r *http.Request) {
KeepRunning: query.LeaveRunning,
TCPEstablished: query.TCPEstablished,
IgnoreRootfs: query.IgnoreRootFS,
+ PrintStats: query.PrintStats,
}
if query.Export {
options.TargetFile = targetFile
}
- err = ctr.Checkpoint(r.Context(), options)
+ criuStatistics, runtimeCheckpointDuration, err := ctr.Checkpoint(r.Context(), options)
if err != nil {
utils.InternalServerError(w, err)
return
@@ -267,7 +269,15 @@ func Checkpoint(w http.ResponseWriter, r *http.Request) {
utils.WriteResponse(w, http.StatusOK, f)
return
}
- utils.WriteResponse(w, http.StatusOK, entities.CheckpointReport{Id: ctr.ID()})
+ utils.WriteResponse(
+ w,
+ http.StatusOK,
+ entities.CheckpointReport{
+ Id: ctr.ID(),
+ RuntimeDuration: runtimeCheckpointDuration,
+ CRIUStatistics: criuStatistics,
+ },
+ )
}
func Restore(w http.ResponseWriter, r *http.Request) {
@@ -284,6 +294,7 @@ func Restore(w http.ResponseWriter, r *http.Request) {
IgnoreVolumes bool `schema:"ignoreVolumes"`
IgnoreStaticIP bool `schema:"ignoreStaticIP"`
IgnoreStaticMAC bool `schema:"ignoreStaticMAC"`
+ PrintStats bool `schema:"printStats"`
}{
// override any golang type defaults
}
@@ -319,17 +330,26 @@ func Restore(w http.ResponseWriter, r *http.Request) {
IgnoreRootfs: query.IgnoreRootFS,
IgnoreStaticIP: query.IgnoreStaticIP,
IgnoreStaticMAC: query.IgnoreStaticMAC,
+ PrintStats: query.PrintStats,
}
if query.Import {
options.TargetFile = targetFile
options.Name = query.Name
}
- err = ctr.Restore(r.Context(), options)
+ criuStatistics, runtimeRestoreDuration, err := ctr.Restore(r.Context(), options)
if err != nil {
utils.InternalServerError(w, err)
return
}
- utils.WriteResponse(w, http.StatusOK, entities.RestoreReport{Id: ctr.ID()})
+ utils.WriteResponse(
+ w,
+ http.StatusOK,
+ entities.RestoreReport{
+ Id: ctr.ID(),
+ RuntimeDuration: runtimeRestoreDuration,
+ CRIUStatistics: criuStatistics,
+ },
+ )
}
func InitContainer(w http.ResponseWriter, r *http.Request) {
diff --git a/pkg/api/handlers/libpod/generate.go b/pkg/api/handlers/libpod/generate.go
index 117c5e2aa..5205d875d 100644
--- a/pkg/api/handlers/libpod/generate.go
+++ b/pkg/api/handlers/libpod/generate.go
@@ -17,14 +17,15 @@ func GenerateSystemd(w http.ResponseWriter, r *http.Request) {
runtime := r.Context().Value(api.RuntimeKey).(*libpod.Runtime)
decoder := r.Context().Value(api.DecoderKey).(*schema.Decoder)
query := struct {
- Name bool `schema:"useName"`
- New bool `schema:"new"`
- NoHeader bool `schema:"noHeader"`
- RestartPolicy *string `schema:"restartPolicy"`
- StopTimeout uint `schema:"stopTimeout"`
- ContainerPrefix string `schema:"containerPrefix"`
- PodPrefix string `schema:"podPrefix"`
- Separator string `schema:"separator"`
+ Name bool `schema:"useName"`
+ New bool `schema:"new"`
+ NoHeader bool `schema:"noHeader"`
+ TemplateUnitFile bool `schema:"templateUnitFile"`
+ RestartPolicy *string `schema:"restartPolicy"`
+ StopTimeout uint `schema:"stopTimeout"`
+ ContainerPrefix string `schema:"containerPrefix"`
+ PodPrefix string `schema:"podPrefix"`
+ Separator string `schema:"separator"`
}{
StopTimeout: util.DefaultContainerConfig().Engine.StopTimeout,
ContainerPrefix: "container",
@@ -40,14 +41,15 @@ func GenerateSystemd(w http.ResponseWriter, r *http.Request) {
containerEngine := abi.ContainerEngine{Libpod: runtime}
options := entities.GenerateSystemdOptions{
- Name: query.Name,
- New: query.New,
- NoHeader: query.NoHeader,
- RestartPolicy: query.RestartPolicy,
- StopTimeout: &query.StopTimeout,
- ContainerPrefix: query.ContainerPrefix,
- PodPrefix: query.PodPrefix,
- Separator: query.Separator,
+ Name: query.Name,
+ New: query.New,
+ NoHeader: query.NoHeader,
+ TemplateUnitFile: query.TemplateUnitFile,
+ RestartPolicy: query.RestartPolicy,
+ StopTimeout: &query.StopTimeout,
+ ContainerPrefix: query.ContainerPrefix,
+ PodPrefix: query.PodPrefix,
+ Separator: query.Separator,
}
report, err := containerEngine.GenerateSystemd(r.Context(), utils.GetName(r), options)
diff --git a/pkg/api/handlers/libpod/pods.go b/pkg/api/handlers/libpod/pods.go
index 2ba292579..3d18406a5 100644
--- a/pkg/api/handlers/libpod/pods.go
+++ b/pkg/api/handlers/libpod/pods.go
@@ -39,8 +39,10 @@ func PodCreate(w http.ResponseWriter, r *http.Request) {
return
}
if !psg.NoInfra {
- infraOptions := &entities.ContainerCreateOptions{ImageVolume: "bind", IsInfra: true, Net: &entities.NetOptions{}, Devices: psg.Devices} // options for pulling the image and FillOutSpec
- err = specgenutil.FillOutSpecGen(psg.InfraContainerSpec, infraOptions, []string{}) // necessary for default values in many cases (userns, idmappings)
+ infraOptions := entities.NewInfraContainerCreateOptions() // options for pulling the image and FillOutSpec
+ infraOptions.Net = &entities.NetOptions{}
+ infraOptions.Devices = psg.Devices
+ err = specgenutil.FillOutSpecGen(psg.InfraContainerSpec, &infraOptions, []string{}) // necessary for default values in many cases (userns, idmappings)
if err != nil {
utils.Error(w, "Something went wrong.", http.StatusInternalServerError, errors.Wrap(err, "error filling out specgen"))
return
diff --git a/pkg/api/server/register_containers.go b/pkg/api/server/register_containers.go
index c4919182b..601e1251b 100644
--- a/pkg/api/server/register_containers.go
+++ b/pkg/api/server/register_containers.go
@@ -1441,6 +1441,10 @@ func (s *APIServer) registerContainersHandlers(r *mux.Router) error {
// name: ignoreRootFS
// type: boolean
// description: do not include root file-system changes when exporting
+ // - in: query
+ // name: printStats
+ // type: boolean
+ // description: add checkpoint statistics to the returned CheckpointReport
// produces:
// - application/json
// responses:
@@ -1495,6 +1499,10 @@ func (s *APIServer) registerContainersHandlers(r *mux.Router) error {
// name: ignoreStaticMAC
// type: boolean
// description: ignore MAC address if set statically
+ // - in: query
+ // name: printStats
+ // type: boolean
+ // description: add restore statistics to the returned RestoreReport
// produces:
// - application/json
// responses:
diff --git a/pkg/bindings/connection.go b/pkg/bindings/connection.go
index a2be44ab4..b2e949f67 100644
--- a/pkg/bindings/connection.go
+++ b/pkg/bindings/connection.go
@@ -145,7 +145,7 @@ func pingNewConnection(ctx context.Context) error {
return err
}
// the ping endpoint sits at / in this case
- response, err := client.DoRequest(nil, http.MethodGet, "/_ping", nil, nil)
+ response, err := client.DoRequest(ctx, nil, http.MethodGet, "/_ping", nil, nil)
if err != nil {
return err
}
@@ -306,7 +306,7 @@ func unixClient(_url *url.URL) Connection {
}
// DoRequest assembles the http request and returns the response
-func (c *Connection) DoRequest(httpBody io.Reader, httpMethod, endpoint string, queryParams url.Values, header map[string]string, pathValues ...string) (*APIResponse, error) {
+func (c *Connection) DoRequest(ctx context.Context, httpBody io.Reader, httpMethod, endpoint string, queryParams url.Values, header map[string]string, pathValues ...string) (*APIResponse, error) {
var (
err error
response *http.Response
@@ -328,7 +328,7 @@ func (c *Connection) DoRequest(httpBody io.Reader, httpMethod, endpoint string,
uri := fmt.Sprintf("http://d/v%d.%d.%d/libpod"+endpoint, params...)
logrus.Debugf("DoRequest Method: %s URI: %v", httpMethod, uri)
- req, err := http.NewRequestWithContext(context.WithValue(context.Background(), clientKey, c), httpMethod, uri, httpBody)
+ req, err := http.NewRequestWithContext(ctx, httpMethod, uri, httpBody)
if err != nil {
return nil, err
}
diff --git a/pkg/bindings/containers/archive.go b/pkg/bindings/containers/archive.go
index 876f5340b..d64fbffd6 100644
--- a/pkg/bindings/containers/archive.go
+++ b/pkg/bindings/containers/archive.go
@@ -23,7 +23,7 @@ func Stat(ctx context.Context, nameOrID string, path string) (*entities.Containe
params := url.Values{}
params.Set("path", path)
- response, err := conn.DoRequest(nil, http.MethodHead, "/containers/%s/archive", params, nil, nameOrID)
+ response, err := conn.DoRequest(ctx, nil, http.MethodHead, "/containers/%s/archive", params, nil, nameOrID)
if err != nil {
return nil, err
}
@@ -71,7 +71,7 @@ func CopyFromArchiveWithOptions(ctx context.Context, nameOrID string, path strin
params.Set("path", path)
return func() error {
- response, err := conn.DoRequest(reader, http.MethodPut, "/containers/%s/archive", params, nil, nameOrID)
+ response, err := conn.DoRequest(ctx, reader, http.MethodPut, "/containers/%s/archive", params, nil, nameOrID)
if err != nil {
return err
}
@@ -92,7 +92,7 @@ func CopyToArchive(ctx context.Context, nameOrID string, path string, writer io.
params := url.Values{}
params.Set("path", path)
- response, err := conn.DoRequest(nil, http.MethodGet, "/containers/%s/archive", params, nil, nameOrID)
+ response, err := conn.DoRequest(ctx, nil, http.MethodGet, "/containers/%s/archive", params, nil, nameOrID)
if err != nil {
return nil, err
}
diff --git a/pkg/bindings/containers/attach.go b/pkg/bindings/containers/attach.go
index 47de89b33..baa3f182e 100644
--- a/pkg/bindings/containers/attach.go
+++ b/pkg/bindings/containers/attach.go
@@ -130,7 +130,7 @@ func Attach(ctx context.Context, nameOrID string, stdin io.Reader, stdout io.Wri
IdleConnTimeout: time.Duration(0),
}
conn.Client.Transport = t
- response, err := conn.DoRequest(nil, http.MethodPost, "/containers/%s/attach", params, headers, nameOrID)
+ response, err := conn.DoRequest(ctx, nil, http.MethodPost, "/containers/%s/attach", params, headers, nameOrID)
if err != nil {
return err
}
@@ -322,7 +322,7 @@ func resizeTTY(ctx context.Context, endpoint string, height *int, width *int) er
params.Set("w", strconv.Itoa(*width))
}
params.Set("running", "true")
- rsp, err := conn.DoRequest(nil, http.MethodPost, endpoint, params, nil)
+ rsp, err := conn.DoRequest(ctx, nil, http.MethodPost, endpoint, params, nil)
if err != nil {
return err
}
@@ -407,7 +407,7 @@ func ExecStartAndAttach(ctx context.Context, sessionID string, options *ExecStar
// We need to inspect the exec session first to determine whether to use
// -t.
- resp, err := conn.DoRequest(nil, http.MethodGet, "/exec/%s/json", nil, nil, sessionID)
+ resp, err := conn.DoRequest(ctx, nil, http.MethodGet, "/exec/%s/json", nil, nil, sessionID)
if err != nil {
return err
}
@@ -478,7 +478,7 @@ func ExecStartAndAttach(ctx context.Context, sessionID string, options *ExecStar
IdleConnTimeout: time.Duration(0),
}
conn.Client.Transport = t
- response, err := conn.DoRequest(bytes.NewReader(bodyJSON), http.MethodPost, "/exec/%s/start", nil, nil, sessionID)
+ response, err := conn.DoRequest(ctx, bytes.NewReader(bodyJSON), http.MethodPost, "/exec/%s/start", nil, nil, sessionID)
if err != nil {
return err
}
diff --git a/pkg/bindings/containers/checkpoint.go b/pkg/bindings/containers/checkpoint.go
index 7f7080f13..2ad2c6931 100644
--- a/pkg/bindings/containers/checkpoint.go
+++ b/pkg/bindings/containers/checkpoint.go
@@ -23,7 +23,7 @@ func Checkpoint(ctx context.Context, nameOrID string, options *CheckpointOptions
if err != nil {
return nil, err
}
- response, err := conn.DoRequest(nil, http.MethodPost, "/containers/%s/checkpoint", params, nil, nameOrID)
+ response, err := conn.DoRequest(ctx, nil, http.MethodPost, "/containers/%s/checkpoint", params, nil, nameOrID)
if err != nil {
return nil, err
}
@@ -52,7 +52,7 @@ func Restore(ctx context.Context, nameOrID string, options *RestoreOptions) (*en
if i := options.GetImportAchive(); options.Changed("ImportArchive") {
params.Set("import", i)
}
- response, err := conn.DoRequest(nil, http.MethodPost, "/containers/%s/restore", params, nil, nameOrID)
+ response, err := conn.DoRequest(ctx, nil, http.MethodPost, "/containers/%s/restore", params, nil, nameOrID)
if err != nil {
return nil, err
}
diff --git a/pkg/bindings/containers/commit.go b/pkg/bindings/containers/commit.go
index a4adebb1f..372a99d32 100644
--- a/pkg/bindings/containers/commit.go
+++ b/pkg/bindings/containers/commit.go
@@ -24,7 +24,7 @@ func Commit(ctx context.Context, nameOrID string, options *CommitOptions) (handl
return handlers.IDResponse{}, err
}
params.Set("container", nameOrID)
- response, err := conn.DoRequest(nil, http.MethodPost, "/commit", params, nil)
+ response, err := conn.DoRequest(ctx, nil, http.MethodPost, "/commit", params, nil)
if err != nil {
return id, err
}
diff --git a/pkg/bindings/containers/containers.go b/pkg/bindings/containers/containers.go
index aafb83f65..14a173025 100644
--- a/pkg/bindings/containers/containers.go
+++ b/pkg/bindings/containers/containers.go
@@ -38,7 +38,7 @@ func List(ctx context.Context, options *ListOptions) ([]entities.ListContainer,
if err != nil {
return nil, err
}
- response, err := conn.DoRequest(nil, http.MethodGet, "/containers/json", params, nil)
+ response, err := conn.DoRequest(ctx, nil, http.MethodGet, "/containers/json", params, nil)
if err != nil {
return containers, err
}
@@ -64,7 +64,7 @@ func Prune(ctx context.Context, options *PruneOptions) ([]*reports.PruneReport,
if err != nil {
return nil, err
}
- response, err := conn.DoRequest(nil, http.MethodPost, "/containers/prune", params, nil)
+ response, err := conn.DoRequest(ctx, nil, http.MethodPost, "/containers/prune", params, nil)
if err != nil {
return nil, err
}
@@ -90,7 +90,7 @@ func Remove(ctx context.Context, nameOrID string, options *RemoveOptions) error
if err != nil {
return err
}
- response, err := conn.DoRequest(nil, http.MethodDelete, "/containers/%s", params, nil, nameOrID)
+ response, err := conn.DoRequest(ctx, nil, http.MethodDelete, "/containers/%s", params, nil, nameOrID)
if err != nil {
return err
}
@@ -115,7 +115,7 @@ func Inspect(ctx context.Context, nameOrID string, options *InspectOptions) (*de
if err != nil {
return nil, err
}
- response, err := conn.DoRequest(nil, http.MethodGet, "/containers/%s/json", params, nil, nameOrID)
+ response, err := conn.DoRequest(ctx, nil, http.MethodGet, "/containers/%s/json", params, nil, nameOrID)
if err != nil {
return nil, err
}
@@ -140,7 +140,7 @@ func Kill(ctx context.Context, nameOrID string, options *KillOptions) error {
if err != nil {
return err
}
- response, err := conn.DoRequest(nil, http.MethodPost, "/containers/%s/kill", params, nil, nameOrID)
+ response, err := conn.DoRequest(ctx, nil, http.MethodPost, "/containers/%s/kill", params, nil, nameOrID)
if err != nil {
return err
}
@@ -160,7 +160,7 @@ func Pause(ctx context.Context, nameOrID string, options *PauseOptions) error {
if err != nil {
return err
}
- response, err := conn.DoRequest(nil, http.MethodPost, "/containers/%s/pause", nil, nil, nameOrID)
+ response, err := conn.DoRequest(ctx, nil, http.MethodPost, "/containers/%s/pause", nil, nil, nameOrID)
if err != nil {
return err
}
@@ -184,7 +184,7 @@ func Restart(ctx context.Context, nameOrID string, options *RestartOptions) erro
if err != nil {
return err
}
- response, err := conn.DoRequest(nil, http.MethodPost, "/containers/%s/restart", params, nil, nameOrID)
+ response, err := conn.DoRequest(ctx, nil, http.MethodPost, "/containers/%s/restart", params, nil, nameOrID)
if err != nil {
return err
}
@@ -209,7 +209,7 @@ func Start(ctx context.Context, nameOrID string, options *StartOptions) error {
if err != nil {
return err
}
- response, err := conn.DoRequest(nil, http.MethodPost, "/containers/%s/start", params, nil, nameOrID)
+ response, err := conn.DoRequest(ctx, nil, http.MethodPost, "/containers/%s/start", params, nil, nameOrID)
if err != nil {
return err
}
@@ -235,7 +235,7 @@ func Stats(ctx context.Context, containers []string, options *StatsOptions) (cha
params.Add("containers", c)
}
- response, err := conn.DoRequest(nil, http.MethodGet, "/containers/stats", params, nil)
+ response, err := conn.DoRequest(ctx, nil, http.MethodGet, "/containers/stats", params, nil)
if err != nil {
return nil, err
}
@@ -293,7 +293,7 @@ func Top(ctx context.Context, nameOrID string, options *TopOptions) ([]string, e
psArgs := strings.Join(options.GetDescriptors(), ",")
params.Add("ps_args", psArgs)
}
- response, err := conn.DoRequest(nil, http.MethodGet, "/containers/%s/top", params, nil, nameOrID)
+ response, err := conn.DoRequest(ctx, nil, http.MethodGet, "/containers/%s/top", params, nil, nameOrID)
if err != nil {
return nil, err
}
@@ -326,7 +326,7 @@ func Unpause(ctx context.Context, nameOrID string, options *UnpauseOptions) erro
if err != nil {
return err
}
- response, err := conn.DoRequest(nil, http.MethodPost, "/containers/%s/unpause", nil, nil, nameOrID)
+ response, err := conn.DoRequest(ctx, nil, http.MethodPost, "/containers/%s/unpause", nil, nil, nameOrID)
if err != nil {
return err
}
@@ -351,7 +351,7 @@ func Wait(ctx context.Context, nameOrID string, options *WaitOptions) (int32, er
if err != nil {
return exitCode, err
}
- response, err := conn.DoRequest(nil, http.MethodPost, "/containers/%s/wait", params, nil, nameOrID)
+ response, err := conn.DoRequest(ctx, nil, http.MethodPost, "/containers/%s/wait", params, nil, nameOrID)
if err != nil {
return exitCode, err
}
@@ -372,7 +372,7 @@ func Exists(ctx context.Context, nameOrID string, options *ExistsOptions) (bool,
if err != nil {
return false, err
}
- response, err := conn.DoRequest(nil, http.MethodGet, "/containers/%s/exists", params, nil, nameOrID)
+ response, err := conn.DoRequest(ctx, nil, http.MethodGet, "/containers/%s/exists", params, nil, nameOrID)
if err != nil {
return false, err
}
@@ -395,7 +395,7 @@ func Stop(ctx context.Context, nameOrID string, options *StopOptions) error {
if err != nil {
return err
}
- response, err := conn.DoRequest(nil, http.MethodPost, "/containers/%s/stop", params, nil, nameOrID)
+ response, err := conn.DoRequest(ctx, nil, http.MethodPost, "/containers/%s/stop", params, nil, nameOrID)
if err != nil {
return err
}
@@ -416,7 +416,7 @@ func Export(ctx context.Context, nameOrID string, w io.Writer, options *ExportOp
if err != nil {
return err
}
- response, err := conn.DoRequest(nil, http.MethodGet, "/containers/%s/export", params, nil, nameOrID)
+ response, err := conn.DoRequest(ctx, nil, http.MethodGet, "/containers/%s/export", params, nil, nameOrID)
if err != nil {
return err
}
@@ -441,7 +441,7 @@ func ContainerInit(ctx context.Context, nameOrID string, options *InitOptions) e
if err != nil {
return err
}
- response, err := conn.DoRequest(nil, http.MethodPost, "/containers/%s/init", nil, nil, nameOrID)
+ response, err := conn.DoRequest(ctx, nil, http.MethodPost, "/containers/%s/init", nil, nil, nameOrID)
if err != nil {
return err
}
@@ -462,7 +462,7 @@ func ShouldRestart(ctx context.Context, nameOrID string, options *ShouldRestartO
if err != nil {
return false, err
}
- response, err := conn.DoRequest(nil, http.MethodPost, "/containers/%s/shouldrestart", nil, nil, nameOrID)
+ response, err := conn.DoRequest(ctx, nil, http.MethodPost, "/containers/%s/shouldrestart", nil, nil, nameOrID)
if err != nil {
return false, err
}
diff --git a/pkg/bindings/containers/create.go b/pkg/bindings/containers/create.go
index c0b9538a6..83b5b5ac7 100644
--- a/pkg/bindings/containers/create.go
+++ b/pkg/bindings/containers/create.go
@@ -26,7 +26,7 @@ func CreateWithSpec(ctx context.Context, s *specgen.SpecGenerator, options *Crea
return ccr, err
}
stringReader := strings.NewReader(specgenString)
- response, err := conn.DoRequest(stringReader, http.MethodPost, "/containers/create", nil, nil)
+ response, err := conn.DoRequest(ctx, stringReader, http.MethodPost, "/containers/create", nil, nil)
if err != nil {
return ccr, err
}
diff --git a/pkg/bindings/containers/diff.go b/pkg/bindings/containers/diff.go
index e4ec49809..65a4f81bb 100644
--- a/pkg/bindings/containers/diff.go
+++ b/pkg/bindings/containers/diff.go
@@ -22,7 +22,7 @@ func Diff(ctx context.Context, nameOrID string, options *DiffOptions) ([]archive
if err != nil {
return nil, err
}
- response, err := conn.DoRequest(nil, http.MethodGet, "/containers/%s/changes", params, nil, nameOrID)
+ response, err := conn.DoRequest(ctx, nil, http.MethodGet, "/containers/%s/changes", params, nil, nameOrID)
if err != nil {
return nil, err
}
diff --git a/pkg/bindings/containers/exec.go b/pkg/bindings/containers/exec.go
index 12b31aba3..e41ed66c6 100644
--- a/pkg/bindings/containers/exec.go
+++ b/pkg/bindings/containers/exec.go
@@ -35,7 +35,7 @@ func ExecCreate(ctx context.Context, nameOrID string, config *handlers.ExecCreat
}
jsonReader := strings.NewReader(string(requestJSON))
- resp, err := conn.DoRequest(jsonReader, http.MethodPost, "/containers/%s/exec", nil, nil, nameOrID)
+ resp, err := conn.DoRequest(ctx, jsonReader, http.MethodPost, "/containers/%s/exec", nil, nil, nameOrID)
if err != nil {
return "", err
}
@@ -63,7 +63,7 @@ func ExecInspect(ctx context.Context, sessionID string, options *ExecInspectOpti
logrus.Debugf("Inspecting session ID %q", sessionID)
- resp, err := conn.DoRequest(nil, http.MethodGet, "/exec/%s/json", nil, nil, sessionID)
+ resp, err := conn.DoRequest(ctx, nil, http.MethodGet, "/exec/%s/json", nil, nil, sessionID)
if err != nil {
return nil, err
}
@@ -101,7 +101,7 @@ func ExecStart(ctx context.Context, sessionID string, options *ExecStartOptions)
return err
}
- resp, err := conn.DoRequest(bytes.NewReader(bodyJSON), http.MethodPost, "/exec/%s/start", nil, nil, sessionID)
+ resp, err := conn.DoRequest(ctx, bytes.NewReader(bodyJSON), http.MethodPost, "/exec/%s/start", nil, nil, sessionID)
if err != nil {
return err
}
diff --git a/pkg/bindings/containers/healthcheck.go b/pkg/bindings/containers/healthcheck.go
index 0e65a5a46..990d8dc69 100644
--- a/pkg/bindings/containers/healthcheck.go
+++ b/pkg/bindings/containers/healthcheck.go
@@ -22,7 +22,7 @@ func RunHealthCheck(ctx context.Context, nameOrID string, options *HealthCheckOp
var (
status define.HealthCheckResults
)
- response, err := conn.DoRequest(nil, http.MethodGet, "/containers/%s/healthcheck", nil, nil, nameOrID)
+ response, err := conn.DoRequest(ctx, nil, http.MethodGet, "/containers/%s/healthcheck", nil, nil, nameOrID)
if err != nil {
return nil, err
}
diff --git a/pkg/bindings/containers/logs.go b/pkg/bindings/containers/logs.go
index 37ffdf0a5..df1dd22ea 100644
--- a/pkg/bindings/containers/logs.go
+++ b/pkg/bindings/containers/logs.go
@@ -29,7 +29,7 @@ func Logs(ctx context.Context, nameOrID string, options *LogOptions, stdoutChan,
if options.Stdout == nil && options.Stderr == nil {
params.Set("stdout", strconv.FormatBool(true))
}
- response, err := conn.DoRequest(nil, http.MethodGet, "/containers/%s/logs", params, nil, nameOrID)
+ response, err := conn.DoRequest(ctx, nil, http.MethodGet, "/containers/%s/logs", params, nil, nameOrID)
if err != nil {
return err
}
diff --git a/pkg/bindings/containers/mount.go b/pkg/bindings/containers/mount.go
index c07998fd3..5756c4cab 100644
--- a/pkg/bindings/containers/mount.go
+++ b/pkg/bindings/containers/mount.go
@@ -21,7 +21,7 @@ func Mount(ctx context.Context, nameOrID string, options *MountOptions) (string,
var (
path string
)
- response, err := conn.DoRequest(nil, http.MethodPost, "/containers/%s/mount", nil, nil, nameOrID)
+ response, err := conn.DoRequest(ctx, nil, http.MethodPost, "/containers/%s/mount", nil, nil, nameOrID)
if err != nil {
return path, err
}
@@ -41,7 +41,7 @@ func Unmount(ctx context.Context, nameOrID string, options *UnmountOptions) erro
if err != nil {
return err
}
- response, err := conn.DoRequest(nil, http.MethodPost, "/containers/%s/unmount", nil, nil, nameOrID)
+ response, err := conn.DoRequest(ctx, nil, http.MethodPost, "/containers/%s/unmount", nil, nil, nameOrID)
if err != nil {
return err
}
@@ -61,7 +61,7 @@ func GetMountedContainerPaths(ctx context.Context, options *MountedContainerPath
return nil, err
}
mounts := make(map[string]string)
- response, err := conn.DoRequest(nil, http.MethodGet, "/containers/showmounted", nil, nil)
+ response, err := conn.DoRequest(ctx, nil, http.MethodGet, "/containers/showmounted", nil, nil)
if err != nil {
return mounts, err
}
diff --git a/pkg/bindings/containers/rename.go b/pkg/bindings/containers/rename.go
index 172d7838a..29dfc581b 100644
--- a/pkg/bindings/containers/rename.go
+++ b/pkg/bindings/containers/rename.go
@@ -20,7 +20,7 @@ func Rename(ctx context.Context, nameOrID string, options *RenameOptions) error
if err != nil {
return err
}
- response, err := conn.DoRequest(nil, http.MethodPost, "/containers/%s/rename", params, nil, nameOrID)
+ response, err := conn.DoRequest(ctx, nil, http.MethodPost, "/containers/%s/rename", params, nil, nameOrID)
if err != nil {
return err
}
diff --git a/pkg/bindings/generate/generate.go b/pkg/bindings/generate/generate.go
index 742956515..641c14231 100644
--- a/pkg/bindings/generate/generate.go
+++ b/pkg/bindings/generate/generate.go
@@ -22,7 +22,7 @@ func Systemd(ctx context.Context, nameOrID string, options *SystemdOptions) (*en
return nil, err
}
- response, err := conn.DoRequest(nil, http.MethodGet, "/generate/%s/systemd", params, nil, nameOrID)
+ response, err := conn.DoRequest(ctx, nil, http.MethodGet, "/generate/%s/systemd", params, nil, nameOrID)
if err != nil {
return nil, err
}
@@ -54,7 +54,7 @@ func Kube(ctx context.Context, nameOrIDs []string, options *KubeOptions) (*entit
for _, name := range nameOrIDs {
params.Add("names", name)
}
- response, err := conn.DoRequest(nil, http.MethodGet, "/generate/kube", params, nil)
+ response, err := conn.DoRequest(ctx, nil, http.MethodGet, "/generate/kube", params, nil)
if err != nil {
return nil, err
}
diff --git a/pkg/bindings/generate/types.go b/pkg/bindings/generate/types.go
index 3c9ea87d4..6f2594604 100644
--- a/pkg/bindings/generate/types.go
+++ b/pkg/bindings/generate/types.go
@@ -16,6 +16,8 @@ type SystemdOptions struct {
New *bool
// NoHeader - Removes autogenerated by Podman and timestamp if set to true
NoHeader *bool
+ // TemplateUnitFile - Create a template unit file that uses the identity specifiers
+ TemplateUnitFile *bool
// RestartPolicy - systemd restart policy.
RestartPolicy *string
// StopTimeout - time when stopping the container.
diff --git a/pkg/bindings/generate/types_systemd_options.go b/pkg/bindings/generate/types_systemd_options.go
index 7a778a52b..b26aa7fc2 100644
--- a/pkg/bindings/generate/types_systemd_options.go
+++ b/pkg/bindings/generate/types_systemd_options.go
@@ -62,6 +62,21 @@ func (o *SystemdOptions) GetNoHeader() bool {
return *o.NoHeader
}
+// WithTemplateUnitFile set field TemplateUnitFile to given value
+func (o *SystemdOptions) WithTemplateUnitFile(value bool) *SystemdOptions {
+ o.TemplateUnitFile = &value
+ return o
+}
+
+// GetTemplateUnitFile returns value of field TemplateUnitFile
+func (o *SystemdOptions) GetTemplateUnitFile() bool {
+ if o.TemplateUnitFile == nil {
+ var z bool
+ return z
+ }
+ return *o.TemplateUnitFile
+}
+
// WithRestartPolicy set field RestartPolicy to given value
func (o *SystemdOptions) WithRestartPolicy(value string) *SystemdOptions {
o.RestartPolicy = &value
diff --git a/pkg/bindings/images/build.go b/pkg/bindings/images/build.go
index 403d90721..3b0bebe9f 100644
--- a/pkg/bindings/images/build.go
+++ b/pkg/bindings/images/build.go
@@ -392,7 +392,7 @@ func Build(ctx context.Context, containerFiles []string, options entities.BuildO
if err != nil {
return nil, err
}
- response, err := conn.DoRequest(tarfile, http.MethodPost, "/build", params, headers)
+ response, err := conn.DoRequest(ctx, tarfile, http.MethodPost, "/build", params, headers)
if err != nil {
return nil, err
}
diff --git a/pkg/bindings/images/diff.go b/pkg/bindings/images/diff.go
index 671b73089..3df0b9615 100644
--- a/pkg/bindings/images/diff.go
+++ b/pkg/bindings/images/diff.go
@@ -19,7 +19,7 @@ func Diff(ctx context.Context, nameOrID string, options *DiffOptions) ([]archive
return nil, err
}
- response, err := conn.DoRequest(nil, http.MethodGet, "/images/%s/changes", nil, nil, nameOrID)
+ response, err := conn.DoRequest(ctx, nil, http.MethodGet, "/images/%s/changes", nil, nil, nameOrID)
if err != nil {
return nil, err
}
diff --git a/pkg/bindings/images/images.go b/pkg/bindings/images/images.go
index 959481e0d..dfb500772 100644
--- a/pkg/bindings/images/images.go
+++ b/pkg/bindings/images/images.go
@@ -23,7 +23,7 @@ func Exists(ctx context.Context, nameOrID string, options *ExistsOptions) (bool,
if err != nil {
return false, err
}
- response, err := conn.DoRequest(nil, http.MethodGet, "/images/%s/exists", nil, nil, nameOrID)
+ response, err := conn.DoRequest(ctx, nil, http.MethodGet, "/images/%s/exists", nil, nil, nameOrID)
if err != nil {
return false, err
}
@@ -47,7 +47,7 @@ func List(ctx context.Context, options *ListOptions) ([]*entities.ImageSummary,
if err != nil {
return nil, err
}
- response, err := conn.DoRequest(nil, http.MethodGet, "/images/json", params, nil)
+ response, err := conn.DoRequest(ctx, nil, http.MethodGet, "/images/json", params, nil)
if err != nil {
return imageSummary, err
}
@@ -71,7 +71,7 @@ func GetImage(ctx context.Context, nameOrID string, options *GetOptions) (*entit
return nil, err
}
inspectedData := entities.ImageInspectReport{}
- response, err := conn.DoRequest(nil, http.MethodGet, "/images/%s/json", params, nil, nameOrID)
+ response, err := conn.DoRequest(ctx, nil, http.MethodGet, "/images/%s/json", params, nil, nameOrID)
if err != nil {
return &inspectedData, err
}
@@ -94,7 +94,7 @@ func Tree(ctx context.Context, nameOrID string, options *TreeOptions) (*entities
if err != nil {
return nil, err
}
- response, err := conn.DoRequest(nil, http.MethodGet, "/images/%s/tree", params, nil, nameOrID)
+ response, err := conn.DoRequest(ctx, nil, http.MethodGet, "/images/%s/tree", params, nil, nameOrID)
if err != nil {
return nil, err
}
@@ -114,7 +114,7 @@ func History(ctx context.Context, nameOrID string, options *HistoryOptions) ([]*
if err != nil {
return nil, err
}
- response, err := conn.DoRequest(nil, http.MethodGet, "/images/%s/history", nil, nil, nameOrID)
+ response, err := conn.DoRequest(ctx, nil, http.MethodGet, "/images/%s/history", nil, nil, nameOrID)
if err != nil {
return history, err
}
@@ -129,7 +129,7 @@ func Load(ctx context.Context, r io.Reader) (*entities.ImageLoadReport, error) {
if err != nil {
return nil, err
}
- response, err := conn.DoRequest(r, http.MethodPost, "/images/load", nil, nil)
+ response, err := conn.DoRequest(ctx, r, http.MethodPost, "/images/load", nil, nil)
if err != nil {
return nil, err
}
@@ -155,7 +155,7 @@ func Export(ctx context.Context, nameOrIDs []string, w io.Writer, options *Expor
for _, ref := range nameOrIDs {
params.Add("references", ref)
}
- response, err := conn.DoRequest(nil, http.MethodGet, "/images/export", params, nil)
+ response, err := conn.DoRequest(ctx, nil, http.MethodGet, "/images/export", params, nil)
if err != nil {
return err
}
@@ -185,7 +185,7 @@ func Prune(ctx context.Context, options *PruneOptions) ([]*reports.PruneReport,
if err != nil {
return nil, err
}
- response, err := conn.DoRequest(nil, http.MethodPost, "/images/prune", params, nil)
+ response, err := conn.DoRequest(ctx, nil, http.MethodPost, "/images/prune", params, nil)
if err != nil {
return deleted, err
}
@@ -207,7 +207,7 @@ func Tag(ctx context.Context, nameOrID, tag, repo string, options *TagOptions) e
params := url.Values{}
params.Set("tag", tag)
params.Set("repo", repo)
- response, err := conn.DoRequest(nil, http.MethodPost, "/images/%s/tag", params, nil, nameOrID)
+ response, err := conn.DoRequest(ctx, nil, http.MethodPost, "/images/%s/tag", params, nil, nameOrID)
if err != nil {
return err
}
@@ -229,7 +229,7 @@ func Untag(ctx context.Context, nameOrID, tag, repo string, options *UntagOption
params := url.Values{}
params.Set("tag", tag)
params.Set("repo", repo)
- response, err := conn.DoRequest(nil, http.MethodPost, "/images/%s/untag", params, nil, nameOrID)
+ response, err := conn.DoRequest(ctx, nil, http.MethodPost, "/images/%s/untag", params, nil, nameOrID)
if err != nil {
return err
}
@@ -257,7 +257,7 @@ func Import(ctx context.Context, r io.Reader, options *ImportOptions) (*entities
if err != nil {
return nil, err
}
- response, err := conn.DoRequest(r, http.MethodPost, "/images/import", params, nil)
+ response, err := conn.DoRequest(ctx, r, http.MethodPost, "/images/import", params, nil)
if err != nil {
return nil, err
}
@@ -298,7 +298,7 @@ func Push(ctx context.Context, source string, destination string, options *PushO
params.Set("destination", destination)
path := fmt.Sprintf("/images/%s/push", source)
- response, err := conn.DoRequest(nil, http.MethodPost, path, params, header)
+ response, err := conn.DoRequest(ctx, nil, http.MethodPost, path, params, header)
if err != nil {
return err
}
@@ -334,7 +334,7 @@ func Search(ctx context.Context, term string, options *SearchOptions) ([]entitie
return nil, err
}
- response, err := conn.DoRequest(nil, http.MethodGet, "/images/search", params, header)
+ response, err := conn.DoRequest(ctx, nil, http.MethodGet, "/images/search", params, header)
if err != nil {
return nil, err
}
diff --git a/pkg/bindings/images/pull.go b/pkg/bindings/images/pull.go
index 7dfe9560c..be21aa593 100644
--- a/pkg/bindings/images/pull.go
+++ b/pkg/bindings/images/pull.go
@@ -47,7 +47,7 @@ func Pull(ctx context.Context, rawImage string, options *PullOptions) ([]string,
return nil, err
}
- response, err := conn.DoRequest(nil, http.MethodPost, "/images/pull", params, header)
+ response, err := conn.DoRequest(ctx, nil, http.MethodPost, "/images/pull", params, header)
if err != nil {
return nil, err
}
diff --git a/pkg/bindings/images/rm.go b/pkg/bindings/images/rm.go
index 461eb7729..47d7c2a4b 100644
--- a/pkg/bindings/images/rm.go
+++ b/pkg/bindings/images/rm.go
@@ -32,7 +32,7 @@ func Remove(ctx context.Context, images []string, options *RemoveOptions) (*enti
for _, image := range images {
params.Add("images", image)
}
- response, err := conn.DoRequest(nil, http.MethodDelete, "/images/remove", params, nil)
+ response, err := conn.DoRequest(ctx, nil, http.MethodDelete, "/images/remove", params, nil)
if err != nil {
return nil, []error{err}
}
diff --git a/pkg/bindings/manifests/manifests.go b/pkg/bindings/manifests/manifests.go
index 6aa4961f1..af74eb406 100644
--- a/pkg/bindings/manifests/manifests.go
+++ b/pkg/bindings/manifests/manifests.go
@@ -42,7 +42,7 @@ func Create(ctx context.Context, names, images []string, options *CreateOptions)
params.Add("image", i)
}
- response, err := conn.DoRequest(nil, http.MethodPost, "/manifests/create", params, nil)
+ response, err := conn.DoRequest(ctx, nil, http.MethodPost, "/manifests/create", params, nil)
if err != nil {
return "", err
}
@@ -57,7 +57,7 @@ func Exists(ctx context.Context, name string, options *ExistsOptions) (bool, err
if err != nil {
return false, err
}
- response, err := conn.DoRequest(nil, http.MethodGet, "/manifests/%s/exists", nil, nil, name)
+ response, err := conn.DoRequest(ctx, nil, http.MethodGet, "/manifests/%s/exists", nil, nil, name)
if err != nil {
return false, err
}
@@ -77,7 +77,7 @@ func Inspect(ctx context.Context, name string, options *InspectOptions) (*manife
if err != nil {
return nil, err
}
- response, err := conn.DoRequest(nil, http.MethodGet, "/manifests/%s/json", nil, nil, name)
+ response, err := conn.DoRequest(ctx, nil, http.MethodGet, "/manifests/%s/json", nil, nil, name)
if err != nil {
return nil, err
}
@@ -102,7 +102,7 @@ func Add(ctx context.Context, name string, options *AddOptions) (string, error)
return "", err
}
stringReader := strings.NewReader(optionsString)
- response, err := conn.DoRequest(stringReader, http.MethodPost, "/manifests/%s/add", nil, nil, name)
+ response, err := conn.DoRequest(ctx, stringReader, http.MethodPost, "/manifests/%s/add", nil, nil, name)
if err != nil {
return "", err
}
@@ -125,7 +125,7 @@ func Remove(ctx context.Context, name, digest string, options *RemoveOptions) (s
}
params := url.Values{}
params.Set("digest", digest)
- response, err := conn.DoRequest(nil, http.MethodDelete, "/manifests/%s", params, nil, name)
+ response, err := conn.DoRequest(ctx, nil, http.MethodDelete, "/manifests/%s", params, nil, name)
if err != nil {
return "", err
}
@@ -163,7 +163,7 @@ func Push(ctx context.Context, name, destination string, options *images.PushOpt
}
params.Set("image", name)
params.Set("destination", destination)
- response, err := conn.DoRequest(nil, http.MethodPost, "/manifests/%s/push", params, nil, name)
+ response, err := conn.DoRequest(ctx, nil, http.MethodPost, "/manifests/%s/push", params, nil, name)
if err != nil {
return "", err
}
@@ -187,7 +187,7 @@ func Push(ctx context.Context, name, destination string, options *images.PushOpt
// return "", err
// }
// stringReader := strings.NewReader(optionsString)
-// response, err := conn.DoRequest(stringReader, http.MethodPost, "/manifests/%s/annotate", params, name)
+// response, err := conn.DoRequest(ctx, stringReader, http.MethodPost, "/manifests/%s/annotate", params, name)
// if err != nil {
// return "", err
// }
diff --git a/pkg/bindings/network/network.go b/pkg/bindings/network/network.go
index 5a0a34f56..172598be1 100644
--- a/pkg/bindings/network/network.go
+++ b/pkg/bindings/network/network.go
@@ -28,7 +28,7 @@ func Create(ctx context.Context, network *types.Network) (types.Network, error)
return report, err
}
reader := strings.NewReader(networkConfig)
- response, err := conn.DoRequest(reader, http.MethodPost, "/networks/create", nil, nil)
+ response, err := conn.DoRequest(ctx, reader, http.MethodPost, "/networks/create", nil, nil)
if err != nil {
return report, err
}
@@ -44,7 +44,7 @@ func Inspect(ctx context.Context, nameOrID string, _ *InspectOptions) (types.Net
if err != nil {
return net, err
}
- response, err := conn.DoRequest(nil, http.MethodGet, "/networks/%s/json", nil, nil, nameOrID)
+ response, err := conn.DoRequest(ctx, nil, http.MethodGet, "/networks/%s/json", nil, nil, nameOrID)
if err != nil {
return net, err
}
@@ -69,7 +69,7 @@ func Remove(ctx context.Context, nameOrID string, options *RemoveOptions) ([]*en
if err != nil {
return nil, err
}
- response, err := conn.DoRequest(nil, http.MethodDelete, "/networks/%s", params, nil, nameOrID)
+ response, err := conn.DoRequest(ctx, nil, http.MethodDelete, "/networks/%s", params, nil, nameOrID)
if err != nil {
return nil, err
}
@@ -92,7 +92,7 @@ func List(ctx context.Context, options *ListOptions) ([]types.Network, error) {
if err != nil {
return nil, err
}
- response, err := conn.DoRequest(nil, http.MethodGet, "/networks/json", params, nil)
+ response, err := conn.DoRequest(ctx, nil, http.MethodGet, "/networks/json", params, nil)
if err != nil {
return netList, err
}
@@ -128,7 +128,7 @@ func Disconnect(ctx context.Context, networkName string, ContainerNameOrID strin
return err
}
stringReader := strings.NewReader(body)
- response, err := conn.DoRequest(stringReader, http.MethodPost, "/networks/%s/disconnect", params, nil, networkName)
+ response, err := conn.DoRequest(ctx, stringReader, http.MethodPost, "/networks/%s/disconnect", params, nil, networkName)
if err != nil {
return err
}
@@ -163,7 +163,7 @@ func Connect(ctx context.Context, networkName string, ContainerNameOrID string,
return err
}
stringReader := strings.NewReader(body)
- response, err := conn.DoRequest(stringReader, http.MethodPost, "/networks/%s/connect", params, nil, networkName)
+ response, err := conn.DoRequest(ctx, stringReader, http.MethodPost, "/networks/%s/connect", params, nil, networkName)
if err != nil {
return err
}
@@ -178,7 +178,7 @@ func Exists(ctx context.Context, nameOrID string, options *ExistsOptions) (bool,
if err != nil {
return false, err
}
- response, err := conn.DoRequest(nil, http.MethodGet, "/networks/%s/exists", nil, nil, nameOrID)
+ response, err := conn.DoRequest(ctx, nil, http.MethodGet, "/networks/%s/exists", nil, nil, nameOrID)
if err != nil {
return false, err
}
@@ -204,7 +204,7 @@ func Prune(ctx context.Context, options *PruneOptions) ([]*entities.NetworkPrune
return nil, err
}
- response, err := conn.DoRequest(nil, http.MethodPost, "/networks/prune", params, nil)
+ response, err := conn.DoRequest(ctx, nil, http.MethodPost, "/networks/prune", params, nil)
if err != nil {
return nil, err
}
diff --git a/pkg/bindings/play/play.go b/pkg/bindings/play/play.go
index bdd13d03d..2cd7c3997 100644
--- a/pkg/bindings/play/play.go
+++ b/pkg/bindings/play/play.go
@@ -45,7 +45,7 @@ func Kube(ctx context.Context, path string, options *KubeOptions) (*entities.Pla
return nil, err
}
- response, err := conn.DoRequest(f, http.MethodPost, "/play/kube", params, header)
+ response, err := conn.DoRequest(ctx, f, http.MethodPost, "/play/kube", params, header)
if err != nil {
return nil, err
}
@@ -74,7 +74,7 @@ func KubeDown(ctx context.Context, path string) (*entities.PlayKubeReport, error
logrus.Warn(err)
}
}()
- response, err := conn.DoRequest(f, http.MethodDelete, "/play/kube", nil, nil)
+ response, err := conn.DoRequest(ctx, f, http.MethodDelete, "/play/kube", nil, nil)
if err != nil {
return nil, err
}
diff --git a/pkg/bindings/pods/pods.go b/pkg/bindings/pods/pods.go
index 3b5832373..9e32f766d 100644
--- a/pkg/bindings/pods/pods.go
+++ b/pkg/bindings/pods/pods.go
@@ -29,7 +29,7 @@ func CreatePodFromSpec(ctx context.Context, spec *entities.PodSpec) (*entities.P
return nil, err
}
stringReader := strings.NewReader(specString)
- response, err := conn.DoRequest(stringReader, http.MethodPost, "/pods/create", nil, nil)
+ response, err := conn.DoRequest(ctx, stringReader, http.MethodPost, "/pods/create", nil, nil)
if err != nil {
return nil, err
}
@@ -44,7 +44,7 @@ func Exists(ctx context.Context, nameOrID string, options *ExistsOptions) (bool,
if err != nil {
return false, err
}
- response, err := conn.DoRequest(nil, http.MethodGet, "/pods/%s/exists", nil, nil, nameOrID)
+ response, err := conn.DoRequest(ctx, nil, http.MethodGet, "/pods/%s/exists", nil, nil, nameOrID)
if err != nil {
return false, err
}
@@ -66,7 +66,7 @@ func Inspect(ctx context.Context, nameOrID string, options *InspectOptions) (*en
if err != nil {
return nil, err
}
- response, err := conn.DoRequest(nil, http.MethodGet, "/pods/%s/json", nil, nil, nameOrID)
+ response, err := conn.DoRequest(ctx, nil, http.MethodGet, "/pods/%s/json", nil, nil, nameOrID)
if err != nil {
return nil, err
}
@@ -92,7 +92,7 @@ func Kill(ctx context.Context, nameOrID string, options *KillOptions) (*entities
if err != nil {
return nil, err
}
- response, err := conn.DoRequest(nil, http.MethodPost, "/pods/%s/kill", params, nil, nameOrID)
+ response, err := conn.DoRequest(ctx, nil, http.MethodPost, "/pods/%s/kill", params, nil, nameOrID)
if err != nil {
return nil, err
}
@@ -112,7 +112,7 @@ func Pause(ctx context.Context, nameOrID string, options *PauseOptions) (*entiti
if err != nil {
return nil, err
}
- response, err := conn.DoRequest(nil, http.MethodPost, "/pods/%s/pause", nil, nil, nameOrID)
+ response, err := conn.DoRequest(ctx, nil, http.MethodPost, "/pods/%s/pause", nil, nil, nameOrID)
if err != nil {
return nil, err
}
@@ -133,7 +133,7 @@ func Prune(ctx context.Context, options *PruneOptions) ([]*entities.PodPruneRepo
if err != nil {
return nil, err
}
- response, err := conn.DoRequest(nil, http.MethodPost, "/pods/prune", nil, nil)
+ response, err := conn.DoRequest(ctx, nil, http.MethodPost, "/pods/prune", nil, nil)
if err != nil {
return nil, err
}
@@ -159,7 +159,7 @@ func List(ctx context.Context, options *ListOptions) ([]*entities.ListPodsReport
if err != nil {
return nil, err
}
- response, err := conn.DoRequest(nil, http.MethodGet, "/pods/json", params, nil)
+ response, err := conn.DoRequest(ctx, nil, http.MethodGet, "/pods/json", params, nil)
if err != nil {
return podsReports, err
}
@@ -179,7 +179,7 @@ func Restart(ctx context.Context, nameOrID string, options *RestartOptions) (*en
if err != nil {
return nil, err
}
- response, err := conn.DoRequest(nil, http.MethodPost, "/pods/%s/restart", nil, nil, nameOrID)
+ response, err := conn.DoRequest(ctx, nil, http.MethodPost, "/pods/%s/restart", nil, nil, nameOrID)
if err != nil {
return nil, err
}
@@ -203,7 +203,7 @@ func Remove(ctx context.Context, nameOrID string, options *RemoveOptions) (*enti
if err != nil {
return nil, err
}
- response, err := conn.DoRequest(nil, http.MethodDelete, "/pods/%s", params, nil, nameOrID)
+ response, err := conn.DoRequest(ctx, nil, http.MethodDelete, "/pods/%s", params, nil, nameOrID)
if err != nil {
return nil, err
}
@@ -223,7 +223,7 @@ func Start(ctx context.Context, nameOrID string, options *StartOptions) (*entiti
if err != nil {
return nil, err
}
- response, err := conn.DoRequest(nil, http.MethodPost, "/pods/%s/start", nil, nil, nameOrID)
+ response, err := conn.DoRequest(ctx, nil, http.MethodPost, "/pods/%s/start", nil, nil, nameOrID)
if err != nil {
return nil, err
}
@@ -252,7 +252,7 @@ func Stop(ctx context.Context, nameOrID string, options *StopOptions) (*entities
if err != nil {
return nil, err
}
- response, err := conn.DoRequest(nil, http.MethodPost, "/pods/%s/stop", params, nil, nameOrID)
+ response, err := conn.DoRequest(ctx, nil, http.MethodPost, "/pods/%s/stop", params, nil, nameOrID)
if err != nil {
return nil, err
}
@@ -279,7 +279,7 @@ func Top(ctx context.Context, nameOrID string, options *TopOptions) ([]string, e
if descriptors := options.GetDescriptors(); len(descriptors) > 0 {
params.Set("ps_args", strings.Join(descriptors, ","))
}
- response, err := conn.DoRequest(nil, http.MethodGet, "/pods/%s/top", params, nil, nameOrID)
+ response, err := conn.DoRequest(ctx, nil, http.MethodGet, "/pods/%s/top", params, nil, nameOrID)
if err != nil {
return nil, err
}
@@ -312,7 +312,7 @@ func Unpause(ctx context.Context, nameOrID string, options *UnpauseOptions) (*en
if err != nil {
return nil, err
}
- response, err := conn.DoRequest(nil, http.MethodPost, "/pods/%s/unpause", nil, nil, nameOrID)
+ response, err := conn.DoRequest(ctx, nil, http.MethodPost, "/pods/%s/unpause", nil, nil, nameOrID)
if err != nil {
return nil, err
}
@@ -339,7 +339,7 @@ func Stats(ctx context.Context, namesOrIDs []string, options *StatsOptions) ([]*
}
var reports []*entities.PodStatsReport
- response, err := conn.DoRequest(nil, http.MethodGet, "/pods/stats", params, nil)
+ response, err := conn.DoRequest(ctx, nil, http.MethodGet, "/pods/stats", params, nil)
if err != nil {
return nil, err
}
diff --git a/pkg/bindings/secrets/secrets.go b/pkg/bindings/secrets/secrets.go
index c439971c9..3847188a5 100644
--- a/pkg/bindings/secrets/secrets.go
+++ b/pkg/bindings/secrets/secrets.go
@@ -22,7 +22,7 @@ func List(ctx context.Context, options *ListOptions) ([]*entities.SecretInfoRepo
if err != nil {
return nil, err
}
- response, err := conn.DoRequest(nil, http.MethodGet, "/secrets/json", params, nil)
+ response, err := conn.DoRequest(ctx, nil, http.MethodGet, "/secrets/json", params, nil)
if err != nil {
return secrs, err
}
@@ -40,7 +40,7 @@ func Inspect(ctx context.Context, nameOrID string, options *InspectOptions) (*en
if err != nil {
return nil, err
}
- response, err := conn.DoRequest(nil, http.MethodGet, "/secrets/%s/json", nil, nil, nameOrID)
+ response, err := conn.DoRequest(ctx, nil, http.MethodGet, "/secrets/%s/json", nil, nil, nameOrID)
if err != nil {
return inspect, err
}
@@ -56,7 +56,7 @@ func Remove(ctx context.Context, nameOrID string) error {
return err
}
- response, err := conn.DoRequest(nil, http.MethodDelete, "/secrets/%s", nil, nil, nameOrID)
+ response, err := conn.DoRequest(ctx, nil, http.MethodDelete, "/secrets/%s", nil, nil, nameOrID)
if err != nil {
return err
}
@@ -80,7 +80,7 @@ func Create(ctx context.Context, reader io.Reader, options *CreateOptions) (*ent
return nil, err
}
- response, err := conn.DoRequest(reader, http.MethodPost, "/secrets/create", params, nil)
+ response, err := conn.DoRequest(ctx, reader, http.MethodPost, "/secrets/create", params, nil)
if err != nil {
return nil, err
}
diff --git a/pkg/bindings/system/info.go b/pkg/bindings/system/info.go
index 8a307a4ca..8d7c30b26 100644
--- a/pkg/bindings/system/info.go
+++ b/pkg/bindings/system/info.go
@@ -14,7 +14,7 @@ func Info(ctx context.Context, _ *InfoOptions) (*define.Info, error) {
if err != nil {
return nil, err
}
- response, err := conn.DoRequest(nil, http.MethodGet, "/info", nil, nil)
+ response, err := conn.DoRequest(ctx, nil, http.MethodGet, "/info", nil, nil)
if err != nil {
return nil, err
}
diff --git a/pkg/bindings/system/system.go b/pkg/bindings/system/system.go
index 719cde52e..3f59b3d7e 100644
--- a/pkg/bindings/system/system.go
+++ b/pkg/bindings/system/system.go
@@ -27,7 +27,7 @@ func Events(ctx context.Context, eventChan chan entities.Event, cancelChan chan
if err != nil {
return err
}
- response, err := conn.DoRequest(nil, http.MethodGet, "/events", params, nil)
+ response, err := conn.DoRequest(ctx, nil, http.MethodGet, "/events", params, nil)
if err != nil {
return err
}
@@ -73,7 +73,7 @@ func Prune(ctx context.Context, options *PruneOptions) (*entities.SystemPruneRep
if err != nil {
return nil, err
}
- response, err := conn.DoRequest(nil, http.MethodPost, "/system/prune", params, nil)
+ response, err := conn.DoRequest(ctx, nil, http.MethodPost, "/system/prune", params, nil)
if err != nil {
return nil, err
}
@@ -101,7 +101,7 @@ func Version(ctx context.Context, options *VersionOptions) (*entities.SystemVers
if err != nil {
return nil, err
}
- response, err := conn.DoRequest(nil, http.MethodGet, "/version", nil, nil)
+ response, err := conn.DoRequest(ctx, nil, http.MethodGet, "/version", nil, nil)
if err != nil {
return nil, err
}
@@ -142,7 +142,7 @@ func DiskUsage(ctx context.Context, options *DiskOptions) (*entities.SystemDfRep
if err != nil {
return nil, err
}
- response, err := conn.DoRequest(nil, http.MethodGet, "/system/df", nil, nil)
+ response, err := conn.DoRequest(ctx, nil, http.MethodGet, "/system/df", nil, nil)
if err != nil {
return nil, err
}
diff --git a/pkg/bindings/test/connection_test.go b/pkg/bindings/test/connection_test.go
new file mode 100644
index 000000000..561cf32b5
--- /dev/null
+++ b/pkg/bindings/test/connection_test.go
@@ -0,0 +1,68 @@
+package test_bindings
+
+import (
+ "context"
+ "time"
+
+ "github.com/containers/podman/v3/pkg/bindings/containers"
+ "github.com/containers/podman/v3/pkg/bindings/system"
+ . "github.com/onsi/ginkgo"
+ . "github.com/onsi/gomega"
+ "github.com/onsi/gomega/gexec"
+)
+
+var _ = Describe("Podman connection", func() {
+ var (
+ bt *bindingTest
+ s *gexec.Session
+ )
+
+ BeforeEach(func() {
+ bt = newBindingTest()
+ bt.RestoreImagesFromCache()
+ s = bt.startAPIService()
+ time.Sleep(1 * time.Second)
+ err := bt.NewConnection()
+ Expect(err).To(BeNil())
+ })
+
+ AfterEach(func() {
+ s.Kill()
+ bt.cleanup()
+ })
+
+ It("request on cancelled context results in error", func() {
+ ctx, cancel := context.WithCancel(bt.conn)
+ cancel()
+ _, err := system.Version(ctx, nil)
+ Expect(err).To(MatchError(ctx.Err()))
+ })
+
+ It("cancel request in flight reports cancelled context", func() {
+ var name = "top"
+ _, err := bt.RunTopContainer(&name, nil)
+ Expect(err).To(BeNil())
+
+ errChan := make(chan error)
+ ctx, cancel := context.WithCancel(bt.conn)
+
+ go func() {
+ defer close(errChan)
+ _, err := containers.Wait(ctx, name, nil)
+ errChan <- err
+ }()
+
+ // Wait for the goroutine to fire the request
+ time.Sleep(1 * time.Second)
+
+ cancel()
+
+ select {
+ case err, ok := <-errChan:
+ Expect(ok).To(BeTrue())
+ Expect(err).To(MatchError(ctx.Err()))
+ case <-time.NewTimer(1 * time.Second).C:
+ Fail("cancelled request did not return in less than 1 second")
+ }
+ })
+})
diff --git a/pkg/bindings/volumes/volumes.go b/pkg/bindings/volumes/volumes.go
index 56cf13ade..ce5a01c49 100644
--- a/pkg/bindings/volumes/volumes.go
+++ b/pkg/bindings/volumes/volumes.go
@@ -29,7 +29,7 @@ func Create(ctx context.Context, config entities.VolumeCreateOptions, options *C
return nil, err
}
stringReader := strings.NewReader(createString)
- response, err := conn.DoRequest(stringReader, http.MethodPost, "/volumes/create", nil, nil)
+ response, err := conn.DoRequest(ctx, stringReader, http.MethodPost, "/volumes/create", nil, nil)
if err != nil {
return nil, err
}
@@ -51,7 +51,7 @@ func Inspect(ctx context.Context, nameOrID string, options *InspectOptions) (*en
if err != nil {
return nil, err
}
- response, err := conn.DoRequest(nil, http.MethodGet, "/volumes/%s/json", nil, nil, nameOrID)
+ response, err := conn.DoRequest(ctx, nil, http.MethodGet, "/volumes/%s/json", nil, nil, nameOrID)
if err != nil {
return &inspect, err
}
@@ -74,7 +74,7 @@ func List(ctx context.Context, options *ListOptions) ([]*entities.VolumeListRepo
if err != nil {
return nil, err
}
- response, err := conn.DoRequest(nil, http.MethodGet, "/volumes/json", params, nil)
+ response, err := conn.DoRequest(ctx, nil, http.MethodGet, "/volumes/json", params, nil)
if err != nil {
return vols, err
}
@@ -96,7 +96,7 @@ func Prune(ctx context.Context, options *PruneOptions) ([]*reports.PruneReport,
if err != nil {
return nil, err
}
- response, err := conn.DoRequest(nil, http.MethodPost, "/volumes/prune", params, nil)
+ response, err := conn.DoRequest(ctx, nil, http.MethodPost, "/volumes/prune", params, nil)
if err != nil {
return nil, err
}
@@ -116,7 +116,7 @@ func Remove(ctx context.Context, nameOrID string, options *RemoveOptions) error
if err != nil {
return err
}
- response, err := conn.DoRequest(nil, http.MethodDelete, "/volumes/%s", params, nil, nameOrID)
+ response, err := conn.DoRequest(ctx, nil, http.MethodDelete, "/volumes/%s", params, nil, nameOrID)
if err != nil {
return err
}
@@ -131,7 +131,7 @@ func Exists(ctx context.Context, nameOrID string, options *ExistsOptions) (bool,
if err != nil {
return false, err
}
- response, err := conn.DoRequest(nil, http.MethodGet, "/volumes/%s/exists", nil, nil, nameOrID)
+ response, err := conn.DoRequest(ctx, nil, http.MethodGet, "/volumes/%s/exists", nil, nil, nameOrID)
if err != nil {
return false, err
}
diff --git a/pkg/domain/entities/containers.go b/pkg/domain/entities/containers.go
index 869c616ea..8b7cd62d9 100644
--- a/pkg/domain/entities/containers.go
+++ b/pkg/domain/entities/containers.go
@@ -190,11 +190,14 @@ type CheckpointOptions struct {
PreCheckPoint bool
WithPrevious bool
Compression archive.Compression
+ PrintStats bool
}
type CheckpointReport struct {
- Err error
- Id string //nolint
+ Err error `json:"-"`
+ Id string `json:"Id` //nolint
+ RuntimeDuration int64 `json:"runtime_checkpoint_duration"`
+ CRIUStatistics *define.CRIUCheckpointRestoreStatistics `json:"criu_statistics"`
}
type RestoreOptions struct {
@@ -211,11 +214,14 @@ type RestoreOptions struct {
ImportPrevious string
PublishPorts []nettypes.PortMapping
Pod string
+ PrintStats bool
}
type RestoreReport struct {
- Err error
- Id string //nolint
+ Err error `json:"-"`
+ Id string `json:"Id` //nolint
+ RuntimeDuration int64 `json:"runtime_restore_duration"`
+ CRIUStatistics *define.CRIUCheckpointRestoreStatistics `json:"criu_statistics"`
}
type ContainerCreateReport struct {
diff --git a/pkg/domain/entities/generate.go b/pkg/domain/entities/generate.go
index 7809c5241..dfb5bfc6c 100644
--- a/pkg/domain/entities/generate.go
+++ b/pkg/domain/entities/generate.go
@@ -20,6 +20,8 @@ type GenerateSystemdOptions struct {
Separator string
// NoHeader - skip header generation
NoHeader bool
+ // TemplateUnitFile - make use of %i and %I to differentiate between the different instances of the unit
+ TemplateUnitFile bool
}
// GenerateSystemdReport
diff --git a/pkg/domain/entities/pods.go b/pkg/domain/entities/pods.go
index 1df18be58..70d2be1e6 100644
--- a/pkg/domain/entities/pods.go
+++ b/pkg/domain/entities/pods.go
@@ -266,6 +266,15 @@ type ContainerCreateOptions struct {
CgroupConf []string
}
+func NewInfraContainerCreateOptions() ContainerCreateOptions {
+ options := ContainerCreateOptions{
+ IsInfra: true,
+ ImageVolume: "bind",
+ MemorySwappiness: -1,
+ }
+ return options
+}
+
type PodCreateReport struct {
Id string //nolint
}
diff --git a/pkg/domain/infra/abi/containers.go b/pkg/domain/infra/abi/containers.go
index c30129001..69c628669 100644
--- a/pkg/domain/infra/abi/containers.go
+++ b/pkg/domain/infra/abi/containers.go
@@ -515,6 +515,7 @@ func (ic *ContainerEngine) ContainerCheckpoint(ctx context.Context, namesOrIds [
PreCheckPoint: options.PreCheckPoint,
WithPrevious: options.WithPrevious,
Compression: options.Compression,
+ PrintStats: options.PrintStats,
}
if options.All {
@@ -531,10 +532,12 @@ func (ic *ContainerEngine) ContainerCheckpoint(ctx context.Context, namesOrIds [
}
reports := make([]*entities.CheckpointReport, 0, len(cons))
for _, con := range cons {
- err = con.Checkpoint(ctx, checkOpts)
+ criuStatistics, runtimeCheckpointDuration, err := con.Checkpoint(ctx, checkOpts)
reports = append(reports, &entities.CheckpointReport{
- Err: err,
- Id: con.ID(),
+ Err: err,
+ Id: con.ID(),
+ RuntimeDuration: runtimeCheckpointDuration,
+ CRIUStatistics: criuStatistics,
})
}
return reports, nil
@@ -557,6 +560,7 @@ func (ic *ContainerEngine) ContainerRestore(ctx context.Context, namesOrIds []st
IgnoreStaticMAC: options.IgnoreStaticMAC,
ImportPrevious: options.ImportPrevious,
Pod: options.Pod,
+ PrintStats: options.PrintStats,
}
filterFuncs := []libpod.ContainerFilter{
@@ -579,10 +583,12 @@ func (ic *ContainerEngine) ContainerRestore(ctx context.Context, namesOrIds []st
}
reports := make([]*entities.RestoreReport, 0, len(cons))
for _, con := range cons {
- err := con.Restore(ctx, restoreOptions)
+ criuStatistics, runtimeRestoreDuration, err := con.Restore(ctx, restoreOptions)
reports = append(reports, &entities.RestoreReport{
- Err: err,
- Id: con.ID(),
+ Err: err,
+ Id: con.ID(),
+ RuntimeDuration: runtimeRestoreDuration,
+ CRIUStatistics: criuStatistics,
})
}
return reports, nil
diff --git a/pkg/domain/infra/abi/play.go b/pkg/domain/infra/abi/play.go
index 3fdb3f286..d2bb95f7c 100644
--- a/pkg/domain/infra/abi/play.go
+++ b/pkg/domain/infra/abi/play.go
@@ -270,7 +270,7 @@ func (ic *ContainerEngine) playKubePod(ctx context.Context, podName string, podY
if podOpt.Infra {
infraImage := util.DefaultContainerConfig().Engine.InfraImage
- infraOptions := entities.ContainerCreateOptions{ImageVolume: "bind"}
+ infraOptions := entities.NewInfraContainerCreateOptions()
podSpec.PodSpecGen.InfraImage = infraImage
podSpec.PodSpecGen.NoInfra = false
podSpec.PodSpecGen.InfraContainerSpec = specgen.NewSpecGenerator(infraImage, false)
diff --git a/pkg/domain/infra/tunnel/generate.go b/pkg/domain/infra/tunnel/generate.go
index 9f69abb1a..3a35dd59c 100644
--- a/pkg/domain/infra/tunnel/generate.go
+++ b/pkg/domain/infra/tunnel/generate.go
@@ -8,7 +8,7 @@ import (
)
func (ic *ContainerEngine) GenerateSystemd(ctx context.Context, nameOrID string, opts entities.GenerateSystemdOptions) (*entities.GenerateSystemdReport, error) {
- options := new(generate.SystemdOptions).WithUseName(opts.Name).WithContainerPrefix(opts.ContainerPrefix).WithNew(opts.New).WithNoHeader(opts.NoHeader)
+ options := new(generate.SystemdOptions).WithUseName(opts.Name).WithContainerPrefix(opts.ContainerPrefix).WithNew(opts.New).WithNoHeader(opts.NoHeader).WithTemplateUnitFile(opts.TemplateUnitFile)
options.WithPodPrefix(opts.PodPrefix).WithSeparator(opts.Separator)
if opts.RestartPolicy != nil {
options.WithRestartPolicy(*opts.RestartPolicy)
diff --git a/pkg/specgenutil/specgen.go b/pkg/specgenutil/specgen.go
index 4e8f954fb..04d3add32 100644
--- a/pkg/specgenutil/specgen.go
+++ b/pkg/specgenutil/specgen.go
@@ -172,7 +172,7 @@ func getMemoryLimits(s *specgen.SpecGenerator, c *entities.ContainerCreateOption
memory.Kernel = &mk
hasLimits = true
}
- if c.MemorySwappiness > 0 {
+ if c.MemorySwappiness >= 0 {
swappiness := uint64(c.MemorySwappiness)
memory.Swappiness = &swappiness
hasLimits = true
diff --git a/pkg/systemd/generate/common.go b/pkg/systemd/generate/common.go
index 3515bb3b7..24c85a27e 100644
--- a/pkg/systemd/generate/common.go
+++ b/pkg/systemd/generate/common.go
@@ -23,7 +23,7 @@ func validateRestartPolicy(restart string) error {
return errors.Errorf("%s is not a valid restart policy", restart)
}
-const headerTemplate = `# {{{{.ServiceName}}}}.service
+const headerTemplate = `# {{{{.ServiceName}}}}{{{{- if (eq .IdentifySpecifier true) }}}}@{{{{- end}}}}.service
{{{{- if (eq .GenerateNoHeader false) }}}}
# autogenerated by Podman {{{{.PodmanVersion}}}}
{{{{- if .TimeStamp}}}}
@@ -32,7 +32,7 @@ const headerTemplate = `# {{{{.ServiceName}}}}.service
{{{{- end}}}}
[Unit]
-Description=Podman {{{{.ServiceName}}}}.service
+Description=Podman {{{{.ServiceName}}}}.service{{{{- if (eq .IdentifySpecifier true) }}}} for %I{{{{- end}}}}
Documentation=man:podman-generate-systemd(1)
Wants=network-online.target
After=network-online.target
diff --git a/pkg/systemd/generate/containers.go b/pkg/systemd/generate/containers.go
index 037652a6d..95ff13371 100644
--- a/pkg/systemd/generate/containers.go
+++ b/pkg/systemd/generate/containers.go
@@ -90,6 +90,8 @@ type containerInfo struct {
// Location of the RunRoot for the container. Required for ensuring the tmpfs
// or volume exists and is mounted when coming online at boot.
RunRoot string
+ // Add %i and %I to description and execute parts
+ IdentifySpecifier bool
}
const containerTemplate = headerTemplate + `
@@ -99,7 +101,7 @@ After={{{{- range $index, $value := .BoundToServices -}}}}{{{{if $index}}}} {{{{
{{{{- end}}}}
[Service]
-Environment={{{{.EnvVariable}}}}=%n
+Environment={{{{.EnvVariable}}}}=%n{{{{- if (eq .IdentifySpecifier true) }}}}-%i{{{{- end}}}}
{{{{- if .ExtraEnvs}}}}
Environment={{{{- range $index, $value := .ExtraEnvs -}}}}{{{{if $index}}}} {{{{end}}}}{{{{ $value }}}}{{{{end}}}}
{{{{- end}}}}
@@ -204,6 +206,46 @@ func containerServiceName(ctr *libpod.Container, options entities.GenerateSystem
return nameOrID, serviceName
}
+// setContainerNameForTemplate updates startCommand to contain the name argument with
+// a value that includes the identify specifier.
+// In case startCommand doesn't contain that argument it's added after "run" and its
+// value will be set to info.ServiceName concated with the identify specifier %i.
+func setContainerNameForTemplate(startCommand []string, info *containerInfo) ([]string, error) {
+ // find the index of "--name" in the command slice
+ nameIx := -1
+ for argIx, arg := range startCommand {
+ if arg == "--name" {
+ nameIx = argIx + 1
+ break
+ }
+ if strings.HasPrefix(arg, "--name=") {
+ nameIx = argIx
+ break
+ }
+ }
+ switch {
+ case nameIx == -1:
+ // if not found, add --name argument in the command slice before the "run" argument.
+ // it's assumed that the command slice contains this argument.
+ runIx := -1
+ for argIx, arg := range startCommand {
+ if arg == "run" {
+ runIx = argIx
+ break
+ }
+ }
+ if runIx == -1 {
+ return startCommand, fmt.Errorf("\"run\" is missing in the command arguments")
+ }
+ startCommand = append(startCommand[:runIx+1], startCommand[runIx:]...)
+ startCommand[runIx+1] = fmt.Sprintf("--name=%s-%%i", info.ServiceName)
+ default:
+ // append the identity specifier (%i) to the end of the --name value
+ startCommand[nameIx] = fmt.Sprintf("%s-%%i", startCommand[nameIx])
+ }
+ return startCommand, nil
+}
+
// executeContainerTemplate executes the container template on the specified
// containerInfo. Note that the containerInfo is also post processed and
// completed, which allows for an easier unit testing.
@@ -273,7 +315,6 @@ func executeContainerTemplate(info *containerInfo, options entities.GenerateSyst
"--rm",
)
remainingCmd := info.CreateCommand[index:]
-
// Presence check for certain flags/options.
fs := pflag.NewFlagSet("args", pflag.ContinueOnError)
fs.ParseErrorsWhitelist.UnknownFlags = true
@@ -389,6 +430,13 @@ func executeContainerTemplate(info *containerInfo, options entities.GenerateSyst
startCommand = append(startCommand, remainingCmd...)
startCommand = escapeSystemdArguments(startCommand)
+ if options.TemplateUnitFile {
+ info.IdentifySpecifier = true
+ startCommand, err = setContainerNameForTemplate(startCommand, info)
+ if err != nil {
+ return "", err
+ }
+ }
info.ExecStart = strings.Join(startCommand, " ")
}
diff --git a/pkg/systemd/generate/containers_test.go b/pkg/systemd/generate/containers_test.go
index f46513459..eab2c2e67 100644
--- a/pkg/systemd/generate/containers_test.go
+++ b/pkg/systemd/generate/containers_test.go
@@ -1,6 +1,7 @@
package generate
import (
+ "fmt"
"testing"
"github.com/containers/podman/v3/pkg/domain/entities"
@@ -522,6 +523,32 @@ NotifyAccess=all
[Install]
WantedBy=multi-user.target default.target
`
+
+ templateGood := `# container-foo@.service
+# autogenerated by Podman CI
+
+[Unit]
+Description=Podman container-foo.service for %I
+Documentation=man:podman-generate-systemd(1)
+Wants=network-online.target
+After=network-online.target
+RequiresMountsFor=/var/run/containers/storage
+
+[Service]
+Environment=PODMAN_SYSTEMD_UNIT=%n-%i
+Restart=on-failure
+StartLimitBurst=42
+TimeoutStopSec=70
+ExecStartPre=/bin/rm -f %t/%n.ctr-id
+ExecStart=/usr/bin/podman run --name=container-foo-%i --cidfile=%t/%n.ctr-id --cgroups=no-conmon --rm --sdnotify=conmon -d awesome-image:latest
+ExecStop=/usr/bin/podman stop --ignore --cidfile=%t/%n.ctr-id
+ExecStopPost=/usr/bin/podman rm -f --ignore --cidfile=%t/%n.ctr-id
+Type=notify
+NotifyAccess=all
+
+[Install]
+WantedBy=multi-user.target default.target
+`
tests := []struct {
name string
info containerInfo
@@ -529,6 +556,7 @@ WantedBy=multi-user.target default.target
new bool
noHeader bool
wantErr bool
+ template bool
}{
{"good with id",
@@ -547,6 +575,7 @@ WantedBy=multi-user.target default.target
false,
false,
false,
+ false,
},
{"good with noHeader",
containerInfo{
@@ -564,6 +593,7 @@ WantedBy=multi-user.target default.target
false,
true,
false,
+ false,
},
{"good with name",
containerInfo{
@@ -581,6 +611,7 @@ WantedBy=multi-user.target default.target
false,
false,
false,
+ false,
},
{"good with name and bound to",
containerInfo{
@@ -599,6 +630,7 @@ WantedBy=multi-user.target default.target
false,
false,
false,
+ false,
},
{"good with name and generic",
containerInfo{
@@ -617,6 +649,7 @@ WantedBy=multi-user.target default.target
true,
false,
false,
+ false,
},
{"good with name and sdnotify",
containerInfo{
@@ -635,6 +668,7 @@ WantedBy=multi-user.target default.target
true,
false,
false,
+ false,
},
{"good with explicit short detach param",
containerInfo{
@@ -653,6 +687,7 @@ WantedBy=multi-user.target default.target
true,
false,
false,
+ false,
},
{"good with explicit short detach param and podInfo",
containerInfo{
@@ -674,6 +709,7 @@ WantedBy=multi-user.target default.target
true,
false,
false,
+ false,
},
{"good with explicit full detach param",
containerInfo{
@@ -692,6 +728,7 @@ WantedBy=multi-user.target default.target
true,
false,
false,
+ false,
},
{"good with id and no param",
containerInfo{
@@ -710,6 +747,7 @@ WantedBy=multi-user.target default.target
true,
false,
false,
+ false,
},
{"good with explicit detach=true param",
containerInfo{
@@ -728,6 +766,7 @@ WantedBy=multi-user.target default.target
true,
false,
false,
+ false,
},
{"good with explicit detach=false param",
containerInfo{
@@ -746,6 +785,7 @@ WantedBy=multi-user.target default.target
true,
false,
false,
+ false,
},
{"good with explicit detach=false param",
containerInfo{
@@ -764,6 +804,7 @@ WantedBy=multi-user.target default.target
true,
false,
false,
+ false,
},
{"good with multiple detach=false params",
containerInfo{
@@ -782,6 +823,7 @@ WantedBy=multi-user.target default.target
true,
false,
false,
+ false,
},
{"good with multiple shorthand params detach first",
containerInfo{
@@ -800,6 +842,7 @@ WantedBy=multi-user.target default.target
true,
false,
false,
+ false,
},
{"good with multiple shorthand params detach last",
containerInfo{
@@ -818,6 +861,7 @@ WantedBy=multi-user.target default.target
true,
false,
false,
+ false,
},
{"good with container create",
containerInfo{
@@ -836,6 +880,7 @@ WantedBy=multi-user.target default.target
true,
false,
false,
+ false,
},
{"good with journald log tag (see #9034)",
containerInfo{
@@ -854,6 +899,7 @@ WantedBy=multi-user.target default.target
true,
false,
false,
+ false,
},
{"good with special chars",
containerInfo{
@@ -872,6 +918,7 @@ WantedBy=multi-user.target default.target
true,
false,
false,
+ false,
},
{"good with ID files",
containerInfo{
@@ -890,6 +937,7 @@ WantedBy=multi-user.target default.target
true,
false,
false,
+ false,
},
{"good with pod ID files",
containerInfo{
@@ -911,6 +959,7 @@ WantedBy=multi-user.target default.target
true,
false,
false,
+ false,
},
{"good with environment variables",
containerInfo{
@@ -930,6 +979,7 @@ WantedBy=multi-user.target default.target
true,
false,
false,
+ false,
},
{"good with restart policy",
containerInfo{
@@ -948,14 +998,34 @@ WantedBy=multi-user.target default.target
true,
false,
false,
+ false,
+ },
+ {"good template",
+ containerInfo{
+ Executable: "/usr/bin/podman",
+ ServiceName: "container-foo",
+ ContainerNameOrID: "foo",
+ PIDFile: "/run/containers/storage/overlay-containers/639c53578af4d84b8800b4635fa4e680ee80fd67e0e6a2d4eea48d1e3230f401/userdata/conmon.pid",
+ StopTimeout: 10,
+ PodmanVersion: "CI",
+ GraphRoot: "/var/lib/containers/storage",
+ RunRoot: "/var/run/containers/storage",
+ CreateCommand: []string{"I'll get stripped", "create", "--restart", "on-failure:42", "awesome-image:latest"},
+ },
+ templateGood,
+ true,
+ false,
+ false,
+ true,
},
}
for _, tt := range tests {
test := tt
t.Run(tt.name, func(t *testing.T) {
opts := entities.GenerateSystemdOptions{
- New: test.new,
- NoHeader: test.noHeader,
+ New: test.new,
+ NoHeader: test.noHeader,
+ TemplateUnitFile: test.template,
}
test.info.RestartPolicy = define.DefaultRestartPolicy
got, err := executeContainerTemplate(&test.info, opts)
@@ -967,3 +1037,48 @@ WantedBy=multi-user.target default.target
})
}
}
+
+func TestSetContainerNameForTemplate(t *testing.T) {
+ tt := []struct {
+ name string
+ startCommand []string
+ info *containerInfo
+ expected []string
+ err error
+ }{
+ {
+ name: "no name argument is set",
+ startCommand: []string{"/usr/bin/podman", "run", "busybox", "top"},
+ info: &containerInfo{ServiceName: "container-122"},
+ expected: []string{"/usr/bin/podman", "run", "--name=container-122-%i", "busybox", "top"},
+ err: nil,
+ },
+ {
+ name: "--name=value is used in arguments",
+ startCommand: []string{"/usr/bin/podman", "run", "--name=lovely_james", "busybox", "top"},
+ info: &containerInfo{},
+ expected: []string{"/usr/bin/podman", "run", "--name=lovely_james-%i", "busybox", "top"},
+ err: nil,
+ },
+ {
+ name: "--name value is used in arguments",
+ startCommand: []string{"/usr/bin/podman", "run", "--name", "lovely_james", "busybox", "top"},
+ info: &containerInfo{},
+ expected: []string{"/usr/bin/podman", "run", "--name", "lovely_james-%i", "busybox", "top"},
+ err: nil,
+ },
+ {
+ name: "--name value is used in arguments",
+ startCommand: []string{"/usr/bin/podman", "create", "busybox", "top"},
+ info: &containerInfo{},
+ expected: []string{"/usr/bin/podman", "create", "busybox", "top"},
+ err: fmt.Errorf("\"run\" is missing in the command arguments"),
+ },
+ }
+
+ for _, te := range tt {
+ res, err := setContainerNameForTemplate(te.startCommand, te.info)
+ assert.Equal(t, te.err, err)
+ assert.Equal(t, te.expected, res)
+ }
+}
diff --git a/pkg/systemd/generate/pods.go b/pkg/systemd/generate/pods.go
index e755b8eea..38f7e8e3e 100644
--- a/pkg/systemd/generate/pods.go
+++ b/pkg/systemd/generate/pods.go
@@ -79,6 +79,8 @@ type podInfo struct {
// Location of the RunRoot for the pod. Required for ensuring the tmpfs
// or volume exists and is mounted when coming online at boot.
RunRoot string
+ // Add %i and %I to description and execute parts - this should not be used
+ IdentifySpecifier bool
}
const podTemplate = headerTemplate + `Requires={{{{- range $index, $value := .RequiredServices -}}}}{{{{if $index}}}} {{{{end}}}}{{{{ $value }}}}.service{{{{end}}}}
@@ -108,6 +110,9 @@ WantedBy=multi-user.target default.target
// Based on the options, the return value might be the content of all units or
// the files they been written to.
func PodUnits(pod *libpod.Pod, options entities.GenerateSystemdOptions) (map[string]string, error) {
+ if options.TemplateUnitFile {
+ return nil, errors.New("--template is not supported for pods")
+ }
// Error out if the pod has no infra container, which we require to be the
// main service.
if !pod.HasInfraContainer() {