Skip to content

Commit

Permalink
Merge pull request #3637 from rhatdan/cgroup
Browse files Browse the repository at this point in the history
Grab all of the containers.conf settings for namespaces
  • Loading branch information
openshift-merge-robot committed Nov 30, 2021
2 parents d469df2 + b480ce8 commit 6d01253
Show file tree
Hide file tree
Showing 10 changed files with 97 additions and 35 deletions.
7 changes: 7 additions & 0 deletions docs/buildah-build.1.md
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,13 @@ The default certificates directory is _/etc/containers/certs.d_.

Path to cgroups under which the cgroup for the container will be created. If the path is not absolute, the path is considered to be relative to the cgroups path of the init process. Cgroups will be created if they do not already exist.

**--cgroupns** *how*

Sets the configuration for cgroup namespaces when handling `RUN` instructions.
The configured value can be "" (the empty string) or "private" to indicate
that a new cgroup namespace should be created, or it can be "host" to indicate
that the cgroup namespace in which `buildah` itself is being run should be reused.

**--compress**

This option is added to be aligned with other containers CLIs.
Expand Down
8 changes: 8 additions & 0 deletions docs/buildah-from.1.md
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,14 @@ The default certificates directory is _/etc/containers/certs.d_.

Path to cgroups under which the cgroup for the container will be created. If the path is not absolute, the path is considered to be relative to the cgroups path of the init process. Cgroups will be created if they do not already exist.

**--cgroupns** *how*

Sets the configuration for IPC namespaces when the container is subsequently
used for `buildah run`.
The configured value can be "" (the empty string) or "private" to indicate
that a new cgroup namespace should be created, or it can be "host" to indicate
that the cgroup namespace in which `buildah` itself is being run should be reused.

**--cidfile** *ContainerIDFile*

Write the container ID to the file.
Expand Down
7 changes: 7 additions & 0 deletions docs/buildah-run.1.md
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,13 @@ Allows setting context directory for current RUN invocation. Specifying a contex
directory causes RUN context to consider context directory as root directory for
specified source in `--mount` of type 'bind'.

**--cgroupns** *how*

Sets the configuration for the cgroup namespaces for the container.
The configured value can be "" (the empty string) or "private" to indicate
that a new cgroup namespace should be created, or it can be "host" to indicate
that the cgroup namespace in which `buildah` itself is being run should be reused.

**--env**, **-e** *env=value*

Temporarily add a value (e.g. env=*value*) to the environment for the running
Expand Down
3 changes: 3 additions & 0 deletions pkg/cli/common.go
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ type UserNSResults struct {

// NameSpaceResults represents the results for Namespace flags
type NameSpaceResults struct {
Cgroup string
IPC string
Network string
CNIConfigDir string
Expand Down Expand Up @@ -143,6 +144,7 @@ func GetUserNSFlagsCompletions() commonComp.FlagCompletions {
// GetNameSpaceFlags returns the common flags for a namespace menu
func GetNameSpaceFlags(flags *NameSpaceResults) pflag.FlagSet {
fs := pflag.FlagSet{}
fs.StringVar(&flags.Cgroup, "cgroupns", "", "'private', or 'host'")
fs.StringVar(&flags.IPC, string(specs.IPCNamespace), "", "'private', `path` of IPC namespace to join, or 'host'")
fs.StringVar(&flags.Network, string(specs.NetworkNamespace), "", "'private', 'none', 'ns:path' of network namespace to join, or 'host'")
fs.StringVar(&flags.CNIConfigDir, "cni-config-dir", define.DefaultCNIConfigDir, "`directory` of CNI configuration files")
Expand All @@ -155,6 +157,7 @@ func GetNameSpaceFlags(flags *NameSpaceResults) pflag.FlagSet {
// GetNameSpaceFlagsCompletions returns the FlagCompletions for the namespace flags
func GetNameSpaceFlagsCompletions() commonComp.FlagCompletions {
flagCompletion := commonComp.FlagCompletions{}
flagCompletion["cgroupns"] = completion.AutocompleteNamespaceFlag
flagCompletion[string(specs.IPCNamespace)] = completion.AutocompleteNamespaceFlag
flagCompletion[string(specs.NetworkNamespace)] = completion.AutocompleteNamespaceFlag
flagCompletion["cni-config-dir"] = commonComp.AutocompleteDefault
Expand Down
11 changes: 3 additions & 8 deletions pkg/parse/parse.go
Original file line number Diff line number Diff line change
Expand Up @@ -1005,13 +1005,6 @@ func IDMappingOptions(c *cobra.Command, isolation define.Isolation) (usernsOptio
}
usernsOptions = define.NamespaceOptions{usernsOption}

usernetwork := c.Flags().Lookup("network")
if usernetwork != nil && !usernetwork.Changed {
usernsOptions = append(usernsOptions, define.NamespaceOption{
Name: string(specs.NetworkNamespace),
Host: usernsOption.Host,
})
}
// If the user requested that we use the host namespace, but also that
// we use mappings, that's not going to work.
if (len(uidmap) != 0 || len(gidmap) != 0) && usernsOption.Host {
Expand Down Expand Up @@ -1055,12 +1048,14 @@ func parseIDMap(spec []string) (m [][3]uint32, err error) {
func NamespaceOptions(c *cobra.Command) (namespaceOptions define.NamespaceOptions, networkPolicy define.NetworkConfigurationPolicy, err error) {
options := make(define.NamespaceOptions, 0, 7)
policy := define.NetworkDefault
for _, what := range []string{string(specs.IPCNamespace), "network", string(specs.PIDNamespace), string(specs.UTSNamespace)} {
for _, what := range []string{"cgroupns", string(specs.IPCNamespace), "network", string(specs.PIDNamespace), string(specs.UTSNamespace)} {
if c.Flags().Lookup(what) != nil && c.Flag(what).Changed {
how := c.Flag(what).Value.String()
switch what {
case "network":
what = string(specs.NetworkNamespace)
case "cgroupns":
what = string(specs.CgroupNamespace)
}
switch how {
case "", "container", "private":
Expand Down
14 changes: 9 additions & 5 deletions run_linux.go
Original file line number Diff line number Diff line change
Expand Up @@ -2318,14 +2318,18 @@ func checkAndOverrideIsolationOptions(isolation define.Isolation, options *RunOp
// DefaultNamespaceOptions returns the default namespace settings from the
// runtime-tools generator library.
func DefaultNamespaceOptions() (define.NamespaceOptions, error) {
cfg, err := config.Default()
if err != nil {
return nil, errors.Wrapf(err, "failed to get container config")
}
options := define.NamespaceOptions{
{Name: string(specs.CgroupNamespace), Host: true},
{Name: string(specs.IPCNamespace), Host: true},
{Name: string(specs.CgroupNamespace), Host: cfg.CgroupNS() == "host"},
{Name: string(specs.IPCNamespace), Host: cfg.IPCNS() == "host"},
{Name: string(specs.MountNamespace), Host: true},
{Name: string(specs.NetworkNamespace), Host: true},
{Name: string(specs.PIDNamespace), Host: true},
{Name: string(specs.NetworkNamespace), Host: cfg.NetNS() == "host" || cfg.NetNS() == "container"},
{Name: string(specs.PIDNamespace), Host: cfg.PidNS() == "host"},
{Name: string(specs.UserNamespace), Host: true},
{Name: string(specs.UTSNamespace), Host: true},
{Name: string(specs.UTSNamespace), Host: cfg.UTSNS() == "host"},
}
g, err := generate.New("linux")
if err != nil {
Expand Down
19 changes: 16 additions & 3 deletions tests/bud.bats
Original file line number Diff line number Diff line change
Expand Up @@ -3100,14 +3100,13 @@ run cat /proc/self/cgroup
_EOF

# with cgroup-parent
run_buildah build --cgroup-parent test-cgroup -t with-flag \
run_buildah build --cgroupns=host --cgroup-parent test-cgroup -t with-flag \
--signature-policy ${TESTSDIR}/policy.json --file ${mytmpdir} .
if is_cgroupsv2; then
expect_output --from="${lines[2]}" "0::/test-cgroup"
else
expect_output --substring "/test-cgroup"
fi

# without cgroup-parent
run_buildah build -t without-flag \
--signature-policy ${TESTSDIR}/policy.json --file ${mytmpdir} .
Expand All @@ -3118,7 +3117,7 @@ _EOF

@test "bud with --cpu-period and --cpu-quota" {
skip_if_chroot
skip_if_rootless
skip_if_rootless_and_cgroupv1
skip_if_no_runtime

_prefetch alpine
Expand All @@ -3143,6 +3142,20 @@ _EOF
expect_output --from="${lines[2]}" "5678 1234"
}

@test "bud check mount /sys/fs/cgroup" {
skip_if_rootless_and_cgroupv1
mytmpdir=${TESTDIR}/my-dir
mkdir -p ${mytmpdir}

cat > $mytmpdir/Containerfile << _EOF
from alpine
run ls /sys/fs/cgroup
_EOF
run_buildah build --signature-policy ${TESTSDIR}/policy.json --file ${mytmpdir}/Containerfile .
expect_output --substring "cpu"
expect_output --substring "memory"
}

@test "bud with --cpu-shares" {
skip_if_chroot
skip_if_rootless
Expand Down
2 changes: 1 addition & 1 deletion tests/from.bats
Original file line number Diff line number Diff line change
Expand Up @@ -583,7 +583,7 @@ load helpers

_prefetch alpine
# with cgroup-parent
run_buildah from -q --cgroup-parent test-cgroup --signature-policy ${TESTSDIR}/policy.json alpine
run_buildah from -q --cgroupns=host --cgroup-parent test-cgroup --signature-policy ${TESTSDIR}/policy.json alpine
cid=$output
run_buildah run $cid /bin/sh -c 'cat /proc/$$/cgroup'
expect_output --substring "test-cgroup"
Expand Down
20 changes: 20 additions & 0 deletions tests/helpers.bash
Original file line number Diff line number Diff line change
Expand Up @@ -427,6 +427,17 @@ function skip_if_rootless() {
fi
}

##################################
# skip_if_rootless_and_cgroupv1 #
##################################
function skip_if_rootless_and_cgroupv1() {
if test "$BUILDAH_ISOLATION" = "rootless"; then
if !is_cgroupsv2; then
skip "${1:-test does not work when \$BUILDAH_ISOLATION = rootless} and not cgroupv2"
fi
fi
}

########################
# skip_if_no_runtime # 'buildah run' can't work without a runtime
########################
Expand Down Expand Up @@ -455,6 +466,15 @@ function skip_if_cgroupsv2() {
fi
}

#######################
# skip_if_cgroupsv1 # Some tests don't work with cgroupsv1
#######################
function skip_if_cgroupsv1() {
if !is_cgroupsv2; then
skip "${1:-test does not work with cgroups v1}"
fi
}

##########################
# skip_if_in_container #
##########################
Expand Down
41 changes: 23 additions & 18 deletions tests/namespaces.bats
Original file line number Diff line number Diff line change
Expand Up @@ -59,8 +59,7 @@ load helpers
run_buildah from --signature-policy ${TESTSDIR}/policy.json --quiet alpine
ctr="$output"

# Check that with settings that don't require a user namespace, we don't get a new network namespace by default.
run_buildah run $RUNOPTS "$ctr" readlink /proc/self/ns/net
run_buildah run $RUNOPTS --net=host "$ctr" readlink /proc/self/ns/net
expect_output "$mynetns"

# Check that with settings that don't require a user namespace, we can request to use a per-container network namespace.
Expand All @@ -71,6 +70,10 @@ load helpers
run_buildah run $RUNOPTS --net=private "$ctr" readlink /proc/self/ns/net
assert "$output" != "$mynetns" \
"[/proc/self/ns/net (--net=private) should not be '$mynetns']"

run_buildah run $RUNOPTS "$ctr" readlink /proc/self/ns/net
assert "$output" != "$mynetns" \
"[/proc/self/ns/net (--net="") should not be '$mynetns']"
}

# Helper for idmapping test: check UID or GID mapping
Expand Down Expand Up @@ -405,22 +408,24 @@ _EOF
for pid in host container private; do
for userns in host container private; do
for uts in host container private; do

if test $userns == private -o $userns == container -a $pid == host ; then
# We can't mount a fresh /proc, and OCI runtime won't let us bind mount the host's.
continue
fi

echo "buildah from --signature-policy ${TESTSDIR}/policy.json --ipc=$ipc --net=$net --pid=$pid --userns=$userns --uts=$uts alpine"
run_buildah from --signature-policy ${TESTSDIR}/policy.json --quiet --ipc=$ipc --net=$net --pid=$pid --userns=$userns --uts=$uts alpine
[ "$output" != "" ]
ctr="$output"
run_buildah run $ctr pwd
[ "$output" != "" ]
run_buildah run --tty=true $ctr pwd
[ "$output" != "" ]
run_buildah run --terminal=false $ctr pwd
[ "$output" != "" ]
for cgroupns in host container private; do

if test $userns == private -o $userns == container -a $pid == host ; then
# We can't mount a fresh /proc, and OCI runtime won't let us bind mount the host's.
continue
fi

echo "buildah from --signature-policy ${TESTSDIR}/policy.json --ipc=$ipc --net=$net --pid=$pid --userns=$userns --uts=$uts --cgroupns=$cgroupns alpine"
run_buildah from --signature-policy ${TESTSDIR}/policy.json --quiet --ipc=$ipc --net=$net --pid=$pid --userns=$userns --uts=$uts --cgroupns=$cgroupns alpine
[ "$output" != "" ]
ctr="$output"
run_buildah run $ctr pwd
[ "$output" != "" ]
run_buildah run --tty=true $ctr pwd
[ "$output" != "" ]
run_buildah run --terminal=false $ctr pwd
[ "$output" != "" ]
done
done
done
done
Expand Down

0 comments on commit 6d01253

Please sign in to comment.