Skip to content

Commit

Permalink
Merge pull request #21062 from gavinkflam/base-hosts-file-flag
Browse files Browse the repository at this point in the history
Add --hosts-file flag; Add nohosts to remote build APIs
  • Loading branch information
openshift-merge-bot[bot] authored Nov 25, 2024
2 parents aba98ad + 4f7395f commit 70c2559
Show file tree
Hide file tree
Showing 28 changed files with 440 additions and 18 deletions.
7 changes: 7 additions & 0 deletions cmd/podman/common/completion.go
Original file line number Diff line number Diff line change
Expand Up @@ -716,6 +716,13 @@ func AutocompleteNetworks(cmd *cobra.Command, args []string, toComplete string)
return getNetworks(cmd, toComplete, completeDefault)
}

// AutocompleteHostsFile - Autocomplete hosts file options.
// -> "image", "none", paths
func AutocompleteHostsFile(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) {
hostsFileModes := []string{"image", "none"}
return hostsFileModes, cobra.ShellCompDirectiveDefault
}

// AutocompleteDefaultOneArg - Autocomplete path only for the first argument.
func AutocompleteDefaultOneArg(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) {
if len(args) == 0 {
Expand Down
14 changes: 14 additions & 0 deletions cmd/podman/common/netflags.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,13 @@ func DefineNetFlags(cmd *cobra.Command) {
)
_ = cmd.RegisterFlagCompletionFunc(addHostFlagName, completion.AutocompleteNone)

hostsFileFlagName := "hosts-file"
netFlags.String(
hostsFileFlagName, "",
`Base file to create the /etc/hosts file inside the container, or one of the special values. ("image"|"none")`,
)
_ = cmd.RegisterFlagCompletionFunc(hostsFileFlagName, AutocompleteHostsFile)

dnsFlagName := "dns"
netFlags.StringSlice(
dnsFlagName, podmanConfig.ContainersConf.DNSServers(),
Expand Down Expand Up @@ -116,6 +123,13 @@ func NetFlagsToNetOptions(opts *entities.NetOptions, flags pflag.FlagSet) (*enti
}
}

if flags.Changed("hosts-file") {
opts.HostsFile, err = flags.GetString("hosts-file")
if err != nil {
return nil, err
}
}

if flags.Changed("dns") {
servers, err := flags.GetStringSlice("dns")
if err != nil {
Expand Down
3 changes: 3 additions & 0 deletions cmd/podman/containers/create.go
Original file line number Diff line number Diff line change
Expand Up @@ -323,6 +323,9 @@ func CreateInit(c *cobra.Command, vals entities.ContainerCreateOptions, isInfra
if noHosts && c.Flag("add-host").Changed {
return vals, errors.New("--no-hosts and --add-host cannot be set together")
}
if noHosts && c.Flag("hosts-file").Changed {
return vals, errors.New("--no-hosts and --hosts-file cannot be set together")
}

if !isInfra && c.Flag("entrypoint").Changed {
val := c.Flag("entrypoint").Value.String()
Expand Down
1 change: 1 addition & 0 deletions cmd/podman/pods/create.go
Original file line number Diff line number Diff line change
Expand Up @@ -265,6 +265,7 @@ func create(cmd *cobra.Command, args []string) error {
}
podSpec.InfraContainerSpec = specgen.NewSpecGenerator(imageName, false)
podSpec.InfraContainerSpec.RawImageName = rawImageName
podSpec.InfraContainerSpec.BaseHostsFile = podSpec.PodNetworkConfig.HostsFile
podSpec.InfraContainerSpec.NetworkOptions = podSpec.NetworkOptions
podSpec.InfraContainerSpec.RestartPolicy = podSpec.RestartPolicy
err = specgenutil.FillOutSpecGen(podSpec.InfraContainerSpec, &infraOptions, []string{})
Expand Down
12 changes: 12 additions & 0 deletions docs/source/markdown/options/hosts-file.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
####> This option file is used in:
####> podman create, pod create, run
####> If file is edited, make sure the changes
####> are applicable to all of those.
#### **--hosts-file**=*path* | *none* | *image*

Base file to create the `/etc/hosts` file inside the container. This must either
be an absolute path to a file on the host system, or one of the following
special flags:
"" Follow the `base_hosts_file` configuration in _containers.conf_ (the default)
`none` Do not use a base file (i.e. start with an empty file)
`image` Use the container image's `/etc/hosts` file as base file
2 changes: 2 additions & 0 deletions docs/source/markdown/podman-create.1.md.in
Original file line number Diff line number Diff line change
Expand Up @@ -199,6 +199,8 @@ Print usage statement

@@option hostname.container

@@option hosts-file

@@option hostuser

@@option http-proxy
Expand Down
2 changes: 2 additions & 0 deletions docs/source/markdown/podman-pod-create.1.md.in
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,8 @@ Print usage statement.

@@option hostname.pod

@@option hosts-file

#### **--infra**

Create an infra container and associate it with the pod. An infra container is a lightweight container used to coordinate the shared kernel namespace of a pod. Default: true.
Expand Down
2 changes: 2 additions & 0 deletions docs/source/markdown/podman-run.1.md.in
Original file line number Diff line number Diff line change
Expand Up @@ -233,6 +233,8 @@ Print usage statement

@@option hostname.container

@@option hosts-file

@@option hostuser

@@option http-proxy
Expand Down
9 changes: 4 additions & 5 deletions libpod/container_config.go
Original file line number Diff line number Diff line change
Expand Up @@ -290,11 +290,10 @@ type ContainerNetworkConfig struct {
// bind-mounted inside the container.
// Conflicts with HostAdd.
UseImageHosts bool
// BaseHostsFile is the path to a hosts file, the entries from this file
// are added to the containers hosts file. As special value "image" is
// allowed which uses the /etc/hosts file from within the image and "none"
// which uses no base file at all. If it is empty we should default
// to the base_hosts_file configuration in containers.conf.
// BaseHostsFile is the base file to create the `/etc/hosts` file inside the container.
// This must either be an absolute path to a file on the host system, or one of the
// special flags `image` or `none`.
// If it is empty it defaults to the base_hosts_file configuration in containers.conf.
BaseHostsFile string `json:"baseHostsFile,omitempty"`
// Hosts to add in container
// Will be appended to host's host file
Expand Down
2 changes: 2 additions & 0 deletions libpod/container_inspect.go
Original file line number Diff line number Diff line change
Expand Up @@ -543,6 +543,8 @@ func (c *Container) generateInspectContainerHostConfig(ctrSpec *spec.Spec, named
hostConfig.GroupAdd = make([]string, 0, len(c.config.Groups))
hostConfig.GroupAdd = append(hostConfig.GroupAdd, c.config.Groups...)

hostConfig.HostsFile = c.config.BaseHostsFile

if ctrSpec.Process != nil {
if ctrSpec.Process.OOMScoreAdj != nil {
hostConfig.OomScoreAdj = *ctrSpec.Process.OOMScoreAdj
Expand Down
2 changes: 2 additions & 0 deletions libpod/define/container_inspect.go
Original file line number Diff line number Diff line change
Expand Up @@ -443,6 +443,8 @@ type InspectContainerHostConfig struct {
// ExtraHosts contains hosts that will be added to the container's
// /etc/hosts.
ExtraHosts []string `json:"ExtraHosts"`
// HostsFile is the base file to create the `/etc/hosts` file inside the container.
HostsFile string `json:"HostsFile"`
// GroupAdd contains groups that the user inside the container will be
// added to.
GroupAdd []string `json:"GroupAdd"`
Expand Down
3 changes: 3 additions & 0 deletions libpod/define/pod_inspect.go
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,9 @@ type InspectPodInfraConfig struct {
// HostAdd adds a number of hosts to the infra container's resolv.conf
// which will be shared with the rest of the pod.
HostAdd []string
// HostsFile is the base file to create the `/etc/hosts` file inside the infra container
// which will be shared with the rest of the pod.
HostsFile string
// Networks is a list of networks the pod will join.
Networks []string
// NetworkOptions are additional options for each network
Expand Down
3 changes: 3 additions & 0 deletions libpod/pod_api.go
Original file line number Diff line number Diff line change
Expand Up @@ -709,6 +709,9 @@ func (p *Pod) Inspect() (*define.InspectPodData, error) {
infraConfig.HostAdd = make([]string, 0, len(infra.config.HostAdd))
infraConfig.HostAdd = append(infraConfig.HostAdd, infra.config.HostAdd...)
}
if len(infra.config.BaseHostsFile) > 0 {
infraConfig.HostsFile = infra.config.BaseHostsFile
}

networks, err := infra.networks()
if err != nil {
Expand Down
2 changes: 2 additions & 0 deletions pkg/api/handlers/compat/images_build.go
Original file line number Diff line number Diff line change
Expand Up @@ -142,6 +142,7 @@ func BuildImage(w http.ResponseWriter, r *http.Request) {
Memory int64 `schema:"memory"`
NamespaceOptions string `schema:"nsoptions"`
NoCache bool `schema:"nocache"`
NoHosts bool `schema:"nohosts"`
OmitHistory bool `schema:"omithistory"`
OSFeatures []string `schema:"osfeature"`
OSVersion string `schema:"osversion"`
Expand Down Expand Up @@ -720,6 +721,7 @@ func BuildImage(w http.ResponseWriter, r *http.Request) {
LabelOpts: labelOpts,
Memory: query.Memory,
MemorySwap: query.MemSwap,
NoHosts: query.NoHosts,
OmitHistory: query.OmitHistory,
SeccompProfilePath: seccomp,
ShmSize: strconv.Itoa(query.ShmSize),
Expand Down
12 changes: 12 additions & 0 deletions pkg/api/server/register_images.go
Original file line number Diff line number Diff line change
Expand Up @@ -523,6 +523,12 @@ func (s *APIServer) registerImagesHandlers(r *mux.Router) error {
// TBD Extra hosts to add to /etc/hosts
// (As of version 1.xx)
// - in: query
// name: nohosts
// type: boolean
// default:
// description: |
// Not to create /etc/hosts when building the image
// - in: query
// name: remote
// type: string
// default:
Expand Down Expand Up @@ -1502,6 +1508,12 @@ func (s *APIServer) registerImagesHandlers(r *mux.Router) error {
// TBD Extra hosts to add to /etc/hosts
// (As of version 1.xx)
// - in: query
// name: nohosts
// type: boolean
// default:
// description: |
// Not to create /etc/hosts when building the image
// - in: query
// name: remote
// type: string
// default:
Expand Down
3 changes: 3 additions & 0 deletions pkg/bindings/images/build.go
Original file line number Diff line number Diff line change
Expand Up @@ -335,6 +335,9 @@ func Build(ctx context.Context, containerFiles []string, options types.BuildOpti
if options.NoCache {
params.Set("nocache", "1")
}
if options.CommonBuildOpts.NoHosts {
params.Set("nohosts", "1")
}
if t := options.Output; len(t) > 0 {
params.Set("output", t)
}
Expand Down
1 change: 1 addition & 0 deletions pkg/domain/entities/pods.go
Original file line number Diff line number Diff line change
Expand Up @@ -368,6 +368,7 @@ func ToPodSpecGen(s specgen.PodSpecGenerator, p *PodCreateOptions) (*specgen.Pod
s.DNSOption = p.Net.DNSOptions
s.NoManageHosts = p.Net.NoHosts
s.HostAdd = p.Net.AddHosts
s.HostsFile = p.Net.HostsFile
}

// Cgroup
Expand Down
1 change: 1 addition & 0 deletions pkg/domain/entities/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ type NetOptions struct {
DNSOptions []string `json:"dns_option,omitempty"`
DNSSearch []string `json:"dns_search,omitempty"`
DNSServers []net.IP `json:"dns_server,omitempty"`
HostsFile string `json:"hosts_file,omitempty"`
Network specgen.Namespace `json:"netns,omitempty"`
NoHosts bool `json:"no_manage_hosts,omitempty"`
PublishPorts []types.PortMapping `json:"portmappings,omitempty"`
Expand Down
3 changes: 3 additions & 0 deletions pkg/specgen/generate/pod_create.go
Original file line number Diff line number Diff line change
Expand Up @@ -243,6 +243,9 @@ func MapSpec(p *specgen.PodSpecGenerator) (*specgen.SpecGenerator, error) {
if len(p.HostAdd) > 0 {
spec.HostAdd = p.HostAdd
}
if len(p.HostsFile) > 0 {
spec.BaseHostsFile = p.HostsFile
}
if len(p.DNSServer) > 0 {
var dnsServers []net.IP
dnsServers = append(dnsServers, p.DNSServer...)
Expand Down
12 changes: 10 additions & 2 deletions pkg/specgen/pod_validate.go
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,9 @@ func (p *PodSpecGenerator) Validate() error {
if len(p.HostAdd) > 0 {
return exclusivePodOptions("NoInfra", "HostAdd")
}
if len(p.HostsFile) > 0 {
return exclusivePodOptions("NoInfra", "HostsFile")
}
if p.NoManageResolvConf {
return exclusivePodOptions("NoInfra", "NoManageResolvConf")
}
Expand All @@ -79,8 +82,13 @@ func (p *PodSpecGenerator) Validate() error {
return exclusivePodOptions("NoManageResolvConf", "DNSOption")
}
}
if p.NoManageHosts && len(p.HostAdd) > 0 {
return exclusivePodOptions("NoManageHosts", "HostAdd")
if p.NoManageHosts {
if len(p.HostAdd) > 0 {
return exclusivePodOptions("NoManageHosts", "HostAdd")
}
if len(p.HostsFile) > 0 {
return exclusivePodOptions("NoManageHosts", "HostsFile")
}
}

return nil
Expand Down
7 changes: 7 additions & 0 deletions pkg/specgen/podspecgen.go
Original file line number Diff line number Diff line change
Expand Up @@ -170,6 +170,13 @@ type PodNetworkConfig struct {
// Conflicts with NoInfra=true and NoManageHosts.
// Optional.
HostAdd []string `json:"hostadd,omitempty"`
// HostsFile is the base file to create the `/etc/hosts` file inside the infra container.
// This must either be an absolute path to a file on the host system, or one of the
// special flags `image` or `none`.
// If it is empty it defaults to the base_hosts_file configuration in containers.conf.
// Conflicts with NoInfra=true and NoManageHosts.
// Optional.
HostsFile string `json:"hostsFile,omitempty"`
// NetworkOptions are additional options for each network
// Optional.
NetworkOptions map[string][]string `json:"network_options,omitempty"`
Expand Down
9 changes: 4 additions & 5 deletions pkg/specgen/specgen.go
Original file line number Diff line number Diff line change
Expand Up @@ -539,11 +539,10 @@ type ContainerNetworkConfig struct {
// Conflicts with HostAdd.
// Optional.
UseImageHosts *bool `json:"use_image_hosts,omitempty"`
// BaseHostsFile is the path to a hosts file, the entries from this file
// are added to the containers hosts file. As special value "image" is
// allowed which uses the /etc/hosts file from within the image and "none"
// which uses no base file at all. If it is empty we should default
// to the base_hosts_file configuration in containers.conf.
// BaseHostsFile is the base file to create the `/etc/hosts` file inside the container.
// This must either be an absolute path to a file on the host system, or one of the
// special flags `image` or `none`.
// If it is empty it defaults to the base_hosts_file configuration in containers.conf.
// Optional.
BaseHostsFile string `json:"base_hosts_file,omitempty"`
// HostAdd is a set of hosts which will be added to the container's
Expand Down
1 change: 1 addition & 0 deletions pkg/specgenutil/specgen.go
Original file line number Diff line number Diff line change
Expand Up @@ -587,6 +587,7 @@ func FillOutSpecGen(s *specgen.SpecGenerator, c *entities.ContainerCreateOptions

if c.Net != nil {
s.HostAdd = c.Net.AddHosts
s.BaseHostsFile = c.Net.HostsFile
s.UseImageResolvConf = &c.Net.UseImageResolvConf
s.DNSServers = c.Net.DNSServers
s.DNSSearch = c.Net.DNSSearch
Expand Down
25 changes: 25 additions & 0 deletions test/e2e/build_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -737,6 +737,31 @@ RUN [[ -L /test/dummy-symlink ]] && echo SYMLNKOK || echo SYMLNKERR`, CITEST_IMA
Expect(session.OutputToString()).To(ContainSubstring("SYMLNKOK"))
})

It("podman build --no-hosts", func() {
targetPath := podmanTest.TempDir

containerFile := filepath.Join(targetPath, "Containerfile")
content := `FROM scratch
RUN echo '56.78.12.34 image.example.com' > /etc/hosts`

Expect(os.WriteFile(containerFile, []byte(content), 0755)).To(Succeed())

defer func() {
Expect(os.RemoveAll(containerFile)).To(Succeed())
}()

session := podmanTest.Podman([]string{
"build", "--pull-never", "-t", "hosts_test", "--no-hosts", "--from", CITEST_IMAGE, targetPath,
})
session.WaitWithDefaultTimeout()
Expect(session).Should(ExitCleanly())

session = podmanTest.Podman([]string{"run", "--no-hosts", "--rm", "hosts_test", "cat", "/etc/hosts"})
session.WaitWithDefaultTimeout()
Expect(session).Should(ExitCleanly())
Expect(session.OutputToString()).To(Equal("56.78.12.34 image.example.com"))
})

It("podman build --from, --add-host, --cap-drop, --cap-add", func() {
targetPath := podmanTest.TempDir

Expand Down
13 changes: 8 additions & 5 deletions test/e2e/common_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -663,14 +663,14 @@ func (p *PodmanTestIntegration) RunLsContainerInPod(name, pod string) (*PodmanSe

// BuildImage uses podman build and buildah to build an image
// called imageName based on a string dockerfile
func (p *PodmanTestIntegration) BuildImage(dockerfile, imageName string, layers string) string {
return p.buildImage(dockerfile, imageName, layers, "")
func (p *PodmanTestIntegration) BuildImage(dockerfile, imageName string, layers string, extraOptions ...string) string {
return p.buildImage(dockerfile, imageName, layers, "", extraOptions)
}

// BuildImageWithLabel uses podman build and buildah to build an image
// called imageName based on a string dockerfile, adds desired label to paramset
func (p *PodmanTestIntegration) BuildImageWithLabel(dockerfile, imageName string, layers string, label string) string {
return p.buildImage(dockerfile, imageName, layers, label)
func (p *PodmanTestIntegration) BuildImageWithLabel(dockerfile, imageName string, layers string, label string, extraOptions ...string) string {
return p.buildImage(dockerfile, imageName, layers, label, extraOptions)
}

// PodmanPID execs podman and returns its PID
Expand Down Expand Up @@ -1299,7 +1299,7 @@ func (s *PodmanSessionIntegration) jq(jqCommand string) (string, error) {
return strings.TrimRight(out.String(), "\n"), err
}

func (p *PodmanTestIntegration) buildImage(dockerfile, imageName string, layers string, label string) string {
func (p *PodmanTestIntegration) buildImage(dockerfile, imageName string, layers string, label string, extraOptions []string) string {
dockerfilePath := filepath.Join(p.TempDir, "Dockerfile-"+stringid.GenerateRandomID())
err := os.WriteFile(dockerfilePath, []byte(dockerfile), 0755)
Expect(err).ToNot(HaveOccurred())
Expand All @@ -1310,6 +1310,9 @@ func (p *PodmanTestIntegration) buildImage(dockerfile, imageName string, layers
if len(imageName) > 0 {
cmd = append(cmd, []string{"-t", imageName}...)
}
if len(extraOptions) > 0 {
cmd = append(cmd, extraOptions...)
}
cmd = append(cmd, p.TempDir)
session := p.Podman(cmd)
session.Wait(240)
Expand Down
Loading

0 comments on commit 70c2559

Please sign in to comment.