libpod: use /var/run instead of /run on FreeBSD

This changes /run to /var/run for .containerenv and secrets in FreeBSD
containers for consistency with FreeBSD path conventions. Running Linux
containers on FreeBSD hosts continue to use /run for compatibility.

[NO NEW TESTS NEEDED]

Signed-off-by: Doug Rabson <dfr@rabson.org>
This commit is contained in:
Doug Rabson
2023-08-17 14:04:23 +01:00
parent e0b8178ad0
commit 27b41f0877
9 changed files with 87 additions and 15 deletions

View File

@ -26,7 +26,9 @@ Secret Options
- `target=target` : Target of secret.
For mounted secrets, this is the path to the secret inside the container.
If a fully qualified path is provided, the secret is mounted at that location.
Otherwise, the secret is mounted to `/run/secrets/target`.
Otherwise, the secret is mounted to
`/run/secrets/target` for linux containers or
`/var/run/secrets/target` for freebsd containers.
If the target is not set, the secret is mounted to `/run/secrets/secretname` by default.
For env secrets, this is the environment variable key. Defaults to `secretname`.
- `uid=0` : UID of secret. Defaults to 0. Mount secret type only.

View File

@ -28,7 +28,8 @@ These will be based on the host's version of the files, though they can be
customized with options (for example, **--dns** will override the host's DNS
servers in the created _resolv.conf_). Additionally, a container environment
file is created in each container to indicate to programs they are running in a
container. This file is located at _/run/.containerenv_. When using the
container. This file is located at _/run/.containerenv_ (or
_/var/run/.containerenv_ for FreeBSD containers). When using the
--privileged flag the .containerenv contains name/value pairs indicating the
container engine version, whether the engine is running in rootless mode, the
container name and ID, as well as the image name and ID that the container is based on. Note: _/run/.containerenv_ will not be created when a volume is mounted on /run.

View File

@ -1953,16 +1953,22 @@ func (c *Container) makeBindMounts() error {
}
}
_, hasRunContainerenv := c.state.BindMounts["/run/.containerenv"]
runPath, err := c.getPlatformRunPath()
if err != nil {
return fmt.Errorf("cannot determine run directory for container: %w", err)
}
containerenvPath := filepath.Join(runPath, ".containerenv")
_, hasRunContainerenv := c.state.BindMounts[containerenvPath]
if !hasRunContainerenv {
Loop:
// check in the spec mounts
for _, m := range c.config.Spec.Mounts {
switch {
case m.Destination == "/run/.containerenv":
case m.Destination == containerenvPath:
hasRunContainerenv = true
break Loop
case m.Destination == "/run" && m.Type != define.TypeTmpfs:
case m.Destination == runPath && m.Type != define.TypeTmpfs:
hasRunContainerenv = true
break Loop
}
@ -1988,11 +1994,11 @@ imageid=%q
rootless=%d
%s`, version.Version.String(), c.Name(), c.ID(), imageName, imageID, isRootless, containerenv)
}
containerenvPath, err := c.writeStringToRundir(".containerenv", containerenv)
containerenvHostPath, err := c.writeStringToRundir(".containerenv", containerenv)
if err != nil {
return fmt.Errorf("creating containerenv file for container %s: %w", c.ID(), err)
}
c.state.BindMounts["/run/.containerenv"] = containerenvPath
c.state.BindMounts[containerenvPath] = containerenvHostPath
}
// Add Subscription Mounts
@ -2010,12 +2016,12 @@ rootless=%d
// creates the /run/secrets dir in the container where we mount as well.
if len(c.Secrets()) > 0 {
// create /run/secrets if subscriptions did not create
if err := c.createSecretMountDir(); err != nil {
if err := c.createSecretMountDir(runPath); err != nil {
return fmt.Errorf("creating secrets mount: %w", err)
}
for _, secret := range c.Secrets() {
secretFileName := secret.Name
base := "/run/secrets"
base := filepath.Join(runPath, "secrets")
if secret.Target != "" {
secretFileName = secret.Target
// If absolute path for target given remove base.
@ -2797,7 +2803,7 @@ func (c *Container) cleanupOverlayMounts() error {
}
// Creates and mounts an empty dir to mount secrets into, if it does not already exist
func (c *Container) createSecretMountDir() error {
func (c *Container) createSecretMountDir(runPath string) error {
src := filepath.Join(c.state.RunDir, "/run/secrets")
_, err := os.Stat(src)
if os.IsNotExist(err) {
@ -2810,7 +2816,7 @@ func (c *Container) createSecretMountDir() error {
if err := os.Chown(src, c.RootUID(), c.RootGID()); err != nil {
return err
}
c.state.BindMounts["/run/secrets"] = src
c.state.BindMounts[filepath.Join(runPath, "secrets")] = src
return nil
}

View File

@ -365,3 +365,23 @@ func (c *Container) makePlatformMtabLink(etcInTheContainerFd, rootUID, rootGID i
// /etc/mtab does not exist on FreeBSD
return nil
}
func (c *Container) getPlatformRunPath() (string, error) {
// If we have a linux image, use "/run", otherwise use "/var/run" for
// consistency with FreeBSD path conventions.
runPath := "/var/run"
if c.config.RootfsImageID != "" {
image, _, err := c.runtime.libimageRuntime.LookupImage(c.config.RootfsImageID, nil)
if err != nil {
return "", err
}
inspectData, err := image.Inspect(nil, nil)
if err != nil {
return "", err
}
if inspectData.Os == "linux" {
runPath = "/run"
}
}
return runPath, nil
}

View File

@ -801,3 +801,7 @@ func (c *Container) makePlatformMtabLink(etcInTheContainerFd, rootUID, rootGID i
}
return nil
}
func (c *Container) getPlatformRunPath() (string, error) {
return "/run", nil
}

View File

@ -424,6 +424,8 @@ func (r *Runtime) setupContainer(ctx context.Context, ctr *Container) (_ *Contai
g.RemoveMount("/etc/hosts")
g.RemoveMount("/run/.containerenv")
g.RemoveMount("/run/secrets")
g.RemoveMount("/var/run/.containerenv")
g.RemoveMount("/var/run/secrets")
// Regenerate Cgroup paths so they don't point to the old
// container ID.

View File

@ -176,7 +176,11 @@ func finalizeMounts(ctx context.Context, s *specgen.SpecGenerator, rt *libpod.Ru
}
if s.ReadWriteTmpfs {
baseMounts = addReadWriteTmpfsMounts(baseMounts, s.Volumes)
runPath, err := imageRunPath(ctx, img)
if err != nil {
return nil, nil, nil, err
}
baseMounts = addReadWriteTmpfsMounts(baseMounts, s.Volumes, runPath)
}
// Final step: maps to arrays
@ -440,8 +444,8 @@ func InitFSMounts(mounts []spec.Mount) error {
return nil
}
func addReadWriteTmpfsMounts(mounts map[string]spec.Mount, volumes []*specgen.NamedVolume) map[string]spec.Mount {
readonlyTmpfs := []string{"/tmp", "/var/tmp", "/run"}
func addReadWriteTmpfsMounts(mounts map[string]spec.Mount, volumes []*specgen.NamedVolume, runPath string) map[string]spec.Mount {
readonlyTmpfs := []string{"/tmp", "/var/tmp", runPath}
options := []string{"rw", "rprivate", "nosuid", "nodev", "tmpcopyup"}
for _, dest := range readonlyTmpfs {
if _, ok := mounts[dest]; ok {
@ -458,7 +462,7 @@ func addReadWriteTmpfsMounts(mounts map[string]spec.Mount, volumes []*specgen.Na
Source: define.TypeTmpfs,
Options: options,
}
if dest != "/run" {
if dest != runPath {
mnt.Options = append(mnt.Options, "noexec")
}
mounts[dest] = mnt

View File

@ -0,0 +1,22 @@
package generate
import (
"context"
"github.com/containers/common/libimage"
)
func imageRunPath(ctx context.Context, img *libimage.Image) (string, error) {
if img != nil {
inspectData, err := img.Inspect(ctx, nil)
if err != nil {
return "", err
}
if inspectData.Os == "freebsd" {
return "/var/run", nil
}
return "/run", nil
} else {
return "/var/run", nil
}
}

View File

@ -0,0 +1,11 @@
package generate
import (
"context"
"github.com/containers/common/libimage"
)
func imageRunPath(ctx context.Context, img *libimage.Image) (string, error) {
return "/run", nil
}