Skip to content

Commit

Permalink
feature: cli support add --add-host
Browse files Browse the repository at this point in the history
Signed-off-by: Lang Chi <21860405@zju.edu.cn>
  • Loading branch information
pouchrobot authored and chilang committed Aug 25, 2020
1 parent 6ef73ce commit c43bbc7
Show file tree
Hide file tree
Showing 6 changed files with 111 additions and 1 deletion.
35 changes: 35 additions & 0 deletions apis/opts/hosts.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
package opts

import (
"fmt"
"net"
"strings"

"github.com/pkg/errors"
)

// ValidateExtraHost validates the provided string is a valid extra-host.
func ValidateExtraHost(val string) error {
// allow for IPv6 addresses in extra hosts by only splitting on first ":"
arr := strings.SplitN(val, ":", 2)
if len(arr) != 2 || len(arr[0]) == 0 {
return errors.Errorf("bad format for add-host: %q", val)
}
// TODO(lang710): Skip ipaddr validation for special "host-gateway" string
// If the IP Address is a string called "host-gateway", replace this
// value with the IP address stored in the daemon level HostGatewayIP
// config variable
if _, err := validateIPAddress(arr[1]); err != nil {
return errors.Wrapf(err, "invalid IP address in add-host: %q", arr[1])
}
return nil
}

// validateIPAddress validates an Ip address.
func validateIPAddress(val string) (string, error) {
var ip = net.ParseIP(strings.TrimSpace(val))
if ip != nil {
return ip.String(), nil
}
return "", fmt.Errorf("%s is not an ip address", val)
}
38 changes: 38 additions & 0 deletions apis/opts/hosts_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
package opts

import (
"strings"
"testing"
)

func TestValidateExtraHosts(t *testing.T) {
valid := []string{
`myhost:192.168.0.1`,
`thathost:10.0.2.1`,
`anipv6host:2003:ab34:e::1`,
`ipv6local:::1`,
}

invalid := map[string]string{
`myhost:192.notanipaddress.1`: `invalid IP`,
`thathost-nosemicolon10.0.0.1`: `bad format`,
`anipv6host:::::1`: `invalid IP`,
`ipv6local:::0::`: `invalid IP`,
}

for _, extrahost := range valid {
if err := ValidateExtraHost(extrahost); err != nil {
t.Fatalf("ValidateExtraHost(`"+extrahost+"`) should succeed: error %v", err)
}
}

for extraHost, expectedError := range invalid {
if err := ValidateExtraHost(extraHost); err == nil {
t.Fatalf("ValidateExtraHost(`%q`) should have failed validation", extraHost)
} else {
if !strings.Contains(err.Error(), expectedError) {
t.Fatalf("ValidateExtraHost(`%q`) error should contain %q", extraHost, expectedError)
}
}
}
}
1 change: 1 addition & 0 deletions cli/common_flags.go
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,7 @@ func addCommonFlags(flagSet *pflag.FlagSet) *container {
flagSet.StringVar(&c.ip, "ip", "", "Set IPv4 address of container endpoint")
flagSet.StringVar(&c.ipv6, "ip6", "", "Set IPv6 address of container endpoint")
flagSet.Int64Var(&c.netPriority, "net-priority", 0, "net priority")
flagSet.StringArrayVar(&c.extraHosts, "add-host", nil, "Add a custom host-to-IP mapping (host:ip)")
// dns
flagSet.StringArrayVar(&c.dns, "dns", nil, "Set DNS servers")
flagSet.StringSliceVar(&c.dnsOptions, "dns-option", nil, "Set DNS options")
Expand Down
2 changes: 2 additions & 0 deletions cli/container.go
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,7 @@ type container struct {
ipv6 string
macAddress string
netPriority int64
extraHosts []string
dns []string
dnsOptions []string
dnsSearch []string
Expand Down Expand Up @@ -268,6 +269,7 @@ func (c *container) config() (*types.ContainerCreateConfig, error) {
Ulimits: c.ulimit.Value(),
PidsLimit: c.pidsLimit,
},
ExtraHosts: c.extraHosts,
DNS: c.dns,
DNSOptions: c.dnsOptions,
DNSSearch: c.dnsSearch,
Expand Down
11 changes: 10 additions & 1 deletion daemon/mgr/network.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import (
"strconv"
"strings"

"github.com/alibaba/pouch/apis/opts"
apitypes "github.com/alibaba/pouch/apis/types"
"github.com/alibaba/pouch/daemon/config"
"github.com/alibaba/pouch/daemon/events"
Expand Down Expand Up @@ -693,8 +694,16 @@ func buildSandboxOptions(config network.Config, endpoint *types.Endpoint) ([]lib
sandboxOptions = append(sandboxOptions, libnetwork.OptionDNSOptions(ds))
}

for _, extraHost := range endpoint.ExtraHosts {
// allow IPv6 addresses in extra hosts; only split on first ":"
if err := opts.ValidateExtraHost(extraHost); err != nil {
return nil, err
}
parts := strings.SplitN(extraHost, ":", 2)
sandboxOptions = append(sandboxOptions, libnetwork.OptionExtraHost(parts[0], parts[1]))
}

// TODO: secondary ip address
// TODO: parse extra hosts
var bindings = make(nat.PortMap)
if endpoint.PortBindings != nil {
for p, b := range endpoint.PortBindings {
Expand Down
25 changes: 25 additions & 0 deletions test/cli_run_network_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -122,3 +122,28 @@ func (suite *PouchRunNetworkSuite) TestRunWithIP(c *check.C) {

c.Assert(found, check.Equals, true)
}

// TestRunAddHost is to verify run container with add-host flag
func (suite *PouchRunNetworkSuite) TestRunAddHost(c *check.C) {
name := "TestRunAddHost"
res := command.PouchRun("run", "--name", name, "--add-host=extra:86.75.30.9", busyboxImage, "grep", "extra", "/etc/hosts")
res.Assert(c, icmd.Success)
defer DelContainerForceMultyTime(c, name)

stdout := res.Stdout()
actual := strings.Trim(stdout, "\r\n")
if !strings.Contains(actual, "86.75.30.9\textra") {
c.Fatalf("expected '86.75.30.9\textra', but says: %q", actual)
}
}

func (suite *PouchRunNetworkSuite) TestRunAddHostInHostMode(c *check.C) {
name := "TestRunAddHostInHostMode"
expectedOutput := "1.2.3.4\textra"
res := command.PouchRun("run", "--name", name, "--add-host=extra:1.2.3.4", "--net=host", busyboxImage, "cat", "/etc/hosts")
res.Assert(c, icmd.Success)
defer DelContainerForceMultyTime(c, name)
if !strings.Contains(res.Stdout(), expectedOutput) {
check.Commentf("Expected '%s', but got %q", expectedOutput, res.Stdout())
}
}

0 comments on commit c43bbc7

Please sign in to comment.