diff --git a/client/client.go b/client/client.go index cbe18ada6..636ed9417 100644 --- a/client/client.go +++ b/client/client.go @@ -354,13 +354,14 @@ func NewClient(cfg *config.Config, consulCatalog consul.CatalogAPI, consulServic c.configCopy = c.config.Copy() c.configLock.Unlock() + // Auto download CNI binaries and configure CNI_PATH if requested. if c.config.AutoFetchCNI { - cniGetter := NewCNIGetter(c.config.AutoFetchCNIURL, c.config.AutoFetchCNIDir) - c.logger.Info("downloading CNI plugins", "url", cniGetter.src) - if err := cniGetter.Get(); err != nil { - c.logger.Warn("failed to fetch CNI plugins", "url", cniGetter.src, "error", err) - } else { - c.config.CNIPath = cniGetter.CNIPath(c.config.CNIPath) + if cniPath := FetchCNIPlugins(c.logger, c.config.AutoFetchCNIURL, c.config.AutoFetchCNIDir); cniPath != "" { + if c.config.CNIPath == "" { + c.config.CNIPath = cniPath + } else { + c.config.CNIPath = c.config.CNIPath + ":" + cniPath + } c.logger.Debug("using new CNI Path", "cni_path", c.config.CNIPath) } } @@ -594,7 +595,7 @@ func (c *Client) init() error { } if c.config.AutoFetchCNI { - c.logger.Info("using alloc directory", "alloc_dir", c.config.AllocDir) + c.logger.Info("using cni directory for plugin downloads", "cni_dir", c.config.AutoFetchCNIDir) } return nil } diff --git a/client/cni_autofetch.go b/client/cni_autofetch.go index 4e887f372..668e0ce16 100644 --- a/client/cni_autofetch.go +++ b/client/cni_autofetch.go @@ -4,9 +4,9 @@ import ( "fmt" "path/filepath" "runtime" - "strings" getter "github.com/hashicorp/go-getter" + hclog "github.com/hashicorp/go-hclog" ) const ( @@ -14,38 +14,35 @@ const ( ) var ( + + // checksums are copied from https://github.com/containernetworking/plugins/releases defaultCNIGetterChecksums = map[string]string{ "linux-amd64": "sha256:e9bfc78acd3ae71be77eb8f3e890cc9078a33cc3797703b8ff2fc3077a232252", "linux-arm": "sha256:ae6ddbd87c05a79aceb92e1c8c32d11e302f6fc55045f87f6a3ea7e0268b2fda", "linux-arm64": "sha256:acde854e3def3c776c532ae521c19d8784534918cc56449ff16945a2909bff6d", "windows-amd64": "sha256:a8a24e9cf93f4db92321afca3fe53bd3ccdf2b7117c403c55a5bac162d8d79cc", } - defaultCNIGetterSrc = fmt.Sprintf("https://github.com/containernetworking/plugins/releases/download/v0.8.1/cni-plugins-%s-%s-v0.8.1.tgz?checksum=%s", - runtime.GOOS, runtime.GOARCH, defaultCNIGetterChecksums[runtime.GOOS+"-"+runtime.GOARCH]) + defaultCNIPluginVersion = "0.8.1" + defaultCNIGetterSrc = fmt.Sprintf("https://github.com/containernetworking/plugins/releases/download/v%s/cni-plugins-%s-%s-v%s.tgz?checksum=%s", + defaultCNIPluginVersion, runtime.GOOS, runtime.GOARCH, defaultCNIPluginVersion, + defaultCNIGetterChecksums[runtime.GOOS+"-"+runtime.GOARCH]) ) -type CNIGetter struct { - src string - dst string -} - -func NewCNIGetter(src, dataDir string) *CNIGetter { +// FetchCNIPlugins downloads the standard set of CNI plugins to the client's +// data directory and returns the path to be used when setting up the CNI_PATH +// environment variable. If an error occures during download, it is logged and +// an empty path is returned +func FetchCNIPlugins(logger hclog.Logger, src string, dataDir string) string { if src == "" { src = defaultCNIGetterSrc } - return &CNIGetter{ - src: src, - dst: filepath.Join(dataDir, nomadCNIBinDir), - } -} -func (g *CNIGetter) Get() error { - return getter.Get(g.dst, g.src) -} - -func (g *CNIGetter) CNIPath(path string) string { - if path == "" { - return g.dst + logger.Info("downloading CNI plugins", "url", src) + dst := filepath.Join(dataDir, nomadCNIBinDir) + if err := getter.Get(dst, src); err != nil { + logger.Warn("failed to fetch CNI plugins", "url", src, "error", err) + return "" } - return path + ":" + g.dst + + return dst } diff --git a/command/agent/config.go b/command/agent/config.go index 3075c6f29..2f8048553 100644 --- a/command/agent/config.go +++ b/command/agent/config.go @@ -261,10 +261,14 @@ type ClientConfig struct { // the host BridgeNetworkSubnet string `hcl:"bridge_network_subnet"` - // AutoFetchCNIPlugins - AutoFetchCNIPlugins bool `hcl:"auto_fetch_cni_plugins` + // AutoFetchCNIPlugins toggles if the Nomad client should attempt to + // automatically download a standard set of CNI plugins, typically from + // the community repo https://github.com/containernetworking/plugins/releases + AutoFetchCNIPlugins bool `hcl:"auto_fetch_cni_plugins"` - // AutoFetchCNIPluginsURL + // AutoFetchCNIPluginsURL sets the source URL to be used if automatically + // downloading CNI plugins. If not set will use a known working version from + // the community repo https://github.com/containernetworking/plugins/releases AutoFetchCNIPluginsURL string `hcl:"auto_fetch_cni_plugins_url"` }