Skip to content

Commit 72e2bf4

Browse files
committed
Support the containers.conf container_name_as_hostname option
When containers.conf has the "container_name_as_hostname" option set, use that value, with values that don't fit `[A-Za-z0-9][A-Za-z0-9.-]+` stripped out. Signed-off-by: Nalin Dahyabhai <[email protected]>
1 parent 5dc3c23 commit 72e2bf4

File tree

5 files changed

+94
-2
lines changed

5 files changed

+94
-2
lines changed

run_common.go

+23
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@ import (
4747
"github.com/containers/storage/pkg/lockfile"
4848
"github.com/containers/storage/pkg/mount"
4949
"github.com/containers/storage/pkg/reexec"
50+
"github.com/containers/storage/pkg/regexp"
5051
"github.com/containers/storage/pkg/unshare"
5152
"github.com/opencontainers/go-digest"
5253
"github.com/opencontainers/runtime-spec/specs-go"
@@ -57,6 +58,10 @@ import (
5758
"golang.org/x/term"
5859
)
5960

61+
const maxHostnameLen = 64
62+
63+
var validHostnames = regexp.Delayed("[A-Za-z0-9][A-Za-z0-9.-]+")
64+
6065
func (b *Builder) createResolvConf(rdir string, chownOpts *idtools.IDPair) (string, error) {
6166
cfile := filepath.Join(rdir, "resolv.conf")
6267
f, err := os.Create(cfile)
@@ -2092,3 +2097,21 @@ func relabel(path, mountLabel string, shared bool) error {
20922097
}
20932098
return nil
20942099
}
2100+
2101+
// mapContainerNameToHostname returns the passed-in string with characters that
2102+
// don't match validHostnames (defined above) stripped out.
2103+
func mapContainerNameToHostname(containerName string) string {
2104+
match := validHostnames.FindStringIndex(containerName)
2105+
if match == nil {
2106+
return ""
2107+
}
2108+
trimmed := containerName[match[0]:]
2109+
match[1] -= match[0]
2110+
match[0] = 0
2111+
for match[1] != len(trimmed) && match[1] < match[0]+maxHostnameLen {
2112+
trimmed = trimmed[:match[1]] + trimmed[match[1]+1:]
2113+
match = validHostnames.FindStringIndex(trimmed)
2114+
match[1] = min(match[1], maxHostnameLen)
2115+
}
2116+
return trimmed[:match[1]]
2117+
}

run_common_test.go

+31
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
package buildah
2+
3+
import (
4+
"testing"
5+
6+
"github.com/stretchr/testify/assert"
7+
)
8+
9+
func TestMapContainerNameToHostname(t *testing.T) {
10+
cases := [][2]string{
11+
{"trivial", "trivial"},
12+
{"Nottrivial", "Nottrivial"},
13+
{"0Nottrivial", "0Nottrivial"},
14+
{"0Nottrivi-al", "0Nottrivi-al"},
15+
{"-0Nottrivi-al", "0Nottrivi-al"},
16+
{".-0Nottrivi-.al", "0Nottrivi-.al"},
17+
{".-0Nottrivi-.al0123456789", "0Nottrivi-.al0123456789"},
18+
{".-0Nottrivi-.al0123456789+0123456789", "0Nottrivi-.al01234567890123456789"},
19+
{".-0Nottrivi-.al0123456789+0123456789/0123456789", "0Nottrivi-.al012345678901234567890123456789"},
20+
{".-0Nottrivi-.al0123456789+0123456789/0123456789%0123456789", "0Nottrivi-.al0123456789012345678901234567890123456789"},
21+
{".-0Nottrivi-.al0123456789+0123456789/0123456789%0123456789_0123456789", "0Nottrivi-.al01234567890123456789012345678901234567890123456789"},
22+
{".-0Nottrivi-.al0123456789+0123456789/0123456789%0123456789_0123456789:0123456", "0Nottrivi-.al012345678901234567890123456789012345678901234567890"},
23+
{".-0Nottrivi-.al0123456789+0123456789/0123456789%0123456789_0123456789:0123456789", "0Nottrivi-.al012345678901234567890123456789012345678901234567890"},
24+
}
25+
for i := range cases {
26+
t.Run(cases[i][0], func(t *testing.T) {
27+
sanitized := mapContainerNameToHostname(cases[i][0])
28+
assert.Equalf(t, cases[i][1], sanitized, "mapping container name %q to a valid hostname", cases[i][0])
29+
})
30+
}
31+
}

run_freebsd.go

+11-1
Original file line numberDiff line numberDiff line change
@@ -586,7 +586,17 @@ func (b *Builder) configureNamespaces(g *generate.Generator, options *RunOptions
586586
} else if b.Hostname() != "" {
587587
g.SetHostname(b.Hostname())
588588
} else {
589-
g.SetHostname(stringid.TruncateID(b.ContainerID))
589+
hostname := stringid.TruncateID(b.ContainerID)
590+
defConfig, err := config.Default()
591+
if err != nil {
592+
return false, "", fmt.Errorf("failed to get container config: %w", err)
593+
}
594+
if defConfig.Containers.ContainerNameAsHostName {
595+
if mapped := mapContainerNameToHostname(b.Container); mapped != "" {
596+
hostname = mapped
597+
}
598+
}
599+
g.SetHostname(hostname)
590600
}
591601
} else {
592602
g.SetHostname("")

run_linux.go

+11-1
Original file line numberDiff line numberDiff line change
@@ -991,7 +991,17 @@ func (b *Builder) configureNamespaces(g *generate.Generator, options *RunOptions
991991
} else if b.Hostname() != "" {
992992
g.SetHostname(b.Hostname())
993993
} else {
994-
g.SetHostname(stringid.TruncateID(b.ContainerID))
994+
hostname := stringid.TruncateID(b.ContainerID)
995+
defConfig, err := config.Default()
996+
if err != nil {
997+
return false, "", fmt.Errorf("failed to get container config: %w", err)
998+
}
999+
if defConfig.Containers.ContainerNameAsHostName {
1000+
if mapped := mapContainerNameToHostname(b.Container); mapped != "" {
1001+
hostname = mapped
1002+
}
1003+
}
1004+
g.SetHostname(hostname)
9951005
}
9961006
} else {
9971007
g.SetHostname("")

tests/run.bats

+18
Original file line numberDiff line numberDiff line change
@@ -997,3 +997,21 @@ _EOF
997997
run_buildah ? bud --pull=false --layers .
998998
expect_output --substring -- "-c requires an argument"
999999
}
1000+
1001+
@test "container_name_as_hostname" {
1002+
skip_if_no_runtime
1003+
1004+
_prefetch alpine
1005+
echo '[containers]' > ${TEST_SCRATCH_DIR}/containers.conf
1006+
echo container_name_as_hostname = true >> ${TEST_SCRATCH_DIR}/containers.conf
1007+
name=alpine-working_containeR-4-test
1008+
sanitizedname=alpine-workingcontaineR-4-test
1009+
run_buildah from --name :"$name": --cidfile ${TEST_SCRATCH_DIR}/cid alpine
1010+
cname="$output"
1011+
run_buildah run "$cname" hostname
1012+
assert "$output" = $(cut -c1-12 < ${TEST_SCRATCH_DIR}/cid)
1013+
CONTAINERS_CONF=${TEST_SCRATCH_DIR}/containers.conf run_buildah run "$cname" hostname
1014+
expect_output "$sanitizedname"
1015+
CONTAINERS_CONF=${TEST_SCRATCH_DIR}/containers.conf run_buildah run "$(cat ${TEST_SCRATCH_DIR}/cid)" hostname
1016+
expect_output "$sanitizedname"
1017+
}

0 commit comments

Comments
 (0)