Implement to set a domainname

opencontainers/runtime-spec#1156

Signed-off-by: utam0k <k0ma@utam0k.jp>
This commit is contained in:
utam0k
2022-10-04 20:45:50 +09:00
parent 11983894a8
commit d9230602e9
7 changed files with 65 additions and 5 deletions

View File

@@ -119,6 +119,9 @@ type Config struct {
// Hostname optionally sets the container's hostname if provided
Hostname string `json:"hostname"`
// Domainname optionally sets the container's domainname if provided
Domainname string `json:"domainname"`
// Namespaces specifies the container's namespaces that it should setup when cloning the init process
// If a namespace is not provided that namespace is shared from the container's parent process
Namespaces Namespaces `json:"namespaces"`

View File

@@ -23,7 +23,7 @@ func Validate(config *configs.Config) error {
cgroupsCheck,
rootfs,
network,
hostname,
uts,
security,
namespaces,
sysctl,
@@ -75,10 +75,13 @@ func network(config *configs.Config) error {
return nil
}
func hostname(config *configs.Config) error {
func uts(config *configs.Config) error {
if config.Hostname != "" && !config.Namespaces.Contains(configs.NEWUTS) {
return errors.New("unable to set hostname without a private UTS namespace")
}
if config.Domainname != "" && !config.Namespaces.Contains(configs.NEWUTS) {
return errors.New("unable to set domainname without a private UTS namespace")
}
return nil
}

View File

@@ -82,7 +82,25 @@ func TestValidateHostname(t *testing.T) {
}
}
func TestValidateHostnameWithoutUTSNamespace(t *testing.T) {
func TestValidateUTS(t *testing.T) {
config := &configs.Config{
Rootfs: "/var",
Domainname: "runc",
Hostname: "runc",
Namespaces: configs.Namespaces(
[]configs.Namespace{
{Type: configs.NEWUTS},
},
),
}
err := Validate(config)
if err != nil {
t.Errorf("Expected error to not occur: %+v", err)
}
}
func TestValidateUTSWithoutUTSNamespace(t *testing.T) {
config := &configs.Config{
Rootfs: "/var",
Hostname: "runc",
@@ -92,6 +110,16 @@ func TestValidateHostnameWithoutUTSNamespace(t *testing.T) {
if err == nil {
t.Error("Expected error to occur but it was nil")
}
config = &configs.Config{
Rootfs: "/var",
Domainname: "runc",
}
err = Validate(config)
if err == nil {
t.Error("Expected error to occur but it was nil")
}
}
func TestValidateSecurityWithMaskPaths(t *testing.T) {

View File

@@ -129,8 +129,9 @@ func newTemplateConfig(t *testing.T, p *tParam) *configs.Config {
ReadonlyPaths: []string{
"/proc/sys", "/proc/sysrq-trigger", "/proc/irq", "/proc/bus",
},
Devices: specconv.AllowedDevices,
Hostname: "integration",
Devices: specconv.AllowedDevices,
Hostname: "integration",
Domainname: "integration",
Mounts: []*configs.Mount{
{
Source: "proc",

View File

@@ -353,6 +353,7 @@ func CreateLibcontainerConfig(opts *CreateOpts) (*configs.Config, error) {
NoPivotRoot: opts.NoPivotRoot,
Readonlyfs: spec.Root.Readonly,
Hostname: spec.Hostname,
Domainname: spec.Domainname,
Labels: append(labels, "bundle="+cwd),
NoNewKeyring: opts.NoNewKeyring,
RootlessEUID: opts.RootlessEUID,

View File

@@ -126,6 +126,11 @@ func (l *linuxStandardInit) Init() error {
return &os.SyscallError{Syscall: "sethostname", Err: err}
}
}
if domainname := l.config.Config.Domainname; domainname != "" {
if err := unix.Setdomainname([]byte(domainname)); err != nil {
return &os.SyscallError{Syscall: "setdomainname", Err: err}
}
}
if err := apparmor.ApplyProfile(l.config.AppArmorProfile); err != nil {
return fmt.Errorf("unable to apply apparmor profile: %w", err)
}

View File

@@ -57,3 +57,22 @@ function teardown() {
runc state test_run_keep
[ "$status" -ne 0 ]
}
@test "runc run [hostname domainname]" {
update_config ' .process.args |= ["sh"]
| .hostname = "myhostname"
| .domainname= "mydomainname"'
runc run -d --console-socket "$CONSOLE_SOCKET" test_utc
[ "$status" -eq 0 ]
# test hostname
runc exec test_utc hostname
[ "$status" -eq 0 ]
[[ "${lines[0]}" == *'myhostname'* ]]
# test domainname
runc exec test_utc cat /proc/sys/kernel/domainname
[ "$status" -eq 0 ]
[[ "${lines[0]}" == *'mydomainname'* ]]
}