summaryrefslogtreecommitdiff
path: root/pkg
diff options
context:
space:
mode:
Diffstat (limited to 'pkg')
-rw-r--r--pkg/api/handlers/libpod/generate.go45
-rw-r--r--pkg/api/handlers/libpod/images.go12
-rw-r--r--pkg/api/handlers/libpod/pods.go30
-rw-r--r--pkg/api/server/register_generate.go62
-rw-r--r--pkg/api/server/register_images.go10
-rw-r--r--pkg/api/server/register_volumes.go38
-rw-r--r--pkg/api/tags.yaml2
-rw-r--r--pkg/bindings/generate/generate.go27
-rw-r--r--pkg/bindings/images/images.go1
-rw-r--r--pkg/bindings/test/containers_test.go11
-rw-r--r--pkg/domain/entities/generate.go7
-rw-r--r--pkg/domain/entities/images.go2
-rw-r--r--pkg/domain/infra/abi/generate.go8
-rw-r--r--pkg/domain/infra/abi/images.go1
-rw-r--r--pkg/domain/infra/abi/play.go21
-rw-r--r--pkg/domain/infra/tunnel/generate.go3
-rw-r--r--pkg/spec/createconfig.go10
-rw-r--r--pkg/specgen/generate/config_linux.go2
-rw-r--r--pkg/specgen/generate/container.go40
-rw-r--r--pkg/specgen/specgen.go7
-rw-r--r--pkg/systemd/generate/containers.go30
-rw-r--r--pkg/systemd/generate/containers_test.go27
-rw-r--r--pkg/systemd/generate/pods.go49
-rw-r--r--pkg/systemd/generate/pods_test.go9
-rw-r--r--pkg/util/utils_supported.go3
25 files changed, 328 insertions, 129 deletions
diff --git a/pkg/api/handlers/libpod/generate.go b/pkg/api/handlers/libpod/generate.go
index 966874a2b..33bb75391 100644
--- a/pkg/api/handlers/libpod/generate.go
+++ b/pkg/api/handlers/libpod/generate.go
@@ -7,10 +7,55 @@ import (
"github.com/containers/podman/v2/pkg/api/handlers/utils"
"github.com/containers/podman/v2/pkg/domain/entities"
"github.com/containers/podman/v2/pkg/domain/infra/abi"
+ "github.com/containers/podman/v2/pkg/util"
"github.com/gorilla/schema"
"github.com/pkg/errors"
)
+func GenerateSystemd(w http.ResponseWriter, r *http.Request) {
+ runtime := r.Context().Value("runtime").(*libpod.Runtime)
+ decoder := r.Context().Value("decoder").(*schema.Decoder)
+ query := struct {
+ Name bool `schema:"useName"`
+ New bool `schema:"new"`
+ RestartPolicy string `schema:"restartPolicy"`
+ StopTimeout uint `schema:"stopTimeout"`
+ ContainerPrefix string `schema:"containerPrefix"`
+ PodPrefix string `schema:"podPrefix"`
+ Separator string `schema:"separator"`
+ }{
+ RestartPolicy: "on-failure",
+ StopTimeout: util.DefaultContainerConfig().Engine.StopTimeout,
+ ContainerPrefix: "container",
+ PodPrefix: "pod",
+ Separator: "-",
+ }
+
+ if err := decoder.Decode(&query, r.URL.Query()); err != nil {
+ utils.Error(w, http.StatusText(http.StatusBadRequest), http.StatusBadRequest,
+ errors.Wrapf(err, "failed to parse parameters for %s", r.URL.String()))
+ return
+ }
+
+ containerEngine := abi.ContainerEngine{Libpod: runtime}
+ options := entities.GenerateSystemdOptions{
+ Name: query.Name,
+ New: query.New,
+ 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)
+ if err != nil {
+ utils.Error(w, "Something went wrong.", http.StatusInternalServerError, errors.Wrap(err, "error generating systemd units"))
+ return
+ }
+
+ utils.WriteResponse(w, http.StatusOK, report.Units)
+}
+
func GenerateKube(w http.ResponseWriter, r *http.Request) {
runtime := r.Context().Value("runtime").(*libpod.Runtime)
decoder := r.Context().Value("decoder").(*schema.Decoder)
diff --git a/pkg/api/handlers/libpod/images.go b/pkg/api/handlers/libpod/images.go
index 51013acf1..8d3fc4e00 100644
--- a/pkg/api/handlers/libpod/images.go
+++ b/pkg/api/handlers/libpod/images.go
@@ -338,11 +338,12 @@ func ImagesPull(w http.ResponseWriter, r *http.Request) {
runtime := r.Context().Value("runtime").(*libpod.Runtime)
decoder := r.Context().Value("decoder").(*schema.Decoder)
query := struct {
- Reference string `schema:"reference"`
- OverrideOS string `schema:"overrideOS"`
- OverrideArch string `schema:"overrideArch"`
- TLSVerify bool `schema:"tlsVerify"`
- AllTags bool `schema:"allTags"`
+ Reference string `schema:"reference"`
+ OverrideOS string `schema:"overrideOS"`
+ OverrideArch string `schema:"overrideArch"`
+ OverrideVariant string `schema:"overrideVariant"`
+ TLSVerify bool `schema:"tlsVerify"`
+ AllTags bool `schema:"allTags"`
}{
TLSVerify: true,
}
@@ -393,6 +394,7 @@ func ImagesPull(w http.ResponseWriter, r *http.Request) {
DockerRegistryCreds: authConf,
OSChoice: query.OverrideOS,
ArchitectureChoice: query.OverrideArch,
+ VariantChoice: query.OverrideVariant,
}
if _, found := r.URL.Query()["tlsVerify"]; found {
dockerRegistryOptions.DockerInsecureSkipTLSVerify = types.NewOptionalBool(!query.TLSVerify)
diff --git a/pkg/api/handlers/libpod/pods.go b/pkg/api/handlers/libpod/pods.go
index 6e704fe65..8f8292567 100644
--- a/pkg/api/handlers/libpod/pods.go
+++ b/pkg/api/handlers/libpod/pods.go
@@ -135,8 +135,8 @@ func PodStop(w http.ResponseWriter, r *http.Request) {
}
}
var errs []error //nolint
- for _, err := range responses {
- errs = append(errs, err)
+ for id, err := range responses {
+ errs = append(errs, errors.Wrapf(err, "error stopping container %s", id))
}
report := entities.PodStopReport{
Errs: errs,
@@ -164,12 +164,12 @@ func PodStart(w http.ResponseWriter, r *http.Request) {
return
}
responses, err := pod.Start(r.Context())
- if err != nil {
+ if err != nil && errors.Cause(err) != define.ErrPodPartialFail {
utils.Error(w, "Something went wrong", http.StatusInternalServerError, err)
return
}
- for _, err := range responses {
- errs = append(errs, err)
+ for id, err := range responses {
+ errs = append(errs, errors.Wrapf(err, "error starting container %s", id))
}
report := entities.PodStartReport{
Errs: errs,
@@ -220,12 +220,12 @@ func PodRestart(w http.ResponseWriter, r *http.Request) {
return
}
responses, err := pod.Restart(r.Context())
- if err != nil {
+ if err != nil && errors.Cause(err) != define.ErrPodPartialFail {
utils.Error(w, "Something went wrong", http.StatusInternalServerError, err)
return
}
- for _, err := range responses {
- errs = append(errs, err)
+ for id, err := range responses {
+ errs = append(errs, errors.Wrapf(err, "error restarting container %s", id))
}
report := entities.PodRestartReport{
Errs: errs,
@@ -271,12 +271,12 @@ func PodPause(w http.ResponseWriter, r *http.Request) {
return
}
responses, err := pod.Pause()
- if err != nil {
+ if err != nil && errors.Cause(err) != define.ErrPodPartialFail {
utils.Error(w, "Something went wrong", http.StatusInternalServerError, err)
return
}
- for _, v := range responses {
- errs = append(errs, v)
+ for id, v := range responses {
+ errs = append(errs, errors.Wrapf(v, "error pausing container %s", id))
}
report := entities.PodPauseReport{
Errs: errs,
@@ -295,12 +295,12 @@ func PodUnpause(w http.ResponseWriter, r *http.Request) {
return
}
responses, err := pod.Unpause()
- if err != nil {
+ if err != nil && errors.Cause(err) != define.ErrPodPartialFail {
utils.Error(w, "failed to pause pod", http.StatusInternalServerError, err)
return
}
- for _, v := range responses {
- errs = append(errs, v)
+ for id, v := range responses {
+ errs = append(errs, errors.Wrapf(v, "error unpausing container %s", id))
}
report := entities.PodUnpauseReport{
Errs: errs,
@@ -403,7 +403,7 @@ func PodKill(w http.ResponseWriter, r *http.Request) {
}
responses, err := pod.Kill(uint(sig))
- if err != nil {
+ if err != nil && errors.Cause(err) != define.ErrPodPartialFail {
utils.Error(w, "failed to kill pod", http.StatusInternalServerError, err)
return
}
diff --git a/pkg/api/server/register_generate.go b/pkg/api/server/register_generate.go
index 7db8ee387..60e5b03f7 100644
--- a/pkg/api/server/register_generate.go
+++ b/pkg/api/server/register_generate.go
@@ -8,6 +8,68 @@ import (
)
func (s *APIServer) registerGenerateHandlers(r *mux.Router) error {
+ // swagger:operation GET /libpod/generate/{name:.*}/systemd libpod libpodGenerateSystemd
+ // ---
+ // tags:
+ // - containers
+ // - pods
+ // summary: Generate Systemd Units
+ // description: Generate Systemd Units based on a pod or container.
+ // parameters:
+ // - in: path
+ // name: name:.*
+ // type: string
+ // required: true
+ // description: Name or ID of the container or pod.
+ // - in: query
+ // name: useName
+ // type: boolean
+ // default: false
+ // description: Use container/pod names instead of IDs.
+ // - in: query
+ // name: new
+ // type: boolean
+ // default: false
+ // description: Create a new container instead of starting an existing one.
+ // - in: query
+ // name: time
+ // type: integer
+ // default: 10
+ // description: Stop timeout override.
+ // - in: query
+ // name: restartPolicy
+ // default: on-failure
+ // type: string
+ // enum: ["no", on-success, on-failure, on-abnormal, on-watchdog, on-abort, always]
+ // description: Systemd restart-policy.
+ // - in: query
+ // name: containerPrefix
+ // type: string
+ // default: container
+ // description: Systemd unit name prefix for containers.
+ // - in: query
+ // name: podPrefix
+ // type: string
+ // default: pod
+ // description: Systemd unit name prefix for pods.
+ // - in: query
+ // name: separator
+ // type: string
+ // default: "-"
+ // description: Systemd unit name separator between name/id and prefix.
+ // produces:
+ // - application/json
+ // responses:
+ // 200:
+ // description: no error
+ // schema:
+ // type: object
+ // additionalProperties:
+ // type: string
+ // 500:
+ // $ref: "#/responses/InternalError"
+ r.HandleFunc(VersionedPath("/libpod/generate/{name:.*}/systemd"), s.APIHandler(libpod.GenerateSystemd)).Methods(http.MethodGet)
+
// swagger:operation GET /libpod/generate/{name:.*}/kube libpod libpodGenerateKube
// ---
// tags:
diff --git a/pkg/api/server/register_images.go b/pkg/api/server/register_images.go
index cb4ce4fe7..64258a073 100644
--- a/pkg/api/server/register_images.go
+++ b/pkg/api/server/register_images.go
@@ -625,7 +625,7 @@ func (s *APIServer) registerImagesHandlers(r *mux.Router) error {
// swagger:operation POST /libpod/images/{name:.*}/push libpod libpodPushImage
// ---
// tags:
- // - images (libpod)
+ // - images
// summary: Push Image
// description: Push an image to a container registry
// parameters:
@@ -905,12 +905,16 @@ func (s *APIServer) registerImagesHandlers(r *mux.Router) error {
// description: "username:password for the registry"
// type: string
// - in: query
+ // name: overrideArch
+ // description: Pull image for the specified architecture.
+ // type: string
+ // - in: query
// name: overrideOS
// description: Pull image for the specified operating system.
// type: string
// - in: query
- // name: overrideArch
- // description: Pull image for the specified architecture.
+ // name: overrideVariant
+ // description: Pull image for the specified variant.
// type: string
// - in: query
// name: tlsVerify
diff --git a/pkg/api/server/register_volumes.go b/pkg/api/server/register_volumes.go
index 8f7848ed4..22488b158 100644
--- a/pkg/api/server/register_volumes.go
+++ b/pkg/api/server/register_volumes.go
@@ -9,8 +9,10 @@ import (
)
func (s *APIServer) registerVolumeHandlers(r *mux.Router) error {
- // swagger:operation POST /libpod/volumes/create volumes libpodCreateVolume
+ // swagger:operation POST /libpod/volumes/create libpod libpodCreateVolume
// ---
+ // tags:
+ // - volumes
// summary: Create a volume
// parameters:
// - in: body
@@ -26,8 +28,10 @@ func (s *APIServer) registerVolumeHandlers(r *mux.Router) error {
// '500':
// "$ref": "#/responses/InternalError"
r.Handle(VersionedPath("/libpod/volumes/create"), s.APIHandler(libpod.CreateVolume)).Methods(http.MethodPost)
- // swagger:operation GET /libpod/volumes/json volumes libpodListVolumes
+ // swagger:operation GET /libpod/volumes/json libpod libpodListVolumes
// ---
+ // tags:
+ // - volumes
// summary: List volumes
// description: Returns a list of volumes
// produces:
@@ -48,8 +52,10 @@ func (s *APIServer) registerVolumeHandlers(r *mux.Router) error {
// '500':
// "$ref": "#/responses/InternalError"
r.Handle(VersionedPath("/libpod/volumes/json"), s.APIHandler(libpod.ListVolumes)).Methods(http.MethodGet)
- // swagger:operation POST /libpod/volumes/prune volumes libpodPruneVolumes
+ // swagger:operation POST /libpod/volumes/prune libpod libpodPruneVolumes
// ---
+ // tags:
+ // - volumes
// summary: Prune volumes
// produces:
// - application/json
@@ -59,8 +65,10 @@ func (s *APIServer) registerVolumeHandlers(r *mux.Router) error {
// '500':
// "$ref": "#/responses/InternalError"
r.Handle(VersionedPath("/libpod/volumes/prune"), s.APIHandler(libpod.PruneVolumes)).Methods(http.MethodPost)
- // swagger:operation GET /libpod/volumes/{name}/json volumes libpodInspectVolume
+ // swagger:operation GET /libpod/volumes/{name}/json libpod libpodInspectVolume
// ---
+ // tags:
+ // - volumes
// summary: Inspect volume
// parameters:
// - in: path
@@ -78,8 +86,10 @@ func (s *APIServer) registerVolumeHandlers(r *mux.Router) error {
// '500':
// "$ref": "#/responses/InternalError"
r.Handle(VersionedPath("/libpod/volumes/{name}/json"), s.APIHandler(libpod.InspectVolume)).Methods(http.MethodGet)
- // swagger:operation DELETE /libpod/volumes/{name} volumes libpodRemoveVolume
+ // swagger:operation DELETE /libpod/volumes/{name} libpod libpodRemoveVolume
// ---
+ // tags:
+ // - volumes
// summary: Remove volume
// parameters:
// - in: path
@@ -110,6 +120,8 @@ func (s *APIServer) registerVolumeHandlers(r *mux.Router) error {
// swagger:operation GET /volumes compat listVolumes
// ---
+ // tags:
+ // - volumes (compat)
// summary: List volumes
// description: Returns a list of volume
// produces:
@@ -134,8 +146,10 @@ func (s *APIServer) registerVolumeHandlers(r *mux.Router) error {
r.Handle(VersionedPath("/volumes"), s.APIHandler(compat.ListVolumes)).Methods(http.MethodGet)
r.Handle("/volumes", s.APIHandler(compat.ListVolumes)).Methods(http.MethodGet)
- // swagger:operation POST /volumes/create volumes createVolume
+ // swagger:operation POST /volumes/create compat createVolume
// ---
+ // tags:
+ // - volumes (compat)
// summary: Create a volume
// parameters:
// - in: body
@@ -153,8 +167,10 @@ func (s *APIServer) registerVolumeHandlers(r *mux.Router) error {
r.Handle(VersionedPath("/volumes/create"), s.APIHandler(compat.CreateVolume)).Methods(http.MethodPost)
r.Handle("/volumes/create", s.APIHandler(compat.CreateVolume)).Methods(http.MethodPost)
- // swagger:operation GET /volumes/{name} volumes inspectVolume
+ // swagger:operation GET /volumes/{name} compat inspectVolume
// ---
+ // tags:
+ // - volumes (compat)
// summary: Inspect volume
// parameters:
// - in: path
@@ -174,8 +190,10 @@ func (s *APIServer) registerVolumeHandlers(r *mux.Router) error {
r.Handle(VersionedPath("/volumes/{name}"), s.APIHandler(compat.InspectVolume)).Methods(http.MethodGet)
r.Handle("/volumes/{name}", s.APIHandler(compat.InspectVolume)).Methods(http.MethodGet)
- // swagger:operation DELETE /volumes/{name} volumes removeVolume
+ // swagger:operation DELETE /volumes/{name} compat removeVolume
// ---
+ // tags:
+ // - volumes (compat)
// summary: Remove volume
// parameters:
// - in: path
@@ -204,8 +222,10 @@ func (s *APIServer) registerVolumeHandlers(r *mux.Router) error {
r.Handle(VersionedPath("/volumes/{name}"), s.APIHandler(compat.RemoveVolume)).Methods(http.MethodDelete)
r.Handle("/volumes/{name}", s.APIHandler(compat.RemoveVolume)).Methods(http.MethodDelete)
- // swagger:operation POST /volumes/prune volumes pruneVolumes
+ // swagger:operation POST /volumes/prune compat pruneVolumes
// ---
+ // tags:
+ // - volumes (compat)
// summary: Prune volumes
// produces:
// - application/json
diff --git a/pkg/api/tags.yaml b/pkg/api/tags.yaml
index f86f8dbea..0cfb3f440 100644
--- a/pkg/api/tags.yaml
+++ b/pkg/api/tags.yaml
@@ -23,5 +23,7 @@ tags:
description: Actions related to images for the compatibility endpoints
- name: networks (compat)
description: Actions related to compatibility networks
+ - name: volumes (compat)
+ description: Actions related to volumes for the compatibility endpoints
- name: system (compat)
description: Actions related to Podman and compatibility engines
diff --git a/pkg/bindings/generate/generate.go b/pkg/bindings/generate/generate.go
index b02221765..dde1cc29c 100644
--- a/pkg/bindings/generate/generate.go
+++ b/pkg/bindings/generate/generate.go
@@ -10,6 +10,33 @@ import (
"github.com/containers/podman/v2/pkg/domain/entities"
)
+func Systemd(ctx context.Context, nameOrID string, options entities.GenerateSystemdOptions) (*entities.GenerateSystemdReport, error) {
+ conn, err := bindings.GetClient(ctx)
+ if err != nil {
+ return nil, err
+ }
+ params := url.Values{}
+
+ params.Set("useName", strconv.FormatBool(options.Name))
+ params.Set("new", strconv.FormatBool(options.New))
+ if options.RestartPolicy != "" {
+ params.Set("restartPolicy", options.RestartPolicy)
+ }
+ if options.StopTimeout != nil {
+ params.Set("stopTimeout", strconv.FormatUint(uint64(*options.StopTimeout), 10))
+ }
+ params.Set("containerPrefix", options.ContainerPrefix)
+ params.Set("podPrefix", options.PodPrefix)
+ params.Set("separator", options.Separator)
+
+ response, err := conn.DoRequest(nil, http.MethodGet, "/generate/%s/systemd", params, nil, nameOrID)
+ if err != nil {
+ return nil, err
+ }
+ report := &entities.GenerateSystemdReport{}
+ return report, response.Process(&report.Units)
+}
+
func Kube(ctx context.Context, nameOrID string, options entities.GenerateKubeOptions) (*entities.GenerateKubeReport, error) {
conn, err := bindings.GetClient(ctx)
if err != nil {
diff --git a/pkg/bindings/images/images.go b/pkg/bindings/images/images.go
index 12d1a9ce9..9f6e78b79 100644
--- a/pkg/bindings/images/images.go
+++ b/pkg/bindings/images/images.go
@@ -365,6 +365,7 @@ func Pull(ctx context.Context, rawImage string, options entities.ImagePullOption
params.Set("reference", rawImage)
params.Set("overrideArch", options.OverrideArch)
params.Set("overrideOS", options.OverrideOS)
+ params.Set("overrideVariant", options.OverrideVariant)
if options.SkipTLSVerify != types.OptionalBoolUndefined {
// Note: we have to verify if skipped is false.
verifyTLS := bool(options.SkipTLSVerify == types.OptionalBoolFalse)
diff --git a/pkg/bindings/test/containers_test.go b/pkg/bindings/test/containers_test.go
index db5be4909..bf2ceab2a 100644
--- a/pkg/bindings/test/containers_test.go
+++ b/pkg/bindings/test/containers_test.go
@@ -2,7 +2,6 @@ package test_bindings
import (
"net/http"
- "strconv"
"strings"
"time"
@@ -10,7 +9,6 @@ import (
"github.com/containers/podman/v2/pkg/bindings"
"github.com/containers/podman/v2/pkg/bindings/containers"
"github.com/containers/podman/v2/pkg/specgen"
- "github.com/containers/podman/v2/test/utils"
. "github.com/onsi/ginkgo"
. "github.com/onsi/gomega"
"github.com/onsi/gomega/gexec"
@@ -182,14 +180,6 @@ var _ = Describe("Podman containers ", func() {
})
It("podman remove a paused container by id with force", func() {
- // FIXME: Skip on F31 and later
- host := utils.GetHostDistributionInfo()
- osVer, err := strconv.Atoi(host.Version)
- Expect(err).To(BeNil())
- if host.Distribution == "fedora" && osVer >= 31 {
- Skip("FIXME: https://github.com/containers/podman/issues/5325")
- }
-
// Removing a paused container with force should work
var name = "top"
cid, err := bt.RunTopContainer(&name, bindings.PFalse, nil)
@@ -280,7 +270,6 @@ var _ = Describe("Podman containers ", func() {
})
It("podman wait to pause|unpause condition", func() {
- Skip("FIXME: https://github.com/containers/podman/issues/6518")
var (
name = "top"
exitCode int32 = -1
diff --git a/pkg/domain/entities/generate.go b/pkg/domain/entities/generate.go
index a8ad13705..4a0d7537e 100644
--- a/pkg/domain/entities/generate.go
+++ b/pkg/domain/entities/generate.go
@@ -4,8 +4,6 @@ import "io"
// GenerateSystemdOptions control the generation of systemd unit files.
type GenerateSystemdOptions struct {
- // Files - generate files instead of printing to stdout.
- Files bool
// Name - use container/pod name instead of its ID.
Name bool
// New - create a new container instead of starting a new one.
@@ -24,9 +22,8 @@ type GenerateSystemdOptions struct {
// GenerateSystemdReport
type GenerateSystemdReport struct {
- // Output of the generate process. Either the generated files or their
- // entire content.
- Output string
+ // Units of the generate process. key = unit name -> value = unit content
+ Units map[string]string
}
// GenerateKubeOptions control the generation of Kubernetes YAML files.
diff --git a/pkg/domain/entities/images.go b/pkg/domain/entities/images.go
index cb970b09a..3a12a4e22 100644
--- a/pkg/domain/entities/images.go
+++ b/pkg/domain/entities/images.go
@@ -137,6 +137,8 @@ type ImagePullOptions struct {
// OverrideOS will overwrite the local operating system (OS) for image
// pulls.
OverrideOS string
+ // OverrideVariant will overwrite the local variant for image pulls.
+ OverrideVariant string
// Quiet can be specified to suppress pull progress when pulling. Ignored
// for remote calls.
Quiet bool
diff --git a/pkg/domain/infra/abi/generate.go b/pkg/domain/infra/abi/generate.go
index 0b73ddd7e..79bf2291e 100644
--- a/pkg/domain/infra/abi/generate.go
+++ b/pkg/domain/infra/abi/generate.go
@@ -19,11 +19,11 @@ func (ic *ContainerEngine) GenerateSystemd(ctx context.Context, nameOrID string,
ctr, ctrErr := ic.Libpod.LookupContainer(nameOrID)
if ctrErr == nil {
// Generate the unit for the container.
- s, err := generate.ContainerUnit(ctr, options)
+ name, content, err := generate.ContainerUnit(ctr, options)
if err != nil {
return nil, err
}
- return &entities.GenerateSystemdReport{Output: s}, nil
+ return &entities.GenerateSystemdReport{Units: map[string]string{name: content}}, nil
}
// If it's not a container, we either have a pod or garbage.
@@ -34,11 +34,11 @@ func (ic *ContainerEngine) GenerateSystemd(ctx context.Context, nameOrID string,
}
// Generate the units for the pod and all its containers.
- s, err := generate.PodUnits(pod, options)
+ units, err := generate.PodUnits(pod, options)
if err != nil {
return nil, err
}
- return &entities.GenerateSystemdReport{Output: s}, nil
+ return &entities.GenerateSystemdReport{Units: units}, nil
}
func (ic *ContainerEngine) GenerateKube(ctx context.Context, nameOrID string, options entities.GenerateKubeOptions) (*entities.GenerateKubeReport, error) {
diff --git a/pkg/domain/infra/abi/images.go b/pkg/domain/infra/abi/images.go
index 70d740bb5..6b94ca9c0 100644
--- a/pkg/domain/infra/abi/images.go
+++ b/pkg/domain/infra/abi/images.go
@@ -251,6 +251,7 @@ func (ir *ImageEngine) Pull(ctx context.Context, rawImage string, options entiti
DockerCertPath: options.CertDir,
OSChoice: options.OverrideOS,
ArchitectureChoice: options.OverrideArch,
+ VariantChoice: options.OverrideVariant,
DockerInsecureSkipTLSVerify: options.SkipTLSVerify,
}
diff --git a/pkg/domain/infra/abi/play.go b/pkg/domain/infra/abi/play.go
index 4ebc37cda..31ad51672 100644
--- a/pkg/domain/infra/abi/play.go
+++ b/pkg/domain/infra/abi/play.go
@@ -144,6 +144,16 @@ func (ic *ContainerEngine) playKubePod(ctx context.Context, podName string, podY
podOptions = append(podOptions, libpod.WithPodHostNetwork())
}
+ if podYAML.Spec.HostAliases != nil {
+ hosts := make([]string, 0, len(podYAML.Spec.HostAliases))
+ for _, hostAlias := range podYAML.Spec.HostAliases {
+ for _, host := range hostAlias.Hostnames {
+ hosts = append(hosts, host+":"+hostAlias.IP)
+ }
+ }
+ podOptions = append(podOptions, libpod.WithPodHosts(hosts))
+ }
+
nsOptions, err := generate.GetNamespaceOptions(strings.Split(createconfig.DefaultKernelNamespaces, ","))
if err != nil {
return nil, err
@@ -250,13 +260,22 @@ func (ic *ContainerEngine) playKubePod(ctx context.Context, podName string, podY
if err := libpod.LabelVolumePath(hostPath.Path); err != nil {
return nil, errors.Wrapf(err, "Error giving %s a label", hostPath.Path)
}
+ case v1.HostPathSocket:
+ st, err := os.Stat(hostPath.Path)
+ if err != nil {
+ return nil, errors.Wrapf(err, "Error checking HostPathSocket")
+ }
+ if st.Mode()&os.ModeSocket != os.ModeSocket {
+ return nil, errors.Errorf("Error checking HostPathSocket: path %s is not a socket", hostPath.Path)
+ }
+
case v1.HostPathDirectory:
case v1.HostPathFile:
case v1.HostPathUnset:
// do nothing here because we will verify the path exists in validateVolumeHostDir
break
default:
- return nil, errors.Errorf("Directories are the only supported HostPath type")
+ return nil, errors.Errorf("Invalid HostPath type %v", hostPath.Type)
}
}
diff --git a/pkg/domain/infra/tunnel/generate.go b/pkg/domain/infra/tunnel/generate.go
index c7d5cd9e2..966f707b1 100644
--- a/pkg/domain/infra/tunnel/generate.go
+++ b/pkg/domain/infra/tunnel/generate.go
@@ -5,11 +5,10 @@ import (
"github.com/containers/podman/v2/pkg/bindings/generate"
"github.com/containers/podman/v2/pkg/domain/entities"
- "github.com/pkg/errors"
)
func (ic *ContainerEngine) GenerateSystemd(ctx context.Context, nameOrID string, options entities.GenerateSystemdOptions) (*entities.GenerateSystemdReport, error) {
- return nil, errors.New("not implemented for tunnel")
+ return generate.Systemd(ic.ClientCxt, nameOrID, options)
}
func (ic *ContainerEngine) GenerateKube(ctx context.Context, nameOrID string, options entities.GenerateKubeOptions) (*entities.GenerateKubeReport, error) {
diff --git a/pkg/spec/createconfig.go b/pkg/spec/createconfig.go
index e0c875fe9..4887e9262 100644
--- a/pkg/spec/createconfig.go
+++ b/pkg/spec/createconfig.go
@@ -267,6 +267,16 @@ func (c *CreateConfig) getContainerCreateOptions(runtime *libpod.Runtime, pod *l
options = append(options, runtime.WithPod(pod))
}
+ // handle some spec from the InfraContainer when it's a pod
+ if pod != nil && pod.HasInfraContainer() {
+ InfraCtr, err := pod.InfraContainer()
+ if err != nil {
+ return nil, err
+ }
+ // handle the pod.spec.hostAliases
+ options = append(options, libpod.WithHosts(InfraCtr.HostsAdd()))
+ }
+
if len(mounts) != 0 || len(namedVolumes) != 0 {
destinations := []string{}
diff --git a/pkg/specgen/generate/config_linux.go b/pkg/specgen/generate/config_linux.go
index 35508c023..1d5dcd8e7 100644
--- a/pkg/specgen/generate/config_linux.go
+++ b/pkg/specgen/generate/config_linux.go
@@ -90,7 +90,7 @@ func DevicesFromPath(g *generate.Generator, devicePath string) error {
}
st, err := os.Stat(resolvedDevicePath)
if err != nil {
- return errors.Wrapf(err, "cannot stat %s", devicePath)
+ return errors.Wrapf(err, "cannot stat device path %s", devicePath)
}
if st.IsDir() {
found := false
diff --git a/pkg/specgen/generate/container.go b/pkg/specgen/generate/container.go
index 53d160442..147ebd61b 100644
--- a/pkg/specgen/generate/container.go
+++ b/pkg/specgen/generate/container.go
@@ -2,6 +2,7 @@ package generate
import (
"context"
+ "os"
"github.com/containers/image/v5/manifest"
"github.com/containers/podman/v2/libpod"
@@ -62,14 +63,24 @@ func CompleteSpec(ctx context.Context, r *libpod.Runtime, s *specgen.SpecGenerat
if err != nil {
return nil, err
}
- // Get Default Environment
- defaultEnvs, err := envLib.ParseSlice(rtc.Containers.Env)
+ // First transform the os env into a map. We need it for the labels later in
+ // any case.
+ osEnv, err := envLib.ParseSlice(os.Environ())
if err != nil {
- return nil, errors.Wrap(err, "Env fields in containers.conf failed to parse")
+ return nil, errors.Wrap(err, "error parsing host environment variables")
}
+ // Get Default Environment from containers.conf
+ defaultEnvs, err := envLib.ParseSlice(rtc.GetDefaultEnv())
+ if err != nil {
+ return nil, errors.Wrap(err, "error parsing fields in containers.conf")
+ }
+ if defaultEnvs["containers"] == "" {
+ defaultEnvs["containers"] = "podman"
+ }
var envs map[string]string
+ // Image Environment defaults
if newImage != nil {
// Image envs from the image if they don't exist
// already, overriding the default environments
@@ -82,9 +93,30 @@ func CompleteSpec(ctx context.Context, r *libpod.Runtime, s *specgen.SpecGenerat
if err != nil {
return nil, errors.Wrap(err, "Env fields from image failed to parse")
}
+ defaultEnvs = envLib.Join(defaultEnvs, envs)
+ }
+
+ // Caller Specified defaults
+ if s.EnvHost {
+ defaultEnvs = envLib.Join(defaultEnvs, osEnv)
+ } else if s.HTTPProxy {
+ for _, envSpec := range []string{
+ "http_proxy",
+ "HTTP_PROXY",
+ "https_proxy",
+ "HTTPS_PROXY",
+ "ftp_proxy",
+ "FTP_PROXY",
+ "no_proxy",
+ "NO_PROXY",
+ } {
+ if v, ok := osEnv[envSpec]; ok {
+ defaultEnvs[envSpec] = v
+ }
+ }
}
- s.Env = envLib.Join(envLib.Join(defaultEnvs, envs), s.Env)
+ s.Env = envLib.Join(defaultEnvs, s.Env)
// Labels and Annotations
annotations := make(map[string]string)
diff --git a/pkg/specgen/specgen.go b/pkg/specgen/specgen.go
index a52225f87..cca05eddb 100644
--- a/pkg/specgen/specgen.go
+++ b/pkg/specgen/specgen.go
@@ -43,6 +43,13 @@ type ContainerBasicConfig struct {
// image's configuration.
// Optional.
Command []string `json:"command,omitempty"`
+ // EnvHost indicates that the host environment should be added to container
+ // Optional.
+ EnvHost bool `json:"env_host,omitempty"`
+ // EnvHTTPProxy indicates that the http host proxy environment variables
+ // should be added to container
+ // Optional.
+ HTTPProxy bool `json:"httpproxy,omitempty"`
// Env is a set of environment variables that will be set in the
// container.
// Optional.
diff --git a/pkg/systemd/generate/containers.go b/pkg/systemd/generate/containers.go
index 5f6376977..caf5de357 100644
--- a/pkg/systemd/generate/containers.go
+++ b/pkg/systemd/generate/containers.go
@@ -3,9 +3,7 @@ package generate
import (
"bytes"
"fmt"
- "io/ioutil"
"os"
- "path/filepath"
"sort"
"strings"
"text/template"
@@ -87,17 +85,22 @@ KillMode=none
Type=forking
[Install]
-WantedBy=multi-user.target default.target`
+WantedBy=multi-user.target default.target
+`
// ContainerUnit generates a systemd unit for the specified container. Based
// on the options, the return value might be the entire unit or a file it has
// been written to.
-func ContainerUnit(ctr *libpod.Container, options entities.GenerateSystemdOptions) (string, error) {
+func ContainerUnit(ctr *libpod.Container, options entities.GenerateSystemdOptions) (string, string, error) {
info, err := generateContainerInfo(ctr, options)
if err != nil {
- return "", err
+ return "", "", err
+ }
+ content, err := executeContainerTemplate(info, options)
+ if err != nil {
+ return "", "", err
}
- return executeContainerTemplate(info, options)
+ return info.ServiceName, content, nil
}
func generateContainerInfo(ctr *libpod.Container, options entities.GenerateSystemdOptions) (*containerInfo, error) {
@@ -288,18 +291,5 @@ func executeContainerTemplate(info *containerInfo, options entities.GenerateSyst
return "", err
}
- if !options.Files {
- return buf.String(), nil
- }
-
- buf.WriteByte('\n')
- cwd, err := os.Getwd()
- if err != nil {
- return "", errors.Wrap(err, "error getting current working directory")
- }
- path := filepath.Join(cwd, fmt.Sprintf("%s.service", info.ServiceName))
- if err := ioutil.WriteFile(path, buf.Bytes(), 0644); err != nil {
- return "", errors.Wrap(err, "error generating systemd unit")
- }
- return path, nil
+ return buf.String(), nil
}
diff --git a/pkg/systemd/generate/containers_test.go b/pkg/systemd/generate/containers_test.go
index b5c736c5a..d27062ef3 100644
--- a/pkg/systemd/generate/containers_test.go
+++ b/pkg/systemd/generate/containers_test.go
@@ -56,7 +56,8 @@ KillMode=none
Type=forking
[Install]
-WantedBy=multi-user.target default.target`
+WantedBy=multi-user.target default.target
+`
goodName := `# container-foobar.service
# autogenerated by Podman CI
@@ -78,7 +79,8 @@ KillMode=none
Type=forking
[Install]
-WantedBy=multi-user.target default.target`
+WantedBy=multi-user.target default.target
+`
goodNameBoundTo := `# container-foobar.service
# autogenerated by Podman CI
@@ -102,7 +104,8 @@ KillMode=none
Type=forking
[Install]
-WantedBy=multi-user.target default.target`
+WantedBy=multi-user.target default.target
+`
goodWithNameAndGeneric := `# jadda-jadda.service
# autogenerated by Podman CI
@@ -125,7 +128,8 @@ KillMode=none
Type=forking
[Install]
-WantedBy=multi-user.target default.target`
+WantedBy=multi-user.target default.target
+`
goodWithExplicitShortDetachParam := `# jadda-jadda.service
# autogenerated by Podman CI
@@ -148,7 +152,8 @@ KillMode=none
Type=forking
[Install]
-WantedBy=multi-user.target default.target`
+WantedBy=multi-user.target default.target
+`
goodNameNewWithPodFile := `# jadda-jadda.service
# autogenerated by Podman CI
@@ -171,7 +176,8 @@ KillMode=none
Type=forking
[Install]
-WantedBy=multi-user.target default.target`
+WantedBy=multi-user.target default.target
+`
goodNameNewDetach := `# jadda-jadda.service
# autogenerated by Podman CI
@@ -194,7 +200,8 @@ KillMode=none
Type=forking
[Install]
-WantedBy=multi-user.target default.target`
+WantedBy=multi-user.target default.target
+`
goodIDNew := `# container-639c53578af4d84b8800b4635fa4e680ee80fd67e0e6a2d4eea48d1e3230f401.service
# autogenerated by Podman CI
@@ -217,7 +224,8 @@ KillMode=none
Type=forking
[Install]
-WantedBy=multi-user.target default.target`
+WantedBy=multi-user.target default.target
+`
tests := []struct {
name string
@@ -375,8 +383,7 @@ WantedBy=multi-user.target default.target`
test := tt
t.Run(tt.name, func(t *testing.T) {
opts := entities.GenerateSystemdOptions{
- Files: false,
- New: test.new,
+ New: test.new,
}
got, err := executeContainerTemplate(&test.info, opts)
if (err != nil) != test.wantErr {
diff --git a/pkg/systemd/generate/pods.go b/pkg/systemd/generate/pods.go
index dec9587d9..c41eedd17 100644
--- a/pkg/systemd/generate/pods.go
+++ b/pkg/systemd/generate/pods.go
@@ -3,9 +3,7 @@ package generate
import (
"bytes"
"fmt"
- "io/ioutil"
"os"
- "path/filepath"
"sort"
"strings"
"text/template"
@@ -88,39 +86,40 @@ KillMode=none
Type=forking
[Install]
-WantedBy=multi-user.target default.target`
+WantedBy=multi-user.target default.target
+`
// PodUnits generates systemd units for the specified pod and its containers.
// 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) (string, error) {
+func PodUnits(pod *libpod.Pod, options entities.GenerateSystemdOptions) (map[string]string, error) {
// Error out if the pod has no infra container, which we require to be the
// main service.
if !pod.HasInfraContainer() {
- return "", errors.Errorf("error generating systemd unit files: Pod %q has no infra container", pod.Name())
+ return nil, errors.Errorf("error generating systemd unit files: Pod %q has no infra container", pod.Name())
}
podInfo, err := generatePodInfo(pod, options)
if err != nil {
- return "", err
+ return nil, err
}
infraID, err := pod.InfraContainerID()
if err != nil {
- return "", err
+ return nil, err
}
// Compute the container-dependency graph for the Pod.
containers, err := pod.AllContainers()
if err != nil {
- return "", err
+ return nil, err
}
if len(containers) == 0 {
- return "", errors.Errorf("error generating systemd unit files: Pod %q has no containers", pod.Name())
+ return nil, errors.Errorf("error generating systemd unit files: Pod %q has no containers", pod.Name())
}
graph, err := libpod.BuildContainerGraph(containers)
if err != nil {
- return "", err
+ return nil, err
}
// Traverse the dependency graph and create systemdgen.containerInfo's for
@@ -133,7 +132,7 @@ func PodUnits(pod *libpod.Pod, options entities.GenerateSystemdOptions) (string,
}
ctrInfo, err := generateContainerInfo(ctr, options)
if err != nil {
- return "", err
+ return nil, err
}
// Now add the container's dependencies and at the container as a
// required service of the infra container.
@@ -149,24 +148,23 @@ func PodUnits(pod *libpod.Pod, options entities.GenerateSystemdOptions) (string,
containerInfos = append(containerInfos, ctrInfo)
}
+ units := map[string]string{}
// Now generate the systemd service for all containers.
- builder := strings.Builder{}
out, err := executePodTemplate(podInfo, options)
if err != nil {
- return "", err
+ return nil, err
}
- builder.WriteString(out)
+ units[podInfo.ServiceName] = out
for _, info := range containerInfos {
info.pod = podInfo
- builder.WriteByte('\n')
out, err := executeContainerTemplate(info, options)
if err != nil {
- return "", err
+ return nil, err
}
- builder.WriteString(out)
+ units[info.ServiceName] = out
}
- return builder.String(), nil
+ return units, nil
}
func generatePodInfo(pod *libpod.Pod, options entities.GenerateSystemdOptions) (*podInfo, error) {
@@ -339,18 +337,5 @@ func executePodTemplate(info *podInfo, options entities.GenerateSystemdOptions)
return "", err
}
- if !options.Files {
- return buf.String(), nil
- }
-
- buf.WriteByte('\n')
- cwd, err := os.Getwd()
- if err != nil {
- return "", errors.Wrap(err, "error getting current working directory")
- }
- path := filepath.Join(cwd, fmt.Sprintf("%s.service", info.ServiceName))
- if err := ioutil.WriteFile(path, buf.Bytes(), 0644); err != nil {
- return "", errors.Wrap(err, "error generating systemd unit")
- }
- return path, nil
+ return buf.String(), nil
}
diff --git a/pkg/systemd/generate/pods_test.go b/pkg/systemd/generate/pods_test.go
index 8bf4705a7..7f1f63b7e 100644
--- a/pkg/systemd/generate/pods_test.go
+++ b/pkg/systemd/generate/pods_test.go
@@ -58,7 +58,8 @@ KillMode=none
Type=forking
[Install]
-WantedBy=multi-user.target default.target`
+WantedBy=multi-user.target default.target
+`
podGoodNamedNew := `# pod-123abc.service
# autogenerated by Podman CI
@@ -84,7 +85,8 @@ KillMode=none
Type=forking
[Install]
-WantedBy=multi-user.target default.target`
+WantedBy=multi-user.target default.target
+`
tests := []struct {
name string
@@ -130,8 +132,7 @@ WantedBy=multi-user.target default.target`
test := tt
t.Run(tt.name, func(t *testing.T) {
opts := entities.GenerateSystemdOptions{
- Files: false,
- New: test.new,
+ New: test.new,
}
got, err := executePodTemplate(&test.info, opts)
if (err != nil) != test.wantErr {
diff --git a/pkg/util/utils_supported.go b/pkg/util/utils_supported.go
index bf59240c6..d627208d8 100644
--- a/pkg/util/utils_supported.go
+++ b/pkg/util/utils_supported.go
@@ -83,9 +83,6 @@ func GetRootlessConfigHomeDir() (string, error) {
return
}
tmpDir := filepath.Join(resolvedHome, ".config")
- if err := os.MkdirAll(tmpDir, 0755); err != nil {
- logrus.Errorf("unable to make temp dir %s", tmpDir)
- }
st, err := os.Stat(tmpDir)
if err == nil && int(st.Sys().(*syscall.Stat_t).Uid) == os.Geteuid() && st.Mode().Perm() >= 0700 {
cfgHomeDir = tmpDir