mirror of
https://github.com/containers/podman.git
synced 2025-05-20 08:36:23 +08:00
Merge pull request #24675 from gtjoseph/main-pass-hostname-to-netavark
Pass container hostname to netavark
This commit is contained in:
@ -666,8 +666,12 @@ func (c *Container) RuntimeName() string {
|
||||
// Runtime spec accessors
|
||||
// Unlocked
|
||||
|
||||
// Hostname gets the container's hostname
|
||||
func (c *Container) Hostname() string {
|
||||
// hostname determines the container's hostname.
|
||||
// If 'network' is true and the container isn't running in a
|
||||
// private UTS namespoace, an empty string will be returned
|
||||
// instead of the host's hostname because we never want to
|
||||
// send the host's hostname to a DHCP or DNS server.
|
||||
func (c *Container) hostname(network bool) string {
|
||||
if c.config.UTSNsCtr != "" {
|
||||
utsNsCtr, err := c.runtime.GetContainer(c.config.UTSNsCtr)
|
||||
if err != nil {
|
||||
@ -677,25 +681,66 @@ func (c *Container) Hostname() string {
|
||||
}
|
||||
return utsNsCtr.Hostname()
|
||||
}
|
||||
|
||||
if c.config.Spec.Hostname != "" {
|
||||
return c.config.Spec.Hostname
|
||||
}
|
||||
|
||||
// if the container is not running in a private UTS namespace,
|
||||
// return the host's hostname.
|
||||
// If the container is not running in a private UTS namespace,
|
||||
// return the host's hostname unless 'network' is true in which
|
||||
// case we return an empty string.
|
||||
privateUTS := c.hasPrivateUTS()
|
||||
if !privateUTS {
|
||||
hostname, err := os.Hostname()
|
||||
if err == nil {
|
||||
if network {
|
||||
return ""
|
||||
}
|
||||
return hostname
|
||||
}
|
||||
logrus.Errorf("unable to get host's hostname for container %s: %v", c.ID(), err)
|
||||
return ""
|
||||
}
|
||||
|
||||
// If container_name_as_hostname is set in the CONTAINERS table in
|
||||
// containers.conf, use a sanitized version of the container's name
|
||||
// as the hostname. Since the container name must already match
|
||||
// the set '[a-zA-Z0-9][a-zA-Z0-9_.-]*', we can just remove any
|
||||
// underscores and limit it to 253 characters to make it a valid
|
||||
// hostname.
|
||||
if c.runtime.config.Containers.ContainerNameAsHostName {
|
||||
sanitizedHostname := strings.ReplaceAll(c.Name(), "_", "")
|
||||
if len(sanitizedHostname) <= 253 {
|
||||
return sanitizedHostname
|
||||
}
|
||||
return sanitizedHostname[:253]
|
||||
}
|
||||
|
||||
// Otherwise use the container's short ID as the hostname.
|
||||
if len(c.ID()) < 11 {
|
||||
return c.ID()
|
||||
}
|
||||
return c.ID()[:12]
|
||||
}
|
||||
|
||||
// Hostname gets the container's hostname
|
||||
func (c *Container) Hostname() string {
|
||||
return c.hostname(false)
|
||||
}
|
||||
|
||||
// If the container isn't running in a private UTS namespace, Hostname()
|
||||
// will return the host's hostname as the container's hostname. If netavark
|
||||
// were to try and obtain a DHCP lease with the host's hostname in an environment
|
||||
// where DDNS was active, bad things could happen. NetworkHostname() on the
|
||||
// other hand, will return an empty string if the container isn't running
|
||||
// in a private UTS namespace.
|
||||
//
|
||||
// This function should only be used to populate the ContainerHostname member
|
||||
// of the common.libnetwork.types.NetworkOptions struct.
|
||||
func (c *Container) NetworkHostname() string {
|
||||
return c.hostname(true)
|
||||
}
|
||||
|
||||
// WorkingDir returns the containers working dir
|
||||
func (c *Container) WorkingDir() string {
|
||||
if c.config.Spec.Process != nil {
|
||||
|
@ -58,6 +58,7 @@ func (c *Container) getNetworkOptions(networkOpts map[string]types.PerNetworkOpt
|
||||
ContainerID: c.config.ID,
|
||||
ContainerName: getNetworkPodName(c),
|
||||
DNSServers: nameservers,
|
||||
ContainerHostname: c.NetworkHostname(),
|
||||
}
|
||||
opts.PortMappings = c.convertPortMappings()
|
||||
|
||||
|
@ -763,4 +763,109 @@ var _ = Describe("Verify podman containers.conf usage", func() {
|
||||
Expect(inspect.OutputToString()).Should(Equal(mode))
|
||||
}
|
||||
})
|
||||
|
||||
startContainer := func(params ...string) string {
|
||||
args := []string{"create"}
|
||||
for _, param := range params {
|
||||
if param == "--name" {
|
||||
args = append(args, "--replace")
|
||||
break
|
||||
}
|
||||
}
|
||||
args = append(args, params...)
|
||||
args = append(args, ALPINE, "true")
|
||||
|
||||
result := podmanTest.Podman(args)
|
||||
result.WaitWithDefaultTimeout()
|
||||
Expect(result).Should(ExitCleanly())
|
||||
containerID := result.OutputToString()
|
||||
|
||||
return containerID
|
||||
}
|
||||
|
||||
getContainerConfig := func(containerID string, formatParam string) string {
|
||||
inspect := podmanTest.Podman([]string{"inspect", "--format", formatParam, containerID})
|
||||
inspect.WaitWithDefaultTimeout()
|
||||
value := inspect.OutputToString()
|
||||
return value
|
||||
}
|
||||
|
||||
It("podman containers.conf container_name_as_hostname", func() {
|
||||
|
||||
// With default containers.conf
|
||||
|
||||
// Start container with no options
|
||||
containerID := startContainer()
|
||||
hostname := getContainerConfig(containerID, "{{ .Config.Hostname }}")
|
||||
// Hostname should be the first 12 characters of the containerID
|
||||
Expect(hostname).To(Equal(containerID[:12]))
|
||||
|
||||
// Start container with name
|
||||
containerID = startContainer("--name", "cname1")
|
||||
hostname = getContainerConfig(containerID, "{{ .Config.Hostname }}")
|
||||
// Hostname should still be the first 12 characters of the containerID
|
||||
Expect(hostname).To(Equal(containerID[:12]))
|
||||
|
||||
// Start container with just hostname
|
||||
containerID = startContainer("--hostname", "cname1.dev")
|
||||
hostname = getContainerConfig(containerID, "{{ .Config.Hostname }}")
|
||||
// Hostname should now be "cname1.dev"
|
||||
Expect(hostname).To(Equal("cname1.dev"))
|
||||
|
||||
// Start container with name and hostname
|
||||
containerID = startContainer("--name", "cname1", "--hostname", "cname1.dev")
|
||||
hostname = getContainerConfig(containerID, "{{ .Config.Hostname }}")
|
||||
// Hostname should now be "cname1.dev"
|
||||
Expect(hostname).To(Equal("cname1.dev"))
|
||||
|
||||
// Create containers.conf override with container_name_as_hostname=true
|
||||
conffile := filepath.Join(podmanTest.TempDir, "container.conf")
|
||||
err := os.WriteFile(conffile, []byte("[containers]\ncontainer_name_as_hostname=true\n"), 0755)
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
os.Setenv("CONTAINERS_CONF_OVERRIDE", conffile)
|
||||
if IsRemote() {
|
||||
podmanTest.RestartRemoteService()
|
||||
}
|
||||
|
||||
// Start container with no options
|
||||
containerID = startContainer()
|
||||
hostname = getContainerConfig(containerID, "{{ .Config.Hostname }}")
|
||||
name := getContainerConfig(containerID, "{{ .Name }}")
|
||||
// Hostname should be the auto generated container name with '_' removed
|
||||
Expect(hostname).To(Equal(strings.ReplaceAll(name, "_", "")))
|
||||
|
||||
// Start container with name
|
||||
containerID = startContainer("--name", "cname1")
|
||||
hostname = getContainerConfig(containerID, "{{ .Config.Hostname }}")
|
||||
// Hostname should be the container name
|
||||
Expect(hostname).To(Equal("cname1"))
|
||||
|
||||
// Start container with name containing '_'
|
||||
containerID = startContainer("--name", "cname1_2_3")
|
||||
hostname = getContainerConfig(containerID, "{{ .Config.Hostname }}")
|
||||
// Hostname should be the set container name with all '_' removed
|
||||
Expect(hostname).To(Equal("cname123"))
|
||||
|
||||
// Start container with just hostname
|
||||
containerID = startContainer("--hostname", "cname1.dev")
|
||||
hostname = getContainerConfig(containerID, "{{ .Config.Hostname }}")
|
||||
// Hostname should now be "cname1.dev"
|
||||
Expect(hostname).To(Equal("cname1.dev"))
|
||||
|
||||
// Start container with name and hostname
|
||||
containerID = startContainer("--name", "cname1", "--hostname", "cname1.dev")
|
||||
hostname = getContainerConfig(containerID, "{{ .Config.Hostname }}")
|
||||
// Hostname should still be "cname1.dev"
|
||||
Expect(hostname).To(Equal("cname1.dev"))
|
||||
|
||||
// Start container with name = 260 characters
|
||||
longHostname := "cnabcdefghijklmnopqrstuvwxyz1234567890.abcdefghijklmnopqrstuvwxyz1234567890.abcdefghijklmnopqrstuvwxyz1234567890.abcdefghijklmnopqrstuvwxyz1234567890.abcdefghijklmnopqrstuvwxyz1234567890.abcdefghijklmnopqrstuvwxyz1234567890.abcdefghijklmnopqrstuvwxyz1234567890"
|
||||
containerID = startContainer("--name", longHostname)
|
||||
hostname = getContainerConfig(containerID, "{{ .Config.Hostname }}")
|
||||
name = getContainerConfig(containerID, "{{ .Name }}")
|
||||
// Double check that name actually got set correctly
|
||||
Expect(name).To(Equal(longHostname))
|
||||
// Hostname should be the container name truncated to 253 characters
|
||||
Expect(hostname).To(Equal(name[:253]))
|
||||
})
|
||||
})
|
||||
|
Reference in New Issue
Block a user