Skip to content

Commit

Permalink
extra-hosts
Browse files Browse the repository at this point in the history
Signed-off-by: fahed dorgaa <fahed.dorgaa@gmail.com>

setup extraHosts

Signed-off-by: fahed dorgaa <fahed.dorgaa@gmail.com>

setup extraHosts

Signed-off-by: fahed dorgaa <fahed.dorgaa@gmail.com>

setup extraHosts

Signed-off-by: fahed dorgaa <fahed.dorgaa@gmail.com>

fixes

Signed-off-by: fahed dorgaa <fahed.dorgaa@gmail.com>

fixes

Signed-off-by: fahed dorgaa <fahed.dorgaa@gmail.com>

fixes

Signed-off-by: fahed dorgaa <fahed.dorgaa@gmail.com>

fixes

Signed-off-by: fahed dorgaa <fahed.dorgaa@gmail.com>

fixes

Signed-off-by: fahed dorgaa <fahed.dorgaa@gmail.com>
  • Loading branch information
fahedouch committed Sep 6, 2021
1 parent d076496 commit 8b8374a
Show file tree
Hide file tree
Showing 8 changed files with 97 additions and 18 deletions.
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -283,6 +283,7 @@ Network flags:
- :whale: `-p, --publish`: Publish a container's port(s) to the host
- :whale: `--dns`: Set custom DNS servers
- :whale: `-h, --hostname`: Container host name
- :whale: `--add-host`: Add a custom host-to-IP mapping (host:ip)

Cgroup flags:
- :whale: `--cpus`: Number of CPUs
Expand Down
8 changes: 8 additions & 0 deletions cmd/nerdctl/internal_oci_hook.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,12 @@ var internalOCIHookCommand = &cli.Command{
Name: "oci-hook",
Usage: "OCI hook",
Action: internalOCIHookAction,
Flags: []cli.Flag{
&cli.StringSliceFlag{
Name: "add-host",
Usage: "Add a custom host-to-IP mapping (host:ip)",
},
},
}

func internalOCIHookAction(clicontext *cli.Context) error {
Expand All @@ -37,9 +43,11 @@ func internalOCIHookAction(clicontext *cli.Context) error {
if err != nil {
return err
}

return ocihook.Run(clicontext.App.Reader, clicontext.App.ErrWriter, event,
dataStore,
clicontext.String("cni-path"),
clicontext.String("cni-netconfpath"),
clicontext.StringSlice("add-host"),
)
}
15 changes: 14 additions & 1 deletion cmd/nerdctl/run.go
Original file line number Diff line number Diff line change
Expand Up @@ -228,6 +228,10 @@ var runCommand = &cli.Command{
Aliases: []string{"e"},
Usage: "Set environment variables",
},
&cli.StringSliceFlag{
Name: "add-host",
Usage: "Add a custom host-to-IP mapping (host:ip)",
},
&cli.StringSliceFlag{
Name: "env-file",
Usage: "Set environment variables from file",
Expand Down Expand Up @@ -427,6 +431,7 @@ func runAction(clicontext *cli.Context) error {
if err := dnsutil.WriteResolvConfFile(resolvConfPath, strutil.DedupeStrSlice(clicontext.StringSlice("dns"))); err != nil {
return err
}

// the content of /etc/hosts is created in OCI Hook
etcHostsPath, err := hostsstore.AllocHostsFile(dataStore, ns, id)
if err != nil {
Expand Down Expand Up @@ -758,7 +763,14 @@ func withNerdctlOCIHook(clicontext *cli.Context, id, stateDir string) (oci.SpecO
if s.Hooks == nil {
s.Hooks = &specs.Hooks{}
}
crArgs := append(args, "createRuntime")
var crArgs []string
crArgs = append(crArgs, args...)
if hosts := strutil.DedupeStrSlice(clicontext.StringSlice("add-host")); len(hosts) > 0 {
for _, v := range hosts {
crArgs = append(crArgs, "--add-host", v)
}
}
crArgs = append(crArgs, "createRuntime")
s.Hooks.CreateRuntime = append(s.Hooks.CreateRuntime, specs.Hook{
Path: selfExe,
Args: crArgs,
Expand All @@ -771,6 +783,7 @@ func withNerdctlOCIHook(clicontext *cli.Context, id, stateDir string) (oci.SpecO
Args: psArgs,
Env: os.Environ(),
})

return nil
}, nil
}
Expand Down
23 changes: 23 additions & 0 deletions cmd/nerdctl/run_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@
package main

import (
"bufio"
"bytes"
"fmt"
"io/ioutil"
"os"
Expand Down Expand Up @@ -189,3 +191,24 @@ func TestRunPidHost(t *testing.T) {

base.Cmd("run", "--rm", "--pid=host", testutil.AlpineImage, "ps", "auxw").AssertOutContains(strconv.Itoa(pid))
}

func TestRunAddHost(t *testing.T) {
base := testutil.NewBase(t)
base.Cmd("run", "--rm", "--add-host", "testing.example.com:10.0.0.1", testutil.AlpineImage, "sh", "-c", "cat /etc/hosts").AssertOutWithFunc(func(stdout string) error {
var found bool
sc := bufio.NewScanner(bytes.NewBufferString(stdout))
for sc.Scan() {
//removing spaces and tabs separating items
line := strings.ReplaceAll(sc.Text(), " ", "")
line = strings.ReplaceAll(line, "\t", "")
if strings.Contains(line, "10.0.0.1testing.example.com") {
found = true
}
}
if !found {
return errors.New("host was not added")
}
return nil
})
base.Cmd("run", "--rm", "--add-host", "10.0.0.1:testing.example.com", testutil.AlpineImage, "sh", "-c", "cat /etc/hosts").AssertFail()
}
4 changes: 4 additions & 0 deletions pkg/composer/serviceparser/serviceparser.go
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ func warnUnknownFields(svc compose.ServiceConfig) {
"Entrypoint",
"Environment",
"Extends", // handled by the loader
"ExtraHosts",
"Hostname",
"Image",
"Labels",
Expand Down Expand Up @@ -464,6 +465,9 @@ func newContainer(project *compose.Project, parsed *Service, i int) (*Container,
c.RunArgs = append(c.RunArgs, fmt.Sprintf("-e=%s=%s", k, *v))
}
}
for _, v := range svc.ExtraHosts {
c.RunArgs = append(c.RunArgs, fmt.Sprintf("--add-host=%s", v))
}

hostname := svc.Hostname
if hostname == "" {
Expand Down
15 changes: 8 additions & 7 deletions pkg/dnsutil/hostsstore/hostsstore.go
Original file line number Diff line number Diff line change
Expand Up @@ -99,11 +99,12 @@ func NewStore(dataStore string) (Store, error) {
}

type Meta struct {
Namespace string
ID string
Networks map[string]*current.Result
Hostname string
Name string
Namespace string
ID string
Networks map[string]*current.Result
Hostname string
ExtraHosts []string
Name string
}

type Store interface {
Expand Down Expand Up @@ -132,7 +133,7 @@ func (x *store) Acquire(meta Meta) error {
if err := ioutil.WriteFile(metaPath, metaB, 0644); err != nil {
return err
}
return newUpdater(x.hostsD).update()
return newUpdater(x.hostsD, meta.ExtraHosts).update()
}
return lockutil.WithDirLock(x.hostsD, fn)
}
Expand All @@ -150,7 +151,7 @@ func (x *store) Release(ns, id string) error {
if err := os.RemoveAll(metaPath); err != nil {
return err
}
return newUpdater(x.hostsD).update()
return newUpdater(x.hostsD, nil).update()
}
return lockutil.WithDirLock(x.hostsD, fn)
}
7 changes: 6 additions & 1 deletion pkg/dnsutil/hostsstore/updater.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,12 +31,13 @@ import (
)

// newUpdater creates an updater for hostsD (/var/lib/nerdctl/<ADDRHASH>/etchosts)
func newUpdater(hostsD string) *updater {
func newUpdater(hostsD string, extraHosts []string) *updater {
u := &updater{
hostsD: hostsD,
metaByIPStr: make(map[string]*Meta),
nwNameByIPStr: make(map[string]string),
metaByDir: make(map[string]*Meta),
extraHosts: extraHosts,
}
return u
}
Expand All @@ -47,6 +48,7 @@ type updater struct {
metaByIPStr map[string]*Meta // key: IP string
nwNameByIPStr map[string]string // key: IP string, value: key of Meta.Networks
metaByDir map[string]*Meta // key: "/var/lib/nerdctl/<ADDRHASH>/etchosts/<NS>/<ID>"
extraHosts []string
}

// update updates the hostsD tree.
Expand Down Expand Up @@ -130,6 +132,9 @@ func (u *updater) phase2() error {
buf.WriteString(fmt.Sprintf("# %s\n", markerBegin))
buf.WriteString("127.0.0.1 localhost localhost.localdomain\n")
buf.WriteString(":1 localhost localhost.localdomain\n")
for _, h := range u.extraHosts {
buf.WriteString(fmt.Sprintf("%s\n", h))
}
// TODO: cut off entries for the containers in other networks
for ip, nwName := range u.nwNameByIPStr {
meta := u.metaByIPStr[ip]
Expand Down
42 changes: 33 additions & 9 deletions pkg/ocihook/ocihook.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,9 +24,9 @@ import (
"net"
"os"
"path/filepath"
"strings"

"github.com/containerd/containerd/cmd/ctr/commands"

pkgapparmor "github.com/containerd/containerd/pkg/apparmor"
gocni "github.com/containerd/go-cni"
"github.com/containerd/nerdctl/pkg/dnsutil/hostsstore"
Expand All @@ -35,13 +35,14 @@ import (
"github.com/containerd/nerdctl/pkg/netutil/nettype"
"github.com/containerd/nerdctl/pkg/rootlessutil"
"github.com/containernetworking/cni/pkg/types/current"
dopts "github.com/docker/cli/opts"
"github.com/opencontainers/runtime-spec/specs-go"
"github.com/pkg/errors"
rlkclient "github.com/rootless-containers/rootlesskit/pkg/api/client"
"github.com/sirupsen/logrus"
)

func Run(stdin io.Reader, stderr io.Writer, event, dataStore, cniPath, cniNetconfPath string) error {
func Run(stdin io.Reader, stderr io.Writer, event, dataStore, cniPath, cniNetconfPath string, extraHosts []string) error {
if stdin == nil || event == "" || dataStore == "" || cniPath == "" || cniNetconfPath == "" {
return errors.New("got insufficient args")
}
Expand All @@ -66,7 +67,7 @@ func Run(stdin io.Reader, stderr io.Writer, event, dataStore, cniPath, cniNetcon
logrus.SetOutput(io.MultiWriter(stderr, logFile))
}

opts, err := newHandlerOpts(&state, dataStore, cniPath, cniNetconfPath)
opts, err := newHandlerOpts(&state, dataStore, cniPath, cniNetconfPath, extraHosts)
if err != nil {
return err
}
Expand All @@ -81,11 +82,32 @@ func Run(stdin io.Reader, stderr io.Writer, event, dataStore, cniPath, cniNetcon
}
}

func newHandlerOpts(state *specs.State, dataStore, cniPath, cniNetconfPath string) (*handlerOpts, error) {
func newHandlerOpts(state *specs.State, dataStore, cniPath, cniNetconfPath string, extraHosts []string) (*handlerOpts, error) {
o := &handlerOpts{
state: state,
dataStore: dataStore,
}

//validate and format extraHosts
ensureExtraHosts := func(extraHosts []string) ([]string, error) {
hosts := []string{}
for _, host := range extraHosts {
hostIP, err := dopts.ValidateExtraHost(host)
if err != nil {
return nil, err
}
if v := strings.SplitN(hostIP, ":", 2); len(v) == 2 {
hosts = append(hosts, fmt.Sprintf("%s %s", v[1], v[0]))
}
}
return hosts, nil
}

var err error
if o.extraHosts, err = ensureExtraHosts(extraHosts); err != nil {
return nil, err
}

hs, err := loadSpec(o.state.Bundle)
if err != nil {
return nil, err
Expand Down Expand Up @@ -181,6 +203,7 @@ type handlerOpts struct {
cniNames []string
fullID string
rootlessKitClient rlkclient.Client
extraHosts []string
}

// hookSpec is from https://github.com/containerd/containerd/blob/v1.4.3/cmd/containerd/command/oci-hook.go#L59-L64
Expand Down Expand Up @@ -280,11 +303,12 @@ func onCreateRuntime(opts *handlerOpts) error {
return err
}
hsMeta := hostsstore.Meta{
Namespace: opts.state.Annotations[labels.Namespace],
ID: opts.state.ID,
Networks: make(map[string]*current.Result, len(opts.cniNames)),
Hostname: opts.state.Annotations[labels.Hostname],
Name: opts.state.Annotations[labels.Name],
Namespace: opts.state.Annotations[labels.Namespace],
ID: opts.state.ID,
Networks: make(map[string]*current.Result, len(opts.cniNames)),
Hostname: opts.state.Annotations[labels.Hostname],
ExtraHosts: opts.extraHosts,
Name: opts.state.Annotations[labels.Name],
}
cniRes, err := opts.cni.Setup(ctx, opts.fullID, nsPath, portMapOpts...)
if err != nil {
Expand Down

0 comments on commit 8b8374a

Please sign in to comment.