summaryrefslogtreecommitdiff
path: root/pkg
diff options
context:
space:
mode:
Diffstat (limited to 'pkg')
-rw-r--r--pkg/api/handlers/compat/containers_create.go5
-rw-r--r--pkg/api/handlers/compat/containers_stats.go30
-rw-r--r--pkg/api/handlers/compat/events.go2
-rw-r--r--pkg/api/handlers/compat/images.go76
-rw-r--r--pkg/api/handlers/compat/images_push.go112
-rw-r--r--pkg/api/handlers/compat/resize.go15
-rw-r--r--pkg/api/handlers/libpod/images.go2
-rw-r--r--pkg/api/handlers/libpod/images_pull.go2
-rw-r--r--pkg/api/handlers/libpod/manifests.go2
-rw-r--r--pkg/api/handlers/libpod/swagger.go2
-rw-r--r--pkg/api/handlers/utils/images.go25
-rw-r--r--pkg/api/server/handler_api.go6
-rw-r--r--pkg/api/server/register_containers.go7
-rw-r--r--pkg/api/server/server.go21
-rw-r--r--pkg/bindings/containers/attach.go54
-rw-r--r--pkg/domain/entities/system.go7
-rw-r--r--pkg/domain/infra/abi/network.go2
-rw-r--r--pkg/machine/config.go1
-rw-r--r--pkg/machine/ignition.go17
-rw-r--r--pkg/machine/qemu/machine.go118
-rw-r--r--pkg/machine/qemu/options_darwin.go2
-rw-r--r--pkg/machine/qemu/options_darwin_amd64.go2
-rw-r--r--pkg/machine/qemu/options_linux.go10
-rw-r--r--pkg/rootless/rootless_linux.c14
-rw-r--r--pkg/systemd/generate/common.go2
-rw-r--r--pkg/systemd/generate/containers.go17
-rw-r--r--pkg/systemd/generate/containers_test.go34
-rw-r--r--pkg/systemd/generate/pods_test.go10
28 files changed, 368 insertions, 229 deletions
diff --git a/pkg/api/handlers/compat/containers_create.go b/pkg/api/handlers/compat/containers_create.go
index 8e9e1fb39..0b5cbd343 100644
--- a/pkg/api/handlers/compat/containers_create.go
+++ b/pkg/api/handlers/compat/containers_create.go
@@ -71,13 +71,12 @@ func CreateContainer(w http.ResponseWriter, r *http.Request) {
imgNameOrID := newImage.ID()
// if the img had multi names with the same sha256 ID, should use the InputName, not the ID
if len(newImage.Names()) > 1 {
- imageRef, err := utils.ParseDockerReference(resolvedName)
- if err != nil {
+ if err := utils.IsRegistryReference(resolvedName); err != nil {
utils.Error(w, http.StatusText(http.StatusBadRequest), http.StatusBadRequest, err)
return
}
// maybe the InputName has no tag, so use full name to display
- imgNameOrID = imageRef.DockerReference().String()
+ imgNameOrID = resolvedName
}
sg := specgen.NewSpecGenerator(imgNameOrID, cliOpts.RootFS)
diff --git a/pkg/api/handlers/compat/containers_stats.go b/pkg/api/handlers/compat/containers_stats.go
index 694b57bb1..851955207 100644
--- a/pkg/api/handlers/compat/containers_stats.go
+++ b/pkg/api/handlers/compat/containers_stats.go
@@ -22,7 +22,8 @@ func StatsContainer(w http.ResponseWriter, r *http.Request) {
decoder := r.Context().Value("decoder").(*schema.Decoder)
query := struct {
- Stream bool `schema:"stream"`
+ Stream bool `schema:"stream"`
+ OneShot bool `schema:"one-shot"` //added schema for one shot
}{
Stream: true,
}
@@ -30,6 +31,10 @@ func StatsContainer(w http.ResponseWriter, r *http.Request) {
utils.Error(w, "Something went wrong.", http.StatusBadRequest, errors.Wrapf(err, "failed to parse parameters for %s", r.URL.String()))
return
}
+ if query.Stream && query.OneShot { // mismatch. one-shot can only be passed with stream=false
+ utils.Error(w, "invalid combination of stream and one-shot", http.StatusBadRequest, define.ErrInvalidArg)
+ return
+ }
name := utils.GetName(r)
ctnr, err := runtime.LookupContainer(name)
@@ -56,6 +61,16 @@ func StatsContainer(w http.ResponseWriter, r *http.Request) {
return
}
+ coder := json.NewEncoder(w)
+ // Write header and content type.
+ w.WriteHeader(http.StatusOK)
+ w.Header().Add("Content-Type", "application/json")
+ if flusher, ok := w.(http.Flusher); ok {
+ flusher.Flush()
+ }
+
+ // Setup JSON encoder for streaming.
+ coder.SetEscapeHTML(true)
var preRead time.Time
var preCPUStats CPUStats
if query.Stream {
@@ -75,17 +90,6 @@ func StatsContainer(w http.ResponseWriter, r *http.Request) {
}
}
- // Write header and content type.
- w.WriteHeader(http.StatusOK)
- w.Header().Add("Content-Type", "application/json")
- if flusher, ok := w.(http.Flusher); ok {
- flusher.Flush()
- }
-
- // Setup JSON encoder for streaming.
- coder := json.NewEncoder(w)
- coder.SetEscapeHTML(true)
-
streamLabel: // A label to flatten the scope
select {
case <-r.Context().Done():
@@ -199,7 +203,7 @@ streamLabel: // A label to flatten the scope
flusher.Flush()
}
- if !query.Stream {
+ if !query.Stream || query.OneShot {
return
}
diff --git a/pkg/api/handlers/compat/events.go b/pkg/api/handlers/compat/events.go
index 405e616c5..9fbac91e0 100644
--- a/pkg/api/handlers/compat/events.go
+++ b/pkg/api/handlers/compat/events.go
@@ -75,7 +75,7 @@ func GetEvents(w http.ResponseWriter, r *http.Request) {
coder := json.NewEncoder(w)
coder.SetEscapeHTML(true)
- for stream := true; stream; stream = query.Stream {
+ for {
select {
case err := <-errorChannel:
if err != nil {
diff --git a/pkg/api/handlers/compat/images.go b/pkg/api/handlers/compat/images.go
index 3f4320efa..7b336c470 100644
--- a/pkg/api/handlers/compat/images.go
+++ b/pkg/api/handlers/compat/images.go
@@ -1,7 +1,6 @@
package compat
import (
- "context"
"encoding/json"
"fmt"
"io/ioutil"
@@ -13,12 +12,12 @@ import (
"github.com/containers/common/libimage"
"github.com/containers/common/pkg/config"
"github.com/containers/image/v5/manifest"
+ "github.com/containers/image/v5/pkg/shortnames"
"github.com/containers/image/v5/types"
"github.com/containers/podman/v3/libpod"
"github.com/containers/podman/v3/pkg/api/handlers"
"github.com/containers/podman/v3/pkg/api/handlers/utils"
"github.com/containers/podman/v3/pkg/auth"
- "github.com/containers/podman/v3/pkg/channel"
"github.com/containers/podman/v3/pkg/domain/entities"
"github.com/containers/podman/v3/pkg/domain/infra/abi"
"github.com/containers/storage"
@@ -210,6 +209,11 @@ func CreateImageFromSrc(w http.ResponseWriter, r *http.Request) {
})
}
+type pullResult struct {
+ images []*libimage.Image
+ err error
+}
+
func CreateImageFromImage(w http.ResponseWriter, r *http.Request) {
// 200 no error
// 404 repo does not exist or no read access
@@ -231,6 +235,14 @@ func CreateImageFromImage(w http.ResponseWriter, r *http.Request) {
fromImage := mergeNameAndTagOrDigest(query.FromImage, query.Tag)
+ // without this early check this function would return 200 but reported error via body stream soon after
+ // it's better to let caller know early via HTTP status code that request cannot be processed
+ _, err := shortnames.Resolve(runtime.SystemContext(), fromImage)
+ if err != nil {
+ utils.Error(w, "Something went wrong.", http.StatusBadRequest, errors.Wrap(err, "failed to resolve image name"))
+ return
+ }
+
authConf, authfile, key, err := auth.GetCredentials(r)
if err != nil {
utils.Error(w, "failed to retrieve repository credentials", http.StatusBadRequest, errors.Wrapf(err, "failed to parse %q header for %s", key, r.URL.String()))
@@ -247,26 +259,14 @@ func CreateImageFromImage(w http.ResponseWriter, r *http.Request) {
}
pullOptions.Writer = os.Stderr // allows for debugging on the server
- stderr := channel.NewWriter(make(chan []byte))
- defer stderr.Close()
-
progress := make(chan types.ProgressProperties)
+
pullOptions.Progress = progress
- var img string
- runCtx, cancel := context.WithCancel(context.Background())
+ pullResChan := make(chan pullResult)
go func() {
- defer cancel()
- pulledImages, err := runtime.LibimageRuntime().Pull(runCtx, fromImage, config.PullPolicyAlways, pullOptions)
- if err != nil {
- stderr.Write([]byte(err.Error() + "\n"))
- } else {
- if len(pulledImages) == 0 {
- utils.Error(w, "Something went wrong.", http.StatusBadRequest, errors.New("internal error: no images pulled"))
- return
- }
- img = pulledImages[0].ID()
- }
+ pulledImages, err := runtime.LibimageRuntime().Pull(r.Context(), fromImage, config.PullPolicyAlways, pullOptions)
+ pullResChan <- pullResult{images: pulledImages, err: err}
}()
flush := func() {
@@ -281,7 +281,6 @@ func CreateImageFromImage(w http.ResponseWriter, r *http.Request) {
enc := json.NewEncoder(w)
enc.SetEscapeHTML(true)
- var failed bool
loop: // break out of for/select infinite loop
for {
@@ -312,32 +311,31 @@ loop: // break out of for/select infinite loop
}
report.Id = e.Artifact.Digest.Encoded()[0:12]
if err := enc.Encode(report); err != nil {
- stderr.Write([]byte(err.Error()))
- }
- flush()
- case e := <-stderr.Chan():
- failed = true
- report.Error = string(e)
- if err := enc.Encode(report); err != nil {
logrus.Warnf("Failed to json encode error %q", err.Error())
}
flush()
- case <-runCtx.Done():
- if !failed {
- if utils.IsLibpodRequest(r) {
- report.Status = "Pull complete"
+ case pullRes := <-pullResChan:
+ err := pullRes.err
+ pulledImages := pullRes.images
+ if err != nil {
+ report.Error = err.Error()
+ } else {
+ if len(pulledImages) > 0 {
+ img := pulledImages[0].ID()
+ if utils.IsLibpodRequest(r) {
+ report.Status = "Pull complete"
+ } else {
+ report.Status = "Download complete"
+ }
+ report.Id = img[0:12]
} else {
- report.Status = "Download complete"
- }
- report.Id = img[0:12]
- if err := enc.Encode(report); err != nil {
- logrus.Warnf("Failed to json encode error %q", err.Error())
+ report.Error = "internal error: no images pulled"
}
- flush()
}
- break loop // break out of for/select infinite loop
- case <-r.Context().Done():
- // Client has closed connection
+ if err := enc.Encode(report); err != nil {
+ logrus.Warnf("Failed to json encode error %q", err.Error())
+ }
+ flush()
break loop // break out of for/select infinite loop
}
}
diff --git a/pkg/api/handlers/compat/images_push.go b/pkg/api/handlers/compat/images_push.go
index db02af445..62f8cdc77 100644
--- a/pkg/api/handlers/compat/images_push.go
+++ b/pkg/api/handlers/compat/images_push.go
@@ -1,7 +1,6 @@
package compat
import (
- "context"
"encoding/json"
"fmt"
"io/ioutil"
@@ -12,7 +11,6 @@ import (
"github.com/containers/podman/v3/libpod"
"github.com/containers/podman/v3/pkg/api/handlers/utils"
"github.com/containers/podman/v3/pkg/auth"
- "github.com/containers/podman/v3/pkg/channel"
"github.com/containers/podman/v3/pkg/domain/entities"
"github.com/containers/podman/v3/pkg/domain/infra/abi"
"github.com/containers/storage"
@@ -101,46 +99,33 @@ func PushImage(w http.ResponseWriter, r *http.Request) {
destination = imageName
}
- errorWriter := channel.NewWriter(make(chan []byte))
- defer errorWriter.Close()
-
- statusWriter := channel.NewWriter(make(chan []byte))
- defer statusWriter.Close()
-
- runCtx, cancel := context.WithCancel(context.Background())
- var failed bool
-
- go func() {
- defer cancel()
-
- statusWriter.Write([]byte(fmt.Sprintf("The push refers to repository [%s]", imageName)))
-
- err := imageEngine.Push(runCtx, imageName, destination, options)
- if err != nil {
- if errors.Cause(err) != storage.ErrImageUnknown {
- errorWriter.Write([]byte("An image does not exist locally with the tag: " + imageName))
- } else {
- errorWriter.Write([]byte(err.Error()))
- }
- }
- }()
-
- flush := func() {
- if flusher, ok := w.(http.Flusher); ok {
- flusher.Flush()
- }
+ flush := func() {}
+ if flusher, ok := w.(http.Flusher); ok {
+ flush = flusher.Flush
}
w.WriteHeader(http.StatusOK)
w.Header().Add("Content-Type", "application/json")
flush()
+ var report jsonmessage.JSONMessage
enc := json.NewEncoder(w)
enc.SetEscapeHTML(true)
+ report.Status = fmt.Sprintf("The push refers to repository [%s]", imageName)
+ if err := enc.Encode(report); err != nil {
+ logrus.Warnf("Failed to json encode error %q", err.Error())
+ }
+ flush()
+
+ pushErrChan := make(chan error)
+ go func() {
+ pushErrChan <- imageEngine.Push(r.Context(), imageName, destination, options)
+ }()
+
loop: // break out of for/select infinite loop
for {
- var report jsonmessage.JSONMessage
+ report = jsonmessage.JSONMessage{}
select {
case e := <-options.Progress:
@@ -160,43 +145,50 @@ loop: // break out of for/select infinite loop
}
report.ID = e.Artifact.Digest.Encoded()[0:12]
if err := enc.Encode(report); err != nil {
- errorWriter.Write([]byte(err.Error()))
+ logrus.Warnf("Failed to json encode error %q", err.Error())
}
flush()
- case e := <-statusWriter.Chan():
- report.Status = string(e)
- if err := enc.Encode(report); err != nil {
- errorWriter.Write([]byte(err.Error()))
+ case err := <-pushErrChan:
+ if err != nil {
+ var msg string
+ if errors.Cause(err) != storage.ErrImageUnknown {
+ msg = "An image does not exist locally with the tag: " + imageName
+ } else {
+ msg = err.Error()
+ }
+ report.Error = &jsonmessage.JSONError{
+ Message: msg,
+ }
+ report.ErrorMessage = msg
+ if err := enc.Encode(report); err != nil {
+ logrus.Warnf("Failed to json encode error %q", err.Error())
+ }
+ flush()
+ break loop
}
- flush()
- case e := <-errorWriter.Chan():
- failed = true
- report.Error = &jsonmessage.JSONError{
- Message: string(e),
+
+ digestBytes, err := ioutil.ReadAll(digestFile)
+ if err != nil {
+ report.Error = &jsonmessage.JSONError{
+ Message: err.Error(),
+ }
+ report.ErrorMessage = err.Error()
+ if err := enc.Encode(report); err != nil {
+ logrus.Warnf("Failed to json encode error %q", err.Error())
+ }
+ flush()
+ break loop
}
- report.ErrorMessage = string(e)
+ tag := query.Tag
+ if tag == "" {
+ tag = "latest"
+ }
+ report.Status = fmt.Sprintf("%s: digest: %s", tag, string(digestBytes))
if err := enc.Encode(report); err != nil {
logrus.Warnf("Failed to json encode error %q", err.Error())
}
+
flush()
- case <-runCtx.Done():
- if !failed {
- digestBytes, err := ioutil.ReadAll(digestFile)
- if err == nil {
- tag := query.Tag
- if tag == "" {
- tag = "latest"
- }
- report.Status = fmt.Sprintf("%s: digest: %s", tag, string(digestBytes))
- if err := enc.Encode(report); err != nil {
- logrus.Warnf("Failed to json encode error %q", err.Error())
- }
- flush()
- }
- }
- break loop // break out of for/select infinite loop
- case <-r.Context().Done():
- // Client has closed connection
break loop // break out of for/select infinite loop
}
}
diff --git a/pkg/api/handlers/compat/resize.go b/pkg/api/handlers/compat/resize.go
index 23ed33a22..f65e313fc 100644
--- a/pkg/api/handlers/compat/resize.go
+++ b/pkg/api/handlers/compat/resize.go
@@ -46,20 +46,13 @@ func ResizeTTY(w http.ResponseWriter, r *http.Request) {
utils.ContainerNotFound(w, name, err)
return
}
- if state, err := ctnr.State(); err != nil {
- utils.InternalServerError(w, errors.Wrapf(err, "cannot obtain container state"))
- return
- } else if state != define.ContainerStateRunning && !query.IgnoreNotRunning {
- utils.Error(w, "Container not running", http.StatusConflict,
- fmt.Errorf("container %q in wrong state %q", name, state.String()))
- return
- }
- // If container is not running, ignore since this can be a race condition, and is expected
if err := ctnr.AttachResize(sz); err != nil {
- if errors.Cause(err) != define.ErrCtrStateInvalid || !query.IgnoreNotRunning {
+ if errors.Cause(err) != define.ErrCtrStateInvalid {
utils.InternalServerError(w, errors.Wrapf(err, "cannot resize container"))
- return
+ } else {
+ utils.Error(w, "Container not running", http.StatusConflict, err)
}
+ return
}
// This is not a 204, even though we write nothing, for compatibility
// reasons.
diff --git a/pkg/api/handlers/libpod/images.go b/pkg/api/handlers/libpod/images.go
index a90408bfd..fc6ab4b4c 100644
--- a/pkg/api/handlers/libpod/images.go
+++ b/pkg/api/handlers/libpod/images.go
@@ -482,7 +482,7 @@ func PushImage(w http.ResponseWriter, r *http.Request) {
destination = source
}
- if _, err := utils.ParseDockerReference(destination); err != nil {
+ if err := utils.IsRegistryReference(destination); err != nil {
utils.Error(w, http.StatusText(http.StatusBadRequest), http.StatusBadRequest, err)
return
}
diff --git a/pkg/api/handlers/libpod/images_pull.go b/pkg/api/handlers/libpod/images_pull.go
index 7545ba235..fe56aa31d 100644
--- a/pkg/api/handlers/libpod/images_pull.go
+++ b/pkg/api/handlers/libpod/images_pull.go
@@ -48,7 +48,7 @@ func ImagesPull(w http.ResponseWriter, r *http.Request) {
}
// Make sure that the reference has no transport or the docker one.
- if _, err := utils.ParseDockerReference(query.Reference); err != nil {
+ if err := utils.IsRegistryReference(query.Reference); err != nil {
utils.Error(w, http.StatusText(http.StatusBadRequest), http.StatusBadRequest, err)
return
}
diff --git a/pkg/api/handlers/libpod/manifests.go b/pkg/api/handlers/libpod/manifests.go
index f21eb2e80..2f36db583 100644
--- a/pkg/api/handlers/libpod/manifests.go
+++ b/pkg/api/handlers/libpod/manifests.go
@@ -169,7 +169,7 @@ func ManifestPush(w http.ResponseWriter, r *http.Request) {
errors.Wrapf(err, "failed to parse parameters for %s", r.URL.String()))
return
}
- if _, err := utils.ParseDockerReference(query.Destination); err != nil {
+ if err := utils.IsRegistryReference(query.Destination); err != nil {
utils.Error(w, http.StatusText(http.StatusBadRequest), http.StatusBadRequest, err)
return
}
diff --git a/pkg/api/handlers/libpod/swagger.go b/pkg/api/handlers/libpod/swagger.go
index 9450a70d9..19eced986 100644
--- a/pkg/api/handlers/libpod/swagger.go
+++ b/pkg/api/handlers/libpod/swagger.go
@@ -95,7 +95,7 @@ type swagInfoResponse struct {
// swagger:response NetworkRmReport
type swagNetworkRmReport struct {
// in:body
- Body entities.NetworkRmReport
+ Body []entities.NetworkRmReport
}
// Network inspect
diff --git a/pkg/api/handlers/utils/images.go b/pkg/api/handlers/utils/images.go
index 2662cd368..2a1908d63 100644
--- a/pkg/api/handlers/utils/images.go
+++ b/pkg/api/handlers/utils/images.go
@@ -15,22 +15,19 @@ import (
"github.com/pkg/errors"
)
-// ParseDockerReference parses the specified image name to a
-// `types.ImageReference` and enforces it to refer to a docker-transport
-// reference.
-func ParseDockerReference(name string) (types.ImageReference, error) {
- dockerPrefix := fmt.Sprintf("%s://", docker.Transport.Name())
+// IsRegistryReference checks if the specified name points to the "docker://"
+// transport. If it points to no supported transport, we'll assume a
+// non-transport reference pointing to an image (e.g., "fedora:latest").
+func IsRegistryReference(name string) error {
imageRef, err := alltransports.ParseImageName(name)
- if err == nil && imageRef.Transport().Name() != docker.Transport.Name() {
- return nil, errors.Errorf("reference %q must be a docker reference", name)
- } else if err != nil {
- origErr := err
- imageRef, err = alltransports.ParseImageName(fmt.Sprintf("%s%s", dockerPrefix, name))
- if err != nil {
- return nil, errors.Wrapf(origErr, "reference %q must be a docker reference", name)
- }
+ if err != nil {
+ // No supported transport -> assume a docker-stype reference.
+ return nil
}
- return imageRef, nil
+ if imageRef.Transport().Name() == docker.Transport.Name() {
+ return nil
+ }
+ return errors.Errorf("unsupport transport %s in %q: only docker transport is supported", imageRef.Transport().Name(), name)
}
// ParseStorageReference parses the specified image name to a
diff --git a/pkg/api/server/handler_api.go b/pkg/api/server/handler_api.go
index 28b8706a8..becc674c0 100644
--- a/pkg/api/server/handler_api.go
+++ b/pkg/api/server/handler_api.go
@@ -63,6 +63,12 @@ func (s *APIServer) APIHandler(h http.HandlerFunc) http.HandlerFunc {
w.Header().Set("Libpod-API-Version", lv)
w.Header().Set("Server", "Libpod/"+lv+" ("+runtime.GOOS+")")
+ if s.CorsHeaders != "" {
+ w.Header().Set("Access-Control-Allow-Origin", s.CorsHeaders)
+ w.Header().Set("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept, X-Registry-Auth, Connection, Upgrade, X-Registry-Config")
+ w.Header().Set("Access-Control-Allow-Methods", "HEAD, GET, POST, DELETE, PUT, OPTIONS")
+ }
+
h(w, r)
logrus.Debugf("APIHandler(%s) -- %s %s END", rid, r.Method, r.URL.String())
}
diff --git a/pkg/api/server/register_containers.go b/pkg/api/server/register_containers.go
index 536c4707a..88ebb4df5 100644
--- a/pkg/api/server/register_containers.go
+++ b/pkg/api/server/register_containers.go
@@ -375,6 +375,11 @@ func (s *APIServer) registerContainersHandlers(r *mux.Router) error {
// type: boolean
// default: true
// description: Stream the output
+ // - in: query
+ // name: one-shot
+ // type: boolean
+ // default: false
+ // description: Provide a one-shot response in which preCPU stats are blank, resulting in a single cycle return.
// produces:
// - application/json
// responses:
@@ -1359,6 +1364,8 @@ func (s *APIServer) registerContainersHandlers(r *mux.Router) error {
// $ref: "#/responses/ok"
// 404:
// $ref: "#/responses/NoSuchContainer"
+ // 409:
+ // $ref: "#/responses/ConflictError"
// 500:
// $ref: "#/responses/InternalError"
r.HandleFunc(VersionedPath("/libpod/containers/{name}/resize"), s.APIHandler(compat.ResizeTTY)).Methods(http.MethodPost)
diff --git a/pkg/api/server/server.go b/pkg/api/server/server.go
index 972541bc6..1e8faf8f5 100644
--- a/pkg/api/server/server.go
+++ b/pkg/api/server/server.go
@@ -34,10 +34,12 @@ type APIServer struct {
context.CancelFunc // Stop APIServer
idleTracker *idle.Tracker // Track connections to support idle shutdown
pprof *http.Server // Sidecar http server for providing performance data
+ CorsHeaders string // Inject CORS headers to each request
}
// Number of seconds to wait for next request, if exceeded shutdown server
const (
+ DefaultCorsHeaders = ""
DefaultServiceDuration = 300 * time.Second
UnlimitedServiceDuration = 0 * time.Second
)
@@ -45,17 +47,22 @@ const (
// shutdownOnce ensures Shutdown() may safely be called from several go routines
var shutdownOnce sync.Once
+type Options struct {
+ Timeout time.Duration
+ CorsHeaders string
+}
+
// NewServer will create and configure a new API server with all defaults
func NewServer(runtime *libpod.Runtime) (*APIServer, error) {
- return newServer(runtime, DefaultServiceDuration, nil)
+ return newServer(runtime, DefaultServiceDuration, nil, DefaultCorsHeaders)
}
// NewServerWithSettings will create and configure a new API server using provided settings
-func NewServerWithSettings(runtime *libpod.Runtime, duration time.Duration, listener *net.Listener) (*APIServer, error) {
- return newServer(runtime, duration, listener)
+func NewServerWithSettings(runtime *libpod.Runtime, listener *net.Listener, opts Options) (*APIServer, error) {
+ return newServer(runtime, opts.Timeout, listener, opts.CorsHeaders)
}
-func newServer(runtime *libpod.Runtime, duration time.Duration, listener *net.Listener) (*APIServer, error) {
+func newServer(runtime *libpod.Runtime, duration time.Duration, listener *net.Listener, corsHeaders string) (*APIServer, error) {
// If listener not provided try socket activation protocol
if listener == nil {
if _, found := os.LookupEnv("LISTEN_PID"); !found {
@@ -71,6 +78,11 @@ func newServer(runtime *libpod.Runtime, duration time.Duration, listener *net.Li
}
listener = &listeners[0]
}
+ if corsHeaders == "" {
+ logrus.Debug("CORS Headers were not set")
+ } else {
+ logrus.Debugf("CORS Headers were set to %s", corsHeaders)
+ }
logrus.Infof("API server listening on %q", (*listener).Addr())
router := mux.NewRouter().UseEncodedPath()
@@ -88,6 +100,7 @@ func newServer(runtime *libpod.Runtime, duration time.Duration, listener *net.Li
idleTracker: idle,
Listener: *listener,
Runtime: runtime,
+ CorsHeaders: corsHeaders,
}
router.NotFoundHandler = http.HandlerFunc(
diff --git a/pkg/bindings/containers/attach.go b/pkg/bindings/containers/attach.go
index fd8a7011d..adef1e7c8 100644
--- a/pkg/bindings/containers/attach.go
+++ b/pkg/bindings/containers/attach.go
@@ -138,7 +138,7 @@ func Attach(ctx context.Context, nameOrID string, stdin io.Reader, stdout io.Wri
winCtx, winCancel := context.WithCancel(ctx)
defer winCancel()
- go attachHandleResize(ctx, winCtx, winChange, false, nameOrID, file)
+ attachHandleResize(ctx, winCtx, winChange, false, nameOrID, file)
}
// If we are attaching around a start, we need to "signal"
@@ -327,32 +327,38 @@ func (f *rawFormatter) Format(entry *logrus.Entry) ([]byte, error) {
return append(buffer, '\r'), nil
}
-// This is intended to be run as a goroutine, handling resizing for a container
-// or exec session.
+// This is intended to not be run as a goroutine, handling resizing for a container
+// or exec session. It will call resize once and then starts a goroutine which calls resize on winChange
func attachHandleResize(ctx, winCtx context.Context, winChange chan os.Signal, isExec bool, id string, file *os.File) {
- // Prime the pump, we need one reset to ensure everything is ready
- winChange <- sig.SIGWINCH
- for {
- select {
- case <-winCtx.Done():
- return
- case <-winChange:
- w, h, err := terminal.GetSize(int(file.Fd()))
- if err != nil {
- logrus.Warnf("failed to obtain TTY size: %v", err)
- }
+ resize := func() {
+ w, h, err := terminal.GetSize(int(file.Fd()))
+ if err != nil {
+ logrus.Warnf("failed to obtain TTY size: %v", err)
+ }
- var resizeErr error
- if isExec {
- resizeErr = ResizeExecTTY(ctx, id, new(ResizeExecTTYOptions).WithHeight(h).WithWidth(w))
- } else {
- resizeErr = ResizeContainerTTY(ctx, id, new(ResizeTTYOptions).WithHeight(h).WithWidth(w))
- }
- if resizeErr != nil {
- logrus.Warnf("failed to resize TTY: %v", resizeErr)
- }
+ var resizeErr error
+ if isExec {
+ resizeErr = ResizeExecTTY(ctx, id, new(ResizeExecTTYOptions).WithHeight(h).WithWidth(w))
+ } else {
+ resizeErr = ResizeContainerTTY(ctx, id, new(ResizeTTYOptions).WithHeight(h).WithWidth(w))
+ }
+ if resizeErr != nil {
+ logrus.Warnf("failed to resize TTY: %v", resizeErr)
}
}
+
+ resize()
+
+ go func() {
+ for {
+ select {
+ case <-winCtx.Done():
+ return
+ case <-winChange:
+ resize()
+ }
+ }
+ }()
}
// Configure the given terminal for raw mode
@@ -457,7 +463,7 @@ func ExecStartAndAttach(ctx context.Context, sessionID string, options *ExecStar
winCtx, winCancel := context.WithCancel(ctx)
defer winCancel()
- go attachHandleResize(ctx, winCtx, winChange, true, sessionID, terminalFile)
+ attachHandleResize(ctx, winCtx, winChange, true, sessionID, terminalFile)
}
if options.GetAttachInput() {
diff --git a/pkg/domain/entities/system.go b/pkg/domain/entities/system.go
index 31a6185dc..cca4bf44e 100644
--- a/pkg/domain/entities/system.go
+++ b/pkg/domain/entities/system.go
@@ -11,9 +11,10 @@ import (
// ServiceOptions provides the input for starting an API Service
type ServiceOptions struct {
- URI string // Path to unix domain socket service should listen on
- Timeout time.Duration // duration of inactivity the service should wait before shutting down
- Command *cobra.Command // CLI command provided. Used in V1 code
+ URI string // Path to unix domain socket service should listen on
+ Timeout time.Duration // duration of inactivity the service should wait before shutting down
+ Command *cobra.Command // CLI command provided. Used in V1 code
+ CorsHeaders string // CORS headers
}
// SystemPruneOptions provides options to prune system.
diff --git a/pkg/domain/infra/abi/network.go b/pkg/domain/infra/abi/network.go
index 33ab280e5..7900caaa6 100644
--- a/pkg/domain/infra/abi/network.go
+++ b/pkg/domain/infra/abi/network.go
@@ -11,7 +11,7 @@ import (
)
func (ic *ContainerEngine) NetworkList(ctx context.Context, options entities.NetworkListOptions) ([]*entities.NetworkListReport, error) {
- var reports []*entities.NetworkListReport
+ reports := make([]*entities.NetworkListReport, 0)
config, err := ic.Libpod.GetConfig()
if err != nil {
diff --git a/pkg/machine/config.go b/pkg/machine/config.go
index 652229963..58794ce42 100644
--- a/pkg/machine/config.go
+++ b/pkg/machine/config.go
@@ -32,6 +32,7 @@ var (
ErrVMAlreadyExists = errors.New("VM already exists")
ErrVMAlreadyRunning = errors.New("VM already running")
ErrMultipleActiveVM = errors.New("only one VM can be active at a time")
+ ForwarderBinaryName = "gvproxy"
)
type Download struct {
diff --git a/pkg/machine/ignition.go b/pkg/machine/ignition.go
index 00068a136..a5c7210af 100644
--- a/pkg/machine/ignition.go
+++ b/pkg/machine/ignition.go
@@ -118,6 +118,7 @@ func getDirs(usrName string) []Directory {
// in one swoop, then the leading dirs are creates as root.
newDirs := []string{
"/home/" + usrName + "/.config",
+ "/home/" + usrName + "/.config/containers",
"/home/" + usrName + "/.config/systemd",
"/home/" + usrName + "/.config/systemd/user",
"/home/" + usrName + "/.config/systemd/user/default.target.wants",
@@ -159,6 +160,22 @@ func getFiles(usrName string) []File {
},
})
+ // Set containers.conf up for core user to use cni networks
+ // by default
+ files = append(files, File{
+ Node: Node{
+ Group: getNodeGrp(usrName),
+ Path: "/home/" + usrName + "/.config/containers/containers.conf",
+ User: getNodeUsr(usrName),
+ },
+ FileEmbedded1: FileEmbedded1{
+ Append: nil,
+ Contents: Resource{
+ Source: strToPtr("data:,%5Bcontainers%5D%0D%0Anetns%3D%22bridge%22%0D%0Arootless_networking%3D%22cni%22"),
+ },
+ Mode: intToPtr(484),
+ },
+ })
// Add a file into linger
files = append(files, File{
Node: Node{
diff --git a/pkg/machine/qemu/machine.go b/pkg/machine/qemu/machine.go
index 0bd711c90..31c355d4a 100644
--- a/pkg/machine/qemu/machine.go
+++ b/pkg/machine/qemu/machine.go
@@ -13,6 +13,8 @@ import (
"strings"
"time"
+ "github.com/containers/podman/v3/pkg/rootless"
+
"github.com/containers/podman/v3/pkg/machine"
"github.com/containers/podman/v3/utils"
"github.com/containers/storage/pkg/homedir"
@@ -82,9 +84,10 @@ func NewMachine(opts machine.InitOptions) (machine.VM, error) {
cmd = append(cmd, []string{"-qmp", monitor.Network + ":/" + monitor.Address + ",server=on,wait=off"}...)
// Add network
- cmd = append(cmd, "-nic", "user,model=virtio,hostfwd=tcp::"+strconv.Itoa(vm.Port)+"-:22")
-
- socketPath, err := getSocketDir()
+ // Right now the mac address is hardcoded so that the host networking gives it a specific IP address. This is
+ // why we can only run one vm at a time right now
+ cmd = append(cmd, []string{"-netdev", "socket,id=vlan,fd=3", "-device", "virtio-net-pci,netdev=vlan,mac=5a:94:ef:e4:0c:ee"}...)
+ socketPath, err := getRuntimeDir()
if err != nil {
return nil, err
}
@@ -235,12 +238,35 @@ func (v *MachineVM) Init(opts machine.InitOptions) error {
// Start executes the qemu command line and forks it
func (v *MachineVM) Start(name string, _ machine.StartOptions) error {
var (
- conn net.Conn
- err error
- wait time.Duration = time.Millisecond * 500
+ conn net.Conn
+ err error
+ qemuSocketConn net.Conn
+ wait time.Duration = time.Millisecond * 500
)
+ if err := v.startHostNetworking(); err != nil {
+ return errors.Errorf("unable to start host networking: %q", err)
+ }
+ qemuSocketPath, _, err := v.getSocketandPid()
+
+ for i := 0; i < 6; i++ {
+ qemuSocketConn, err = net.Dial("unix", qemuSocketPath)
+ if err == nil {
+ break
+ }
+ time.Sleep(wait)
+ wait++
+ }
+ if err != nil {
+ return err
+ }
+
+ fd, err := qemuSocketConn.(*net.UnixConn).File()
+ if err != nil {
+ return err
+ }
+
attr := new(os.ProcAttr)
- files := []*os.File{os.Stdin, os.Stdout, os.Stderr}
+ files := []*os.File{os.Stdin, os.Stdout, os.Stderr, fd}
attr.Files = files
logrus.Debug(v.CmdLine)
cmd := v.CmdLine
@@ -256,7 +282,7 @@ func (v *MachineVM) Start(name string, _ machine.StartOptions) error {
return err
}
fmt.Println("Waiting for VM ...")
- socketPath, err := getSocketDir()
+ socketPath, err := getRuntimeDir()
if err != nil {
return err
}
@@ -309,16 +335,42 @@ func (v *MachineVM) Stop(name string, _ machine.StopOptions) error {
logrus.Error(err)
}
}()
- _, err = qmpMonitor.Run(input)
- return err
+ if _, err = qmpMonitor.Run(input); err != nil {
+ return err
+ }
+ _, pidFile, err := v.getSocketandPid()
+ if err != nil {
+ return err
+ }
+ if _, err := os.Stat(pidFile); os.IsNotExist(err) {
+ logrus.Infof("pid file %s does not exist", pidFile)
+ return nil
+ }
+ pidString, err := ioutil.ReadFile(pidFile)
+ if err != nil {
+ return err
+ }
+ pidNum, err := strconv.Atoi(string(pidString))
+ if err != nil {
+ return err
+ }
+
+ p, err := os.FindProcess(pidNum)
+ if p == nil && err != nil {
+ return err
+ }
+ return p.Kill()
}
// NewQMPMonitor creates the monitor subsection of our vm
func NewQMPMonitor(network, name string, timeout time.Duration) (Monitor, error) {
- rtDir, err := getSocketDir()
+ rtDir, err := getRuntimeDir()
if err != nil {
return Monitor{}, err
}
+ if !rootless.IsRootless() {
+ rtDir = "/run"
+ }
rtDir = filepath.Join(rtDir, "podman")
if _, err := os.Stat(filepath.Join(rtDir)); os.IsNotExist(err) {
// TODO 0644 is fine on linux but macos is weird
@@ -533,3 +585,47 @@ func CheckActiveVM() (bool, string, error) {
}
return false, "", nil
}
+
+// startHostNetworking runs a binary on the host system that allows users
+// to setup port forwarding to the podman virtual machine
+func (v *MachineVM) startHostNetworking() error {
+ binary, err := exec.LookPath(machine.ForwarderBinaryName)
+ if err != nil {
+ return err
+ }
+ // Listen on all at port 7777 for setting up and tearing
+ // down forwarding
+ listenSocket := "tcp://0.0.0.0:7777"
+ qemuSocket, pidFile, err := v.getSocketandPid()
+ if err != nil {
+ return err
+ }
+ attr := new(os.ProcAttr)
+ // Pass on stdin, stdout, stderr
+ files := []*os.File{os.Stdin, os.Stdout, os.Stderr}
+ attr.Files = files
+ cmd := []string{binary}
+ cmd = append(cmd, []string{"-listen", listenSocket, "-listen-qemu", fmt.Sprintf("unix://%s", qemuSocket), "-pid-file", pidFile}...)
+ // Add the ssh port
+ cmd = append(cmd, []string{"-ssh-port", fmt.Sprintf("%d", v.Port)}...)
+ if logrus.GetLevel() == logrus.DebugLevel {
+ cmd = append(cmd, "--debug")
+ fmt.Println(cmd)
+ }
+ _, err = os.StartProcess(cmd[0], cmd, attr)
+ return err
+}
+
+func (v *MachineVM) getSocketandPid() (string, string, error) {
+ rtPath, err := getRuntimeDir()
+ if err != nil {
+ return "", "", err
+ }
+ if !rootless.IsRootless() {
+ rtPath = "/run"
+ }
+ socketDir := filepath.Join(rtPath, "podman")
+ pidFile := filepath.Join(socketDir, fmt.Sprintf("%s.pid", v.Name))
+ qemuSocket := filepath.Join(socketDir, fmt.Sprintf("qemu_%s.sock", v.Name))
+ return qemuSocket, pidFile, nil
+}
diff --git a/pkg/machine/qemu/options_darwin.go b/pkg/machine/qemu/options_darwin.go
index 46ccf24cb..440937131 100644
--- a/pkg/machine/qemu/options_darwin.go
+++ b/pkg/machine/qemu/options_darwin.go
@@ -6,7 +6,7 @@ import (
"github.com/pkg/errors"
)
-func getSocketDir() (string, error) {
+func getRuntimeDir() (string, error) {
tmpDir, ok := os.LookupEnv("TMPDIR")
if !ok {
return "", errors.New("unable to resolve TMPDIR")
diff --git a/pkg/machine/qemu/options_darwin_amd64.go b/pkg/machine/qemu/options_darwin_amd64.go
index 69f7982b2..ee1036291 100644
--- a/pkg/machine/qemu/options_darwin_amd64.go
+++ b/pkg/machine/qemu/options_darwin_amd64.go
@@ -5,7 +5,7 @@ var (
)
func (v *MachineVM) addArchOptions() []string {
- opts := []string{"-cpu", "host"}
+ opts := []string{"-machine", "q35,accel=hvf:tcg"}
return opts
}
diff --git a/pkg/machine/qemu/options_linux.go b/pkg/machine/qemu/options_linux.go
index 0a2e40d8f..c73a68cc6 100644
--- a/pkg/machine/qemu/options_linux.go
+++ b/pkg/machine/qemu/options_linux.go
@@ -1,7 +1,13 @@
package qemu
-import "github.com/containers/podman/v3/pkg/util"
+import (
+ "github.com/containers/podman/v3/pkg/rootless"
+ "github.com/containers/podman/v3/pkg/util"
+)
-func getSocketDir() (string, error) {
+func getRuntimeDir() (string, error) {
+ if !rootless.IsRootless() {
+ return "/run", nil
+ }
return util.GetRuntimeDir()
}
diff --git a/pkg/rootless/rootless_linux.c b/pkg/rootless/rootless_linux.c
index 918b9a7e6..0d1d6e93e 100644
--- a/pkg/rootless/rootless_linux.c
+++ b/pkg/rootless/rootless_linux.c
@@ -311,10 +311,10 @@ static void __attribute__((constructor)) init()
do_socket_activation = true;
saved_systemd_listen_pid = strdup(listen_pid);
saved_systemd_listen_fds = strdup(listen_fds);
- saved_systemd_listen_fdnames = strdup(listen_fdnames);
+ if (listen_fdnames != NULL)
+ saved_systemd_listen_fdnames = strdup(listen_fdnames);
if (saved_systemd_listen_pid == NULL
- || saved_systemd_listen_fds == NULL
- || saved_systemd_listen_fdnames == NULL)
+ || saved_systemd_listen_fds == NULL)
{
fprintf (stderr, "save socket listen environments error: %s\n", strerror (errno));
_exit (EXIT_FAILURE);
@@ -700,7 +700,9 @@ reexec_userns_join (int pid_to_join, char *pause_pid_file_path)
sprintf (s, "%d", getpid());
setenv ("LISTEN_PID", s, true);
setenv ("LISTEN_FDS", saved_systemd_listen_fds, true);
- setenv ("LISTEN_FDNAMES", saved_systemd_listen_fdnames, true);
+ // Setting fdnames is optional for systemd_socket_activation
+ if (saved_systemd_listen_fdnames != NULL)
+ setenv ("LISTEN_FDNAMES", saved_systemd_listen_fdnames, true);
}
setenv ("_CONTAINERS_USERNS_CONFIGURED", "init", 1);
@@ -896,7 +898,9 @@ reexec_in_user_namespace (int ready, char *pause_pid_file_path, char *file_to_re
sprintf (s, "%d", getpid());
setenv ("LISTEN_PID", s, true);
setenv ("LISTEN_FDS", saved_systemd_listen_fds, true);
- setenv ("LISTEN_FDNAMES", saved_systemd_listen_fdnames, true);
+ // Setting fdnames is optional for systemd_socket_activation
+ if (saved_systemd_listen_fdnames != NULL)
+ setenv ("LISTEN_FDNAMES", saved_systemd_listen_fdnames, true);
}
setenv ("_CONTAINERS_USERNS_CONFIGURED", "init", 1);
diff --git a/pkg/systemd/generate/common.go b/pkg/systemd/generate/common.go
index 0f667e2f4..1ee070888 100644
--- a/pkg/systemd/generate/common.go
+++ b/pkg/systemd/generate/common.go
@@ -36,7 +36,7 @@ Description=Podman {{{{.ServiceName}}}}.service
Documentation=man:podman-generate-systemd(1)
Wants=network.target
After=network-online.target
-RequiresMountsFor={{{{.GraphRoot}}}} {{{{.RunRoot}}}}
+RequiresMountsFor={{{{.RunRoot}}}}
`
// filterPodFlags removes --pod, --pod-id-file and --infra-conmon-pidfile from the specified command.
diff --git a/pkg/systemd/generate/containers.go b/pkg/systemd/generate/containers.go
index eb1fb67ff..72f321347 100644
--- a/pkg/systemd/generate/containers.go
+++ b/pkg/systemd/generate/containers.go
@@ -152,14 +152,14 @@ func generateContainerInfo(ctr *libpod.Container, options entities.GenerateSyste
return nil, errors.Errorf("could not determine storage store for container")
}
- graphRoot := store.GraphRoot()
- if graphRoot == "" {
- return nil, errors.Errorf("could not lookup container's graphroot: got empty string")
- }
-
- runRoot := store.RunRoot()
- if runRoot == "" {
- return nil, errors.Errorf("could not lookup container's runroot: got empty string")
+ var runRoot string
+ if options.New {
+ runRoot = "%t/containers"
+ } else {
+ runRoot = store.RunRoot()
+ if runRoot == "" {
+ return nil, errors.Errorf("could not lookup container's runroot: got empty string")
+ }
}
envs := config.Spec.Process.Env
@@ -172,7 +172,6 @@ func generateContainerInfo(ctr *libpod.Container, options entities.GenerateSyste
StopTimeout: timeout,
GenerateTimestamp: true,
CreateCommand: createCommand,
- GraphRoot: graphRoot,
RunRoot: runRoot,
containerEnv: envs,
}
diff --git a/pkg/systemd/generate/containers_test.go b/pkg/systemd/generate/containers_test.go
index 75b08526b..b1070fa52 100644
--- a/pkg/systemd/generate/containers_test.go
+++ b/pkg/systemd/generate/containers_test.go
@@ -48,7 +48,7 @@ Description=Podman container-639c53578af4d84b8800b4635fa4e680ee80fd67e0e6a2d4eea
Documentation=man:podman-generate-systemd(1)
Wants=network.target
After=network-online.target
-RequiresMountsFor=/var/lib/containers/storage /var/run/containers/storage
+RequiresMountsFor=/var/run/containers/storage
[Service]
Environment=PODMAN_SYSTEMD_UNIT=%n
@@ -74,7 +74,7 @@ Description=Podman container-foobar.service
Documentation=man:podman-generate-systemd(1)
Wants=network.target
After=network-online.target
-RequiresMountsFor=/var/lib/containers/storage /var/run/containers/storage
+RequiresMountsFor=/var/run/containers/storage
[Service]
Environment=PODMAN_SYSTEMD_UNIT=%n
@@ -98,7 +98,7 @@ Description=Podman container-foobar.service
Documentation=man:podman-generate-systemd(1)
Wants=network.target
After=network-online.target
-RequiresMountsFor=/var/lib/containers/storage /var/run/containers/storage
+RequiresMountsFor=/var/run/containers/storage
BindsTo=a.service b.service c.service pod.service
After=a.service b.service c.service pod.service
@@ -124,7 +124,7 @@ Description=Podman jadda-jadda.service
Documentation=man:podman-generate-systemd(1)
Wants=network.target
After=network-online.target
-RequiresMountsFor=/var/lib/containers/storage /var/run/containers/storage
+RequiresMountsFor=/var/run/containers/storage
[Service]
Environment=PODMAN_SYSTEMD_UNIT=%n
@@ -149,7 +149,7 @@ Description=Podman jadda-jadda.service
Documentation=man:podman-generate-systemd(1)
Wants=network.target
After=network-online.target
-RequiresMountsFor=/var/lib/containers/storage /var/run/containers/storage
+RequiresMountsFor=/var/run/containers/storage
[Service]
Environment=PODMAN_SYSTEMD_UNIT=%n
@@ -174,7 +174,7 @@ Description=Podman jadda-jadda.service
Documentation=man:podman-generate-systemd(1)
Wants=network.target
After=network-online.target
-RequiresMountsFor=/var/lib/containers/storage /var/run/containers/storage
+RequiresMountsFor=/var/run/containers/storage
[Service]
Environment=PODMAN_SYSTEMD_UNIT=%n
@@ -199,7 +199,7 @@ Description=Podman jadda-jadda.service
Documentation=man:podman-generate-systemd(1)
Wants=network.target
After=network-online.target
-RequiresMountsFor=/var/lib/containers/storage /var/run/containers/storage
+RequiresMountsFor=/var/run/containers/storage
[Service]
Environment=PODMAN_SYSTEMD_UNIT=%n
@@ -224,7 +224,7 @@ Description=Podman container-639c53578af4d84b8800b4635fa4e680ee80fd67e0e6a2d4eea
Documentation=man:podman-generate-systemd(1)
Wants=network.target
After=network-online.target
-RequiresMountsFor=/var/lib/containers/storage /var/run/containers/storage
+RequiresMountsFor=/var/run/containers/storage
[Service]
Environment=PODMAN_SYSTEMD_UNIT=%n
@@ -250,7 +250,7 @@ Description=Podman jadda-jadda.service
Documentation=man:podman-generate-systemd(1)
Wants=network.target
After=network-online.target
-RequiresMountsFor=/var/lib/containers/storage /var/run/containers/storage
+RequiresMountsFor=/var/run/containers/storage
[Service]
Environment=PODMAN_SYSTEMD_UNIT=%n
@@ -279,7 +279,7 @@ Description=Podman jadda-jadda.service
Documentation=man:podman-generate-systemd(1)
Wants=network.target
After=network-online.target
-RequiresMountsFor=/var/lib/containers/storage /var/run/containers/storage
+RequiresMountsFor=/var/run/containers/storage
[Service]
Environment=PODMAN_SYSTEMD_UNIT=%n
@@ -304,7 +304,7 @@ Description=Podman jadda-jadda.service
Documentation=man:podman-generate-systemd(1)
Wants=network.target
After=network-online.target
-RequiresMountsFor=/var/lib/containers/storage /var/run/containers/storage
+RequiresMountsFor=/var/run/containers/storage
[Service]
Environment=PODMAN_SYSTEMD_UNIT=%n
@@ -329,7 +329,7 @@ Description=Podman jadda-jadda.service
Documentation=man:podman-generate-systemd(1)
Wants=network.target
After=network-online.target
-RequiresMountsFor=/var/lib/containers/storage /var/run/containers/storage
+RequiresMountsFor=/var/run/containers/storage
[Service]
Environment=PODMAN_SYSTEMD_UNIT=%n
@@ -354,7 +354,7 @@ Description=Podman jadda-jadda.service
Documentation=man:podman-generate-systemd(1)
Wants=network.target
After=network-online.target
-RequiresMountsFor=/var/lib/containers/storage /var/run/containers/storage
+RequiresMountsFor=/var/run/containers/storage
[Service]
Environment=PODMAN_SYSTEMD_UNIT=%n
@@ -379,7 +379,7 @@ Description=Podman jadda-jadda.service
Documentation=man:podman-generate-systemd(1)
Wants=network.target
After=network-online.target
-RequiresMountsFor=/var/lib/containers/storage /var/run/containers/storage
+RequiresMountsFor=/var/run/containers/storage
[Service]
Environment=PODMAN_SYSTEMD_UNIT=%n
@@ -404,7 +404,7 @@ Description=Podman jadda-jadda.service
Documentation=man:podman-generate-systemd(1)
Wants=network.target
After=network-online.target
-RequiresMountsFor=/var/lib/containers/storage /var/run/containers/storage
+RequiresMountsFor=/var/run/containers/storage
[Service]
Environment=PODMAN_SYSTEMD_UNIT=%n
@@ -429,7 +429,7 @@ Description=Podman jadda-jadda.service
Documentation=man:podman-generate-systemd(1)
Wants=network.target
After=network-online.target
-RequiresMountsFor=/var/lib/containers/storage /var/run/containers/storage
+RequiresMountsFor=/var/run/containers/storage
[Service]
Environment=PODMAN_SYSTEMD_UNIT=%n
@@ -454,7 +454,7 @@ Description=Podman jadda-jadda.service
Documentation=man:podman-generate-systemd(1)
Wants=network.target
After=network-online.target
-RequiresMountsFor=/var/lib/containers/storage /var/run/containers/storage
+RequiresMountsFor=/var/run/containers/storage
[Service]
Environment=PODMAN_SYSTEMD_UNIT=%n
diff --git a/pkg/systemd/generate/pods_test.go b/pkg/systemd/generate/pods_test.go
index 0e4d92c50..a11e1e11e 100644
--- a/pkg/systemd/generate/pods_test.go
+++ b/pkg/systemd/generate/pods_test.go
@@ -47,7 +47,7 @@ Description=Podman pod-123abc.service
Documentation=man:podman-generate-systemd(1)
Wants=network.target
After=network-online.target
-RequiresMountsFor=/var/lib/containers/storage /var/run/containers/storage
+RequiresMountsFor=/var/run/containers/storage
Requires=container-1.service container-2.service
Before=container-1.service container-2.service
@@ -75,7 +75,7 @@ Description=Podman pod-123abc.service
Documentation=man:podman-generate-systemd(1)
Wants=network.target
After=network-online.target
-RequiresMountsFor=/var/lib/containers/storage /var/run/containers/storage
+RequiresMountsFor=/var/run/containers/storage
Requires=container-1.service container-2.service
Before=container-1.service container-2.service
@@ -103,7 +103,7 @@ Description=Podman pod-123abc.service
Documentation=man:podman-generate-systemd(1)
Wants=network.target
After=network-online.target
-RequiresMountsFor=/var/lib/containers/storage /var/run/containers/storage
+RequiresMountsFor=/var/run/containers/storage
Requires=container-1.service container-2.service
Before=container-1.service container-2.service
@@ -131,7 +131,7 @@ Description=Podman pod-123abc.service
Documentation=man:podman-generate-systemd(1)
Wants=network.target
After=network-online.target
-RequiresMountsFor=/var/lib/containers/storage /var/run/containers/storage
+RequiresMountsFor=/var/run/containers/storage
Requires=container-1.service container-2.service
Before=container-1.service container-2.service
@@ -159,7 +159,7 @@ Description=Podman pod-123abc.service
Documentation=man:podman-generate-systemd(1)
Wants=network.target
After=network-online.target
-RequiresMountsFor=/var/lib/containers/storage /var/run/containers/storage
+RequiresMountsFor=/var/run/containers/storage
Requires=container-1.service container-2.service
Before=container-1.service container-2.service