diff options
-rw-r--r-- | cmd/podman/create.go | 19 | ||||
-rw-r--r-- | cmd/podman/run.go | 6 | ||||
-rw-r--r-- | cmd/podman/run_test.go | 82 | ||||
-rw-r--r-- | libpod/networking.go | 3 | ||||
-rw-r--r-- | libpod/options.go | 2 | ||||
-rw-r--r-- | libpod/runtime.go | 6 | ||||
-rw-r--r-- | pkg/storage/doc.go | 5 | ||||
-rw-r--r-- | pkg/storage/image.go | 551 | ||||
-rw-r--r-- | pkg/storage/image_regexp.go | 125 | ||||
-rw-r--r-- | pkg/storage/runtime.go | 452 | ||||
-rw-r--r-- | vendor/github.com/cri-o/ocicni/pkg/ocicni/noop.go | 24 | ||||
-rw-r--r-- | vendor/github.com/cri-o/ocicni/pkg/ocicni/ocicni.go | 64 | ||||
-rw-r--r-- | vendor/github.com/cri-o/ocicni/pkg/ocicni/types.go | 6 |
13 files changed, 136 insertions, 1209 deletions
diff --git a/cmd/podman/create.go b/cmd/podman/create.go index 076e8c56e..ead2f6735 100644 --- a/cmd/podman/create.go +++ b/cmd/podman/create.go @@ -160,13 +160,18 @@ func createCmd(c *cli.Context) error { } } + if len(c.Args()) < 1 { + return errors.Errorf("image name or ID is required") + } + runtime, err := getRuntime(c) if err != nil { return errors.Wrapf(err, "error creating libpod runtime") } defer runtime.Shutdown(false) - createConfig, err := parseCreateOpts(c, runtime) + imageName, _, data, err := imageData(c, runtime, c.Args()[0]) + createConfig, err := parseCreateOpts(c, runtime, imageName, data) if err != nil { return err } @@ -365,15 +370,13 @@ func imageData(c *cli.Context, runtime *libpod.Runtime, image string) (string, s // Parses CLI options related to container creation into a config which can be // parsed into an OCI runtime spec -func parseCreateOpts(c *cli.Context, runtime *libpod.Runtime) (*createConfig, error) { +func parseCreateOpts(c *cli.Context, runtime *libpod.Runtime, imageName string, data *libpod.ImageData) (*createConfig, error) { + //imageName, imageID, data, err := imageData(c, runtime, image) var command []string var memoryLimit, memoryReservation, memorySwap, memoryKernel int64 var blkioWeight uint16 - if len(c.Args()) < 1 { - return nil, errors.Errorf("image name or ID is required") - } - image := c.Args()[0] + imageID := data.ID if len(c.Args()) > 1 { command = c.Args()[1:] @@ -460,10 +463,6 @@ func parseCreateOpts(c *cli.Context, runtime *libpod.Runtime) (*createConfig, er } shmDir = ctr.ShmDir() } - imageName, imageID, data, err := imageData(c, runtime, image) - if err != nil { - return nil, err - } // USER user := c.String("user") diff --git a/cmd/podman/run.go b/cmd/podman/run.go index d9bc00b78..eecfe87b3 100644 --- a/cmd/podman/run.go +++ b/cmd/podman/run.go @@ -41,8 +41,12 @@ func runCmd(c *cli.Context) error { return errors.Wrapf(err, "error creating libpod runtime") } defer runtime.Shutdown(false) + if len(c.Args()) < 1 { + return errors.Errorf("image name or ID is required") + } - createConfig, err := parseCreateOpts(c, runtime) + imageName, _, data, err := imageData(c, runtime, c.Args()[0]) + createConfig, err := parseCreateOpts(c, runtime, imageName, data) if err != nil { return err } diff --git a/cmd/podman/run_test.go b/cmd/podman/run_test.go new file mode 100644 index 000000000..622e75d3e --- /dev/null +++ b/cmd/podman/run_test.go @@ -0,0 +1,82 @@ +package main + +import ( + "testing" + + ociv1 "github.com/opencontainers/image-spec/specs-go/v1" + spec "github.com/opencontainers/runtime-spec/specs-go" + "github.com/projectatomic/libpod/libpod" + "github.com/stretchr/testify/assert" + "github.com/urfave/cli" +) + +var ( + cmd = []string{"podman", "test", "alpine"} + CLI *cli.Context + testCommand = cli.Command{ + Name: "test", + Flags: createFlags, + Action: testCmd, + } +) + +// generates a mocked ImageData structure based on alpine +func generateAlpineImageData() *libpod.ImageData { + config := &ociv1.ImageConfig{ + User: "", + ExposedPorts: nil, + Env: []string{"PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"}, + Entrypoint: []string{}, + Cmd: []string{"/bin/sh"}, + Volumes: nil, + WorkingDir: "", + Labels: nil, + StopSignal: "", + } + + data := &libpod.ImageData{ + ID: "e21c333399e0aeedfd70e8827c9fba3f8e9b170ef8a48a29945eb7702bf6aa5f", + RepoTags: []string{"docker.io/library/alpine:latest"}, + RepoDigests: []string{"docker.io/library/alpine@sha256:5cb04fce748f576d7b72a37850641de8bd725365519673c643ef2d14819b42c6"}, + Comment: "Created:2017-12-01 18:48:48.949613376 +0000", + Author: "", + Architecture: "amd64", + Os: "linux", + Version: "17.06.2-ce", + Config: config, + } + return data +} + +// sets a global CLI +func testCmd(c *cli.Context) error { + CLI = c + return nil +} + +// creates the mocked cli pointing to our create flags +// global flags like log-level are not implemented +func createCLI() cli.App { + a := cli.App{ + Commands: []cli.Command{ + testCommand, + }, + } + return a +} + +func getRuntimeSpec(c *cli.Context) *spec.Spec { + runtime, _ := getRuntime(c) + createConfig, _ := parseCreateOpts(c, runtime, "alpine", generateAlpineImageData()) + runtimeSpec, _ := createConfigToOCISpec(createConfig) + return runtimeSpec +} + +// TestPIDsLimit verifies the inputed pid-limit is correctly defined in the spec +func TestPIDsLimit(t *testing.T) { + a := createCLI() + args := []string{"--pids-limit", "22"} + a.Run(append(cmd, args...)) + runtimeSpec := getRuntimeSpec(CLI) + assert.Equal(t, runtimeSpec.Linux.Resources.Pids.Limit, int64(22)) +} diff --git a/libpod/networking.go b/libpod/networking.go index 456830708..41bd65d25 100644 --- a/libpod/networking.go +++ b/libpod/networking.go @@ -38,7 +38,8 @@ func (r *Runtime) createNetNS(ctr *Container) (err error) { podNetwork := getPodNetwork(ctr.ID(), ctr.Name(), ctrNS.Path(), ctr.config.PortMappings) - if err := r.netPlugin.SetUpPod(podNetwork); err != nil { + _, err = r.netPlugin.SetUpPod(podNetwork) + if err != nil { return errors.Wrapf(err, "error configuring network namespace for container %s", ctr.ID()) } diff --git a/libpod/options.go b/libpod/options.go index cd1ad5eda..8097f3a64 100644 --- a/libpod/options.go +++ b/libpod/options.go @@ -275,7 +275,7 @@ func WithCNIPluginDir(dir string) RuntimeOption { return ErrRuntimeFinalized } - rt.config.CNIPluginDir = dir + rt.config.CNIPluginDir = []string{dir} return nil } diff --git a/libpod/runtime.go b/libpod/runtime.go index aed6acd86..d0aa481cf 100644 --- a/libpod/runtime.go +++ b/libpod/runtime.go @@ -51,7 +51,7 @@ type RuntimeConfig struct { MaxLogSize int64 NoPivotRoot bool CNIConfigDir string - CNIPluginDir string + CNIPluginDir []string } var ( @@ -73,7 +73,7 @@ var ( MaxLogSize: -1, NoPivotRoot: false, CNIConfigDir: "/etc/cni/net.d/", - CNIPluginDir: "/usr/libexec/cni", + CNIPluginDir: []string{"/usr/libexec/cni", "/opt/cni/bin"}, } ) @@ -173,7 +173,7 @@ func NewRuntime(options ...RuntimeOption) (runtime *Runtime, err error) { } // Set up the CNI net plugin - netPlugin, err := ocicni.InitCNI(runtime.config.CNIConfigDir, runtime.config.CNIPluginDir) + netPlugin, err := ocicni.InitCNI(runtime.config.CNIConfigDir, runtime.config.CNIPluginDir...) if err != nil { return nil, errors.Wrapf(err, "error configuring CNI network plugin") } diff --git a/pkg/storage/doc.go b/pkg/storage/doc.go deleted file mode 100644 index 6366b22a4..000000000 --- a/pkg/storage/doc.go +++ /dev/null @@ -1,5 +0,0 @@ -// Package storage provides helper functions for creating and managing CRI pod -// sandboxes and containers and metadata associated with them in the format -// that crio understands. The API it provides should be considered to be -// unstable. -package storage diff --git a/pkg/storage/image.go b/pkg/storage/image.go deleted file mode 100644 index 1ddfe2107..000000000 --- a/pkg/storage/image.go +++ /dev/null @@ -1,551 +0,0 @@ -package storage - -import ( - "errors" - "fmt" - "net" - "path" - "regexp" - "strings" - - "github.com/containers/image/copy" - "github.com/containers/image/docker/reference" - "github.com/containers/image/image" - "github.com/containers/image/signature" - istorage "github.com/containers/image/storage" - "github.com/containers/image/transports/alltransports" - "github.com/containers/image/types" - "github.com/containers/storage" - distreference "github.com/docker/distribution/reference" -) - -// ImageResult wraps a subset of information about an image: its ID, its names, -// and the size, if known, or nil if it isn't. -type ImageResult struct { - ID string - Names []string - Digests []string - Size *uint64 - ImageRef string -} - -type indexInfo struct { - name string - secure bool -} - -type imageService struct { - store storage.Store - defaultTransport string - insecureRegistryCIDRs []*net.IPNet - indexConfigs map[string]*indexInfo - registries []string -} - -// ImageServer wraps up various CRI-related activities into a reusable -// implementation. -type ImageServer interface { - // ListImages returns list of all images which match the filter. - ListImages(systemContext *types.SystemContext, filter string) ([]ImageResult, error) - // ImageStatus returns status of an image which matches the filter. - ImageStatus(systemContext *types.SystemContext, filter string) (*ImageResult, error) - // PullImage imports an image from the specified location. - PullImage(systemContext *types.SystemContext, imageName string, options *copy.Options) (types.ImageReference, error) - // UntagImage removes a name from the specified image, and if it was - // the only name the image had, removes the image. - UntagImage(systemContext *types.SystemContext, imageName string) error - // RemoveImage deletes the specified image. - RemoveImage(systemContext *types.SystemContext, imageName string) error - // GetStore returns the reference to the storage library Store which - // the image server uses to hold images, and is the destination used - // when it's asked to pull an image. - GetStore() storage.Store - // CanPull preliminary checks whether we're allowed to pull an image - CanPull(imageName string, options *copy.Options) (bool, error) - // ResolveNames takes an image reference and if it's unqualified (w/o hostname), - // it uses crio's default registries to qualify it. - ResolveNames(imageName string) ([]string, error) -} - -func (svc *imageService) getRef(name string) (types.ImageReference, error) { - ref, err := alltransports.ParseImageName(name) - if err != nil { - ref2, err2 := istorage.Transport.ParseStoreReference(svc.store, "@"+name) - if err2 != nil { - ref3, err3 := istorage.Transport.ParseStoreReference(svc.store, name) - if err3 != nil { - return nil, err - } - ref2 = ref3 - } - ref = ref2 - } - return ref, nil -} - -func (svc *imageService) ListImages(systemContext *types.SystemContext, filter string) ([]ImageResult, error) { - results := []ImageResult{} - if filter != "" { - ref, err := svc.getRef(filter) - if err != nil { - return nil, err - } - if image, err := istorage.Transport.GetStoreImage(svc.store, ref); err == nil { - img, err := ref.NewImage(systemContext) - if err != nil { - return nil, err - } - size := imageSize(img) - img.Close() - results = append(results, ImageResult{ - ID: image.ID, - Names: image.Names, - Size: size, - }) - } - } else { - images, err := svc.store.Images() - if err != nil { - return nil, err - } - for _, image := range images { - ref, err := istorage.Transport.ParseStoreReference(svc.store, "@"+image.ID) - if err != nil { - return nil, err - } - img, err := ref.NewImage(systemContext) - if err != nil { - return nil, err - } - size := imageSize(img) - img.Close() - results = append(results, ImageResult{ - ID: image.ID, - Names: image.Names, - Size: size, - }) - } - } - return results, nil -} - -func (svc *imageService) ImageStatus(systemContext *types.SystemContext, nameOrID string) (*ImageResult, error) { - ref, err := alltransports.ParseImageName(nameOrID) - if err != nil { - ref2, err2 := istorage.Transport.ParseStoreReference(svc.store, "@"+nameOrID) - if err2 != nil { - ref3, err3 := istorage.Transport.ParseStoreReference(svc.store, nameOrID) - if err3 != nil { - return nil, err - } - ref2 = ref3 - } - ref = ref2 - } - image, err := istorage.Transport.GetStoreImage(svc.store, ref) - if err != nil { - return nil, err - } - - img, err := ref.NewImage(systemContext) - if err != nil { - return nil, err - } - size := imageSize(img) - img.Close() - - result := ImageResult{ - ID: image.ID, - Names: image.Names, - Size: size, - } - if len(image.Names) > 0 { - result.ImageRef = image.Names[0] - if ref2, err2 := istorage.Transport.ParseStoreReference(svc.store, image.Names[0]); err2 == nil { - if dref := ref2.DockerReference(); dref != nil { - result.ImageRef = reference.FamiliarString(dref) - } - } - } - - return &result, nil -} - -func imageSize(img types.Image) *uint64 { - if sum, err := img.Size(); err == nil { - usum := uint64(sum) - return &usum - } - return nil -} - -func (svc *imageService) CanPull(imageName string, options *copy.Options) (bool, error) { - srcRef, err := svc.prepareImage(imageName, options) - if err != nil { - return false, err - } - rawSource, err := srcRef.NewImageSource(options.SourceCtx) - if err != nil { - return false, err - } - src, err := image.FromSource(options.SourceCtx, rawSource) - if err != nil { - rawSource.Close() - return false, err - } - src.Close() - return true, nil -} - -// prepareImage creates an image reference from an image string and set options -// for the source context -func (svc *imageService) prepareImage(imageName string, options *copy.Options) (types.ImageReference, error) { - if imageName == "" { - return nil, storage.ErrNotAnImage - } - - srcRef, err := alltransports.ParseImageName(imageName) - if err != nil { - if svc.defaultTransport == "" { - return nil, err - } - srcRef2, err2 := alltransports.ParseImageName(svc.defaultTransport + imageName) - if err2 != nil { - return nil, err - } - srcRef = srcRef2 - } - - if options.SourceCtx == nil { - options.SourceCtx = &types.SystemContext{} - } - - hostname := reference.Domain(srcRef.DockerReference()) - if secure := svc.isSecureIndex(hostname); !secure { - options.SourceCtx.DockerInsecureSkipTLSVerify = !secure - } - return srcRef, nil -} - -func (svc *imageService) PullImage(systemContext *types.SystemContext, imageName string, options *copy.Options) (types.ImageReference, error) { - policy, err := signature.DefaultPolicy(systemContext) - if err != nil { - return nil, err - } - policyContext, err := signature.NewPolicyContext(policy) - if err != nil { - return nil, err - } - if options == nil { - options = ©.Options{} - } - - srcRef, err := svc.prepareImage(imageName, options) - if err != nil { - return nil, err - } - - dest := imageName - if srcRef.DockerReference() != nil { - dest = srcRef.DockerReference().Name() - if tagged, ok := srcRef.DockerReference().(reference.NamedTagged); ok { - dest = dest + ":" + tagged.Tag() - } - if canonical, ok := srcRef.DockerReference().(reference.Canonical); ok { - dest = dest + "@" + canonical.Digest().String() - } - } - destRef, err := istorage.Transport.ParseStoreReference(svc.store, dest) - if err != nil { - return nil, err - } - err = copy.Image(policyContext, destRef, srcRef, options) - if err != nil { - return nil, err - } - return destRef, nil -} - -func (svc *imageService) UntagImage(systemContext *types.SystemContext, nameOrID string) error { - ref, err := alltransports.ParseImageName(nameOrID) - if err != nil { - ref2, err2 := istorage.Transport.ParseStoreReference(svc.store, "@"+nameOrID) - if err2 != nil { - ref3, err3 := istorage.Transport.ParseStoreReference(svc.store, nameOrID) - if err3 != nil { - return err - } - ref2 = ref3 - } - ref = ref2 - } - - img, err := istorage.Transport.GetStoreImage(svc.store, ref) - if err != nil { - return err - } - - if nameOrID != img.ID { - namedRef, err := svc.prepareImage(nameOrID, ©.Options{}) - if err != nil { - return err - } - - name := nameOrID - if namedRef.DockerReference() != nil { - name = namedRef.DockerReference().Name() - if tagged, ok := namedRef.DockerReference().(reference.NamedTagged); ok { - name = name + ":" + tagged.Tag() - } - if canonical, ok := namedRef.DockerReference().(reference.Canonical); ok { - name = name + "@" + canonical.Digest().String() - } - } - - prunedNames := make([]string, 0, len(img.Names)) - for _, imgName := range img.Names { - if imgName != name && imgName != nameOrID { - prunedNames = append(prunedNames, imgName) - } - } - - if len(prunedNames) > 0 { - return svc.store.SetNames(img.ID, prunedNames) - } - } - - return ref.DeleteImage(systemContext) -} - -func (svc *imageService) RemoveImage(systemContext *types.SystemContext, nameOrID string) error { - ref, err := alltransports.ParseImageName(nameOrID) - if err != nil { - ref2, err2 := istorage.Transport.ParseStoreReference(svc.store, "@"+nameOrID) - if err2 != nil { - ref3, err3 := istorage.Transport.ParseStoreReference(svc.store, nameOrID) - if err3 != nil { - return err - } - ref2 = ref3 - } - ref = ref2 - } - return ref.DeleteImage(systemContext) -} - -func (svc *imageService) GetStore() storage.Store { - return svc.store -} - -func (svc *imageService) isSecureIndex(indexName string) bool { - if index, ok := svc.indexConfigs[indexName]; ok { - return index.secure - } - - host, _, err := net.SplitHostPort(indexName) - if err != nil { - // assume indexName is of the form `host` without the port and go on. - host = indexName - } - - addrs, err := net.LookupIP(host) - if err != nil { - ip := net.ParseIP(host) - if ip != nil { - addrs = []net.IP{ip} - } - - // if ip == nil, then `host` is neither an IP nor it could be looked up, - // either because the index is unreachable, or because the index is behind an HTTP proxy. - // So, len(addrs) == 0 and we're not aborting. - } - - // Try CIDR notation only if addrs has any elements, i.e. if `host`'s IP could be determined. - for _, addr := range addrs { - for _, ipnet := range svc.insecureRegistryCIDRs { - // check if the addr falls in the subnet - if ipnet.Contains(addr) { - return false - } - } - } - - return true -} - -func isValidHostname(hostname string) bool { - return hostname != "" && !strings.Contains(hostname, "/") && - (strings.Contains(hostname, ".") || - strings.Contains(hostname, ":") || hostname == "localhost") -} - -func isReferenceFullyQualified(reposName reference.Named) bool { - indexName, _, _ := splitReposName(reposName) - return indexName != "" -} - -const ( - // defaultHostname is the default built-in hostname - defaultHostname = "docker.io" - // legacyDefaultHostname is automatically converted to DefaultHostname - legacyDefaultHostname = "index.docker.io" - // defaultRepoPrefix is the prefix used for default repositories in default host - defaultRepoPrefix = "library/" -) - -// splitReposName breaks a reposName into an index name and remote name -func splitReposName(reposName reference.Named) (indexName string, remoteName reference.Named, err error) { - var remoteNameStr string - indexName, remoteNameStr = distreference.SplitHostname(reposName) - if !isValidHostname(indexName) { - // This is a Docker Index repos (ex: samalba/hipache or ubuntu) - // 'docker.io' - indexName = "" - remoteName = reposName - } else { - remoteName, err = withName(remoteNameStr) - } - return -} - -func validateName(name string) error { - if err := validateID(strings.TrimPrefix(name, defaultHostname+"/")); err == nil { - return fmt.Errorf("Invalid repository name (%s), cannot specify 64-byte hexadecimal strings", name) - } - return nil -} - -var validHex = regexp.MustCompile(`^([a-f0-9]{64})$`) - -// validateID checks whether an ID string is a valid image ID. -func validateID(id string) error { - if ok := validHex.MatchString(id); !ok { - return fmt.Errorf("image ID %q is invalid", id) - } - return nil -} - -// withName returns a named object representing the given string. If the input -// is invalid ErrReferenceInvalidFormat will be returned. -func withName(name string) (reference.Named, error) { - name, err := normalize(name) - if err != nil { - return nil, err - } - if err := validateName(name); err != nil { - return nil, err - } - r, err := distreference.WithName(name) - return r, err -} - -// splitHostname splits a repository name to hostname and remotename string. -// If no valid hostname is found, empty string will be returned as a resulting -// hostname. Repository name needs to be already validated before. -func splitHostname(name string) (hostname, remoteName string) { - i := strings.IndexRune(name, '/') - if i == -1 || (!strings.ContainsAny(name[:i], ".:") && name[:i] != "localhost") { - hostname, remoteName = "", name - } else { - hostname, remoteName = name[:i], name[i+1:] - } - if hostname == legacyDefaultHostname { - hostname = defaultHostname - } - if hostname == defaultHostname && !strings.ContainsRune(remoteName, '/') { - remoteName = defaultRepoPrefix + remoteName - } - return -} - -// normalize returns a repository name in its normalized form, meaning it -// will contain library/ prefix for official images. -func normalize(name string) (string, error) { - host, remoteName := splitHostname(name) - if strings.ToLower(remoteName) != remoteName { - return "", errors.New("invalid reference format: repository name must be lowercase") - } - if host == defaultHostname { - if strings.HasPrefix(remoteName, defaultRepoPrefix) { - remoteName = strings.TrimPrefix(remoteName, defaultRepoPrefix) - } - return host + "/" + remoteName, nil - } - return name, nil -} - -func (svc *imageService) ResolveNames(imageName string) ([]string, error) { - r, err := reference.ParseNormalizedNamed(imageName) - if err != nil { - return nil, err - } - if isReferenceFullyQualified(r) { - // this means the image is already fully qualified - return []string{imageName}, nil - } - // we got an unqualified image here, we can't go ahead w/o registries configured - // properly. - if len(svc.registries) == 0 { - return nil, errors.New("no registries configured while trying to pull an unqualified image") - } - // this means we got an image in the form of "busybox" - // we need to use additional registries... - // normalize the unqualified image to be domain/repo/image... - _, rest := splitDomain(r.Name()) - images := []string{} - for _, r := range svc.registries { - images = append(images, path.Join(r, rest)) - } - return images, nil -} - -// GetImageService returns an ImageServer that uses the passed-in store, and -// which will prepend the passed-in defaultTransport value to an image name if -// a name that's passed to its PullImage() method can't be resolved to an image -// in the store and can't be resolved to a source on its own. -func GetImageService(store storage.Store, defaultTransport string, insecureRegistries []string, registries []string) (ImageServer, error) { - if store == nil { - var err error - store, err = storage.GetStore(storage.DefaultStoreOptions) - if err != nil { - return nil, err - } - } - - seenRegistries := make(map[string]bool, len(registries)) - cleanRegistries := []string{} - for _, r := range registries { - if seenRegistries[r] { - continue - } - cleanRegistries = append(cleanRegistries, r) - seenRegistries[r] = true - } - - is := &imageService{ - store: store, - defaultTransport: defaultTransport, - indexConfigs: make(map[string]*indexInfo), - insecureRegistryCIDRs: make([]*net.IPNet, 0), - registries: cleanRegistries, - } - - insecureRegistries = append(insecureRegistries, "127.0.0.0/8") - // Split --insecure-registry into CIDR and registry-specific settings. - for _, r := range insecureRegistries { - // Check if CIDR was passed to --insecure-registry - _, ipnet, err := net.ParseCIDR(r) - if err == nil { - // Valid CIDR. - is.insecureRegistryCIDRs = append(is.insecureRegistryCIDRs, ipnet) - } else { - // Assume `host:port` if not CIDR. - is.indexConfigs[r] = &indexInfo{ - name: r, - secure: false, - } - } - } - - return is, nil -} diff --git a/pkg/storage/image_regexp.go b/pkg/storage/image_regexp.go deleted file mode 100644 index 96de64884..000000000 --- a/pkg/storage/image_regexp.go +++ /dev/null @@ -1,125 +0,0 @@ -package storage - -// This is a fork of docker/distribution code to be used when manipulating image -// references. -// DO NOT EDIT THIS FILE. - -import "regexp" - -var ( - // alphaNumericRegexp defines the alpha numeric atom, typically a - // component of names. This only allows lower case characters and digits. - alphaNumericRegexp = match(`[a-z0-9]+`) - - // separatorRegexp defines the separators allowed to be embedded in name - // components. This allow one period, one or two underscore and multiple - // dashes. - separatorRegexp = match(`(?:[._]|__|[-]*)`) - - // nameComponentRegexp restricts registry path component names to start - // with at least one letter or number, with following parts able to be - // separated by one period, one or two underscore and multiple dashes. - nameComponentRegexp = expression( - alphaNumericRegexp, - optional(repeated(separatorRegexp, alphaNumericRegexp))) - - // domainComponentRegexp restricts the registry domain component of a - // repository name to start with a component as defined by domainRegexp - // and followed by an optional port. - domainComponentRegexp = match(`(?:[a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9-]*[a-zA-Z0-9])`) - - // domainRegexp defines the structure of potential domain components - // that may be part of image names. This is purposely a subset of what is - // allowed by DNS to ensure backwards compatibility with Docker image - // names. - domainRegexp = expression( - domainComponentRegexp, - optional(repeated(literal(`.`), domainComponentRegexp)), - optional(literal(`:`), match(`[0-9]+`))) - - // NameRegexp is the format for the name component of references. The - // regexp has capturing groups for the domain and name part omitting - // the separating forward slash from either. - NameRegexp = expression( - optional(domainRegexp, literal(`/`)), - nameComponentRegexp, - optional(repeated(literal(`/`), nameComponentRegexp))) - - // anchoredNameRegexp is used to parse a name value, capturing the - // domain and trailing components. - anchoredNameRegexp = anchored( - optional(capture(domainRegexp), literal(`/`)), - capture(nameComponentRegexp, - optional(repeated(literal(`/`), nameComponentRegexp)))) - - // IdentifierRegexp is the format for string identifier used as a - // content addressable identifier using sha256. These identifiers - // are like digests without the algorithm, since sha256 is used. - IdentifierRegexp = match(`([a-f0-9]{64})`) - - // ShortIdentifierRegexp is the format used to represent a prefix - // of an identifier. A prefix may be used to match a sha256 identifier - // within a list of trusted identifiers. - ShortIdentifierRegexp = match(`([a-f0-9]{6,64})`) -) - -// match compiles the string to a regular expression. -var match = regexp.MustCompile - -// literal compiles s into a literal regular expression, escaping any regexp -// reserved characters. -func literal(s string) *regexp.Regexp { - re := match(regexp.QuoteMeta(s)) - - if _, complete := re.LiteralPrefix(); !complete { - panic("must be a literal") - } - - return re -} - -func splitDomain(name string) (string, string) { - match := anchoredNameRegexp.FindStringSubmatch(name) - if len(match) != 3 { - return "", name - } - return match[1], match[2] -} - -// expression defines a full expression, where each regular expression must -// follow the previous. -func expression(res ...*regexp.Regexp) *regexp.Regexp { - var s string - for _, re := range res { - s += re.String() - } - - return match(s) -} - -// optional wraps the expression in a non-capturing group and makes the -// production optional. -func optional(res ...*regexp.Regexp) *regexp.Regexp { - return match(group(expression(res...)).String() + `?`) -} - -// repeated wraps the regexp in a non-capturing group to get one or more -// matches. -func repeated(res ...*regexp.Regexp) *regexp.Regexp { - return match(group(expression(res...)).String() + `+`) -} - -// group wraps the regexp in a non-capturing group. -func group(res ...*regexp.Regexp) *regexp.Regexp { - return match(`(?:` + expression(res...).String() + `)`) -} - -// capture wraps the expression in a capturing group. -func capture(res ...*regexp.Regexp) *regexp.Regexp { - return match(`(` + expression(res...).String() + `)`) -} - -// anchored anchors the regular expression by adding start and end delimiters. -func anchored(res ...*regexp.Regexp) *regexp.Regexp { - return match(`^` + expression(res...).String() + `$`) -} diff --git a/pkg/storage/runtime.go b/pkg/storage/runtime.go deleted file mode 100644 index bc402f413..000000000 --- a/pkg/storage/runtime.go +++ /dev/null @@ -1,452 +0,0 @@ -package storage - -import ( - "encoding/json" - "fmt" - "time" - - "github.com/containers/image/copy" - istorage "github.com/containers/image/storage" - "github.com/containers/image/transports/alltransports" - "github.com/containers/image/types" - "github.com/containers/storage" - "github.com/opencontainers/image-spec/specs-go/v1" - "github.com/pkg/errors" - "github.com/sirupsen/logrus" -) - -var ( - // ErrInvalidPodName is returned when a pod name specified to a - // function call is found to be invalid (most often, because it's - // empty). - ErrInvalidPodName = errors.New("invalid pod name") - // ErrInvalidImageName is returned when an image name specified to a - // function call is found to be invalid (most often, because it's - // empty). - ErrInvalidImageName = errors.New("invalid image name") - // ErrInvalidContainerName is returned when a container name specified - // to a function call is found to be invalid (most often, because it's - // empty). - ErrInvalidContainerName = errors.New("invalid container name") - // ErrInvalidSandboxID is returned when a sandbox ID specified to a - // function call is found to be invalid (because it's either - // empty or doesn't match a valid sandbox). - ErrInvalidSandboxID = errors.New("invalid sandbox ID") - // ErrInvalidContainerID is returned when a container ID specified to a - // function call is found to be invalid (because it's either - // empty or doesn't match a valid container). - ErrInvalidContainerID = errors.New("invalid container ID") -) - -type runtimeService struct { - storageImageServer ImageServer - pauseImage string -} - -// ContainerInfo wraps a subset of information about a container: its ID and -// the locations of its nonvolatile and volatile per-container directories, -// along with a copy of the configuration blob from the image that was used to -// create the container, if the image had a configuration. -type ContainerInfo struct { - ID string - Dir string - RunDir string - Config *v1.Image -} - -// RuntimeServer wraps up various CRI-related activities into a reusable -// implementation. -type RuntimeServer interface { - // CreatePodSandbox creates a pod infrastructure container, using the - // specified PodID for the infrastructure container's ID. In the CRI - // view of things, a sandbox is distinct from its containers, including - // its infrastructure container, but at this level the sandbox is - // essentially the same as its infrastructure container, with a - // container's membership in a pod being signified by it listing the - // same pod ID in its metadata that the pod's other members do, and - // with the pod's infrastructure container having the same value for - // both its pod's ID and its container ID. - // Pointer arguments can be nil. Either the image name or ID can be - // omitted, but not both. All other arguments are required. - CreatePodSandbox(systemContext *types.SystemContext, podName, podID, imageName, imageID, containerName, metadataName, uid, namespace string, attempt uint32, copyOptions *copy.Options) (ContainerInfo, error) - // RemovePodSandbox deletes a pod sandbox's infrastructure container. - // The CRI expects that a sandbox can't be removed unless its only - // container is its infrastructure container, but we don't enforce that - // here, since we're just keeping track of it for higher level APIs. - RemovePodSandbox(idOrName string) error - - // GetContainerMetadata returns the metadata we've stored for a container. - GetContainerMetadata(idOrName string) (RuntimeContainerMetadata, error) - // SetContainerMetadata updates the metadata we've stored for a container. - SetContainerMetadata(idOrName string, metadata RuntimeContainerMetadata) error - - // CreateContainer creates a container with the specified ID. - // Pointer arguments can be nil. Either the image name or ID can be - // omitted, but not both. All other arguments are required. - CreateContainer(systemContext *types.SystemContext, podName, podID, imageName, imageID, containerName, containerID, metadataName string, attempt uint32, mountLabel string, copyOptions *copy.Options) (ContainerInfo, error) - // DeleteContainer deletes a container, unmounting it first if need be. - DeleteContainer(idOrName string) error - - // StartContainer makes sure a container's filesystem is mounted, and - // returns the location of its root filesystem, which is not guaranteed - // by lower-level drivers to never change. - StartContainer(idOrName string) (string, error) - // StopContainer attempts to unmount a container's root filesystem, - // freeing up any kernel resources which may be limited. - StopContainer(idOrName string) error - - // GetWorkDir returns the path of a nonvolatile directory on the - // filesystem (somewhere under the Store's Root directory) which can be - // used to store arbitrary data that is specific to the container. It - // will be removed automatically when the container is deleted. - GetWorkDir(id string) (string, error) - // GetRunDir returns the path of a volatile directory (does not survive - // the host rebooting, somewhere under the Store's RunRoot directory) - // on the filesystem which can be used to store arbitrary data that is - // specific to the container. It will be removed automatically when - // the container is deleted. - GetRunDir(id string) (string, error) -} - -// RuntimeContainerMetadata is the structure that we encode as JSON and store -// in the metadata field of storage.Container objects. It is used for -// specifying attributes of pod sandboxes and containers when they are being -// created, and allows a container's MountLabel, and possibly other values, to -// be modified in one read/write cycle via calls to -// RuntimeServer.ContainerMetadata, RuntimeContainerMetadata.SetMountLabel, -// and RuntimeServer.SetContainerMetadata. -type RuntimeContainerMetadata struct { - // Pod is true if this is the pod's infrastructure container. - Pod bool `json:"pod,omitempty"` // Applicable to both PodSandboxes and Containers - // The pod's name and ID, kept for use by upper layers in determining - // which containers belong to which pods. - PodName string `json:"pod-name"` // Applicable to both PodSandboxes and Containers, mandatory - PodID string `json:"pod-id"` // Applicable to both PodSandboxes and Containers, mandatory - // The provided name and the ID of the image that was used to - // instantiate the container. - ImageName string `json:"image-name"` // Applicable to both PodSandboxes and Containers - ImageID string `json:"image-id"` // Applicable to both PodSandboxes and Containers - // The container's name, which for an infrastructure container is usually PodName + "-infra". - ContainerName string `json:"name"` // Applicable to both PodSandboxes and Containers, mandatory - // The name as originally specified in PodSandbox or Container CRI metadata. - MetadataName string `json:"metadata-name"` // Applicable to both PodSandboxes and Containers, mandatory - UID string `json:"uid,omitempty"` // Only applicable to pods - Namespace string `json:"namespace,omitempty"` // Only applicable to pods - Attempt uint32 `json:"attempt,omitempty"` // Applicable to both PodSandboxes and Containers - CreatedAt int64 `json:"created-at"` // Applicable to both PodSandboxes and Containers - MountLabel string `json:"mountlabel,omitempty"` // Applicable to both PodSandboxes and Containers -} - -// SetMountLabel updates the mount label held by a RuntimeContainerMetadata -// object. -func (metadata *RuntimeContainerMetadata) SetMountLabel(mountLabel string) { - metadata.MountLabel = mountLabel -} - -func (r *runtimeService) createContainerOrPodSandbox(systemContext *types.SystemContext, podName, podID, imageName, imageID, containerName, containerID, metadataName, uid, namespace string, attempt uint32, mountLabel string, options *copy.Options) (ContainerInfo, error) { - var ref types.ImageReference - if podName == "" || podID == "" { - return ContainerInfo{}, ErrInvalidPodName - } - if imageName == "" && imageID == "" { - return ContainerInfo{}, ErrInvalidImageName - } - if containerName == "" { - return ContainerInfo{}, ErrInvalidContainerName - } - if metadataName == "" { - metadataName = containerName - } - - // Check if we have the specified image. - ref, err := istorage.Transport.ParseStoreReference(r.storageImageServer.GetStore(), imageName) - if err != nil { - // Maybe it's some other transport's copy of the image? - otherRef, err2 := alltransports.ParseImageName(imageName) - if err2 == nil && otherRef.DockerReference() != nil { - ref, err = istorage.Transport.ParseStoreReference(r.storageImageServer.GetStore(), otherRef.DockerReference().Name()) - } - if err != nil { - // Maybe the image ID is sufficient? - ref, err = istorage.Transport.ParseStoreReference(r.storageImageServer.GetStore(), "@"+imageID) - if err != nil { - return ContainerInfo{}, err - } - } - } - img, err := istorage.Transport.GetStoreImage(r.storageImageServer.GetStore(), ref) - if img == nil && errors.Cause(err) == storage.ErrImageUnknown && imageName == r.pauseImage { - image := imageID - if imageName != "" { - image = imageName - } - if image == "" { - return ContainerInfo{}, ErrInvalidImageName - } - logrus.Debugf("couldn't find image %q, retrieving it", image) - ref, err = r.storageImageServer.PullImage(systemContext, image, options) - if err != nil { - return ContainerInfo{}, err - } - img, err = istorage.Transport.GetStoreImage(r.storageImageServer.GetStore(), ref) - if err != nil { - return ContainerInfo{}, err - } - logrus.Debugf("successfully pulled image %q", image) - } - if img == nil && errors.Cause(err) == storage.ErrImageUnknown { - if imageID == "" { - return ContainerInfo{}, fmt.Errorf("image %q not present in image store", imageName) - } - if imageName == "" { - return ContainerInfo{}, fmt.Errorf("image with ID %q not present in image store", imageID) - } - return ContainerInfo{}, fmt.Errorf("image %q with ID %q not present in image store", imageName, imageID) - } - - // Pull out a copy of the image's configuration. - image, err := ref.NewImage(systemContext) - if err != nil { - return ContainerInfo{}, err - } - defer image.Close() - - imageConfig, err := image.OCIConfig() - if err != nil { - return ContainerInfo{}, err - } - - // Update the image name and ID. - if imageName == "" && len(img.Names) > 0 { - imageName = img.Names[0] - } - imageID = img.ID - - // Build metadata to store with the container. - metadata := RuntimeContainerMetadata{ - Pod: containerID == podID, - PodName: podName, - PodID: podID, - ImageName: imageName, - ImageID: imageID, - ContainerName: containerName, - MetadataName: metadataName, - UID: uid, - Namespace: namespace, - Attempt: attempt, - CreatedAt: time.Now().Unix(), - MountLabel: mountLabel, - } - mdata, err := json.Marshal(&metadata) - if err != nil { - return ContainerInfo{}, err - } - - // Build the container. - names := []string{metadata.ContainerName} - if metadata.Pod { - names = append(names, metadata.PodName) - } - container, err := r.storageImageServer.GetStore().CreateContainer(containerID, names, img.ID, "", string(mdata), nil) - if err != nil { - if metadata.Pod { - logrus.Debugf("failed to create pod sandbox %s(%s): %v", metadata.PodName, metadata.PodID, err) - } else { - logrus.Debugf("failed to create container %s(%s): %v", metadata.ContainerName, containerID, err) - } - return ContainerInfo{}, err - } - if metadata.Pod { - logrus.Debugf("created pod sandbox %q", container.ID) - } else { - logrus.Debugf("created container %q", container.ID) - } - - // If anything fails after this point, we need to delete the incomplete - // container before returning. - defer func() { - if err != nil { - if err2 := r.storageImageServer.GetStore().DeleteContainer(container.ID); err2 != nil { - if metadata.Pod { - logrus.Infof("%v deleting partially-created pod sandbox %q", err2, container.ID) - } else { - logrus.Infof("%v deleting partially-created container %q", err2, container.ID) - } - return - } - logrus.Infof("deleted partially-created container %q", container.ID) - } - }() - - // Add a name to the container's layer so that it's easier to follow - // what's going on if we're just looking at the storage-eye view of things. - layerName := metadata.ContainerName + "-layer" - names, err = r.storageImageServer.GetStore().Names(container.LayerID) - if err != nil { - return ContainerInfo{}, err - } - names = append(names, layerName) - err = r.storageImageServer.GetStore().SetNames(container.LayerID, names) - if err != nil { - return ContainerInfo{}, err - } - - // Find out where the container work directories are, so that we can return them. - containerDir, err := r.storageImageServer.GetStore().ContainerDirectory(container.ID) - if err != nil { - return ContainerInfo{}, err - } - if metadata.Pod { - logrus.Debugf("pod sandbox %q has work directory %q", container.ID, containerDir) - } else { - logrus.Debugf("container %q has work directory %q", container.ID, containerDir) - } - - containerRunDir, err := r.storageImageServer.GetStore().ContainerRunDirectory(container.ID) - if err != nil { - return ContainerInfo{}, err - } - if metadata.Pod { - logrus.Debugf("pod sandbox %q has run directory %q", container.ID, containerRunDir) - } else { - logrus.Debugf("container %q has run directory %q", container.ID, containerRunDir) - } - - return ContainerInfo{ - ID: container.ID, - Dir: containerDir, - RunDir: containerRunDir, - Config: imageConfig, - }, nil -} - -func (r *runtimeService) CreatePodSandbox(systemContext *types.SystemContext, podName, podID, imageName, imageID, containerName, metadataName, uid, namespace string, attempt uint32, copyOptions *copy.Options) (ContainerInfo, error) { - return r.createContainerOrPodSandbox(systemContext, podName, podID, imageName, imageID, containerName, podID, metadataName, uid, namespace, attempt, "", copyOptions) -} - -func (r *runtimeService) CreateContainer(systemContext *types.SystemContext, podName, podID, imageName, imageID, containerName, containerID, metadataName string, attempt uint32, mountLabel string, copyOptions *copy.Options) (ContainerInfo, error) { - return r.createContainerOrPodSandbox(systemContext, podName, podID, imageName, imageID, containerName, containerID, metadataName, "", "", attempt, mountLabel, copyOptions) -} - -func (r *runtimeService) RemovePodSandbox(idOrName string) error { - container, err := r.storageImageServer.GetStore().Container(idOrName) - if err != nil { - if errors.Cause(err) == storage.ErrContainerUnknown { - return ErrInvalidSandboxID - } - return err - } - err = r.storageImageServer.GetStore().DeleteContainer(container.ID) - if err != nil { - logrus.Debugf("failed to delete pod sandbox %q: %v", container.ID, err) - return err - } - return nil -} - -func (r *runtimeService) DeleteContainer(idOrName string) error { - if idOrName == "" { - return ErrInvalidContainerID - } - container, err := r.storageImageServer.GetStore().Container(idOrName) - if err != nil { - return err - } - err = r.storageImageServer.GetStore().DeleteContainer(container.ID) - if err != nil { - logrus.Debugf("failed to delete container %q: %v", container.ID, err) - return err - } - return nil -} - -func (r *runtimeService) SetContainerMetadata(idOrName string, metadata RuntimeContainerMetadata) error { - mdata, err := json.Marshal(&metadata) - if err != nil { - logrus.Debugf("failed to encode metadata for %q: %v", idOrName, err) - return err - } - return r.storageImageServer.GetStore().SetMetadata(idOrName, string(mdata)) -} - -func (r *runtimeService) GetContainerMetadata(idOrName string) (RuntimeContainerMetadata, error) { - metadata := RuntimeContainerMetadata{} - mdata, err := r.storageImageServer.GetStore().Metadata(idOrName) - if err != nil { - return metadata, err - } - if err = json.Unmarshal([]byte(mdata), &metadata); err != nil { - return metadata, err - } - return metadata, nil -} - -func (r *runtimeService) StartContainer(idOrName string) (string, error) { - container, err := r.storageImageServer.GetStore().Container(idOrName) - if err != nil { - if errors.Cause(err) == storage.ErrContainerUnknown { - return "", ErrInvalidContainerID - } - return "", err - } - metadata := RuntimeContainerMetadata{} - if err = json.Unmarshal([]byte(container.Metadata), &metadata); err != nil { - return "", err - } - mountPoint, err := r.storageImageServer.GetStore().Mount(container.ID, metadata.MountLabel) - if err != nil { - logrus.Debugf("failed to mount container %q: %v", container.ID, err) - return "", err - } - logrus.Debugf("mounted container %q at %q", container.ID, mountPoint) - return mountPoint, nil -} - -func (r *runtimeService) StopContainer(idOrName string) error { - if idOrName == "" { - return ErrInvalidContainerID - } - container, err := r.storageImageServer.GetStore().Container(idOrName) - if err != nil { - return err - } - err = r.storageImageServer.GetStore().Unmount(container.ID) - if err != nil { - logrus.Debugf("failed to unmount container %q: %v", container.ID, err) - return err - } - logrus.Debugf("unmounted container %q", container.ID) - return nil -} - -func (r *runtimeService) GetWorkDir(id string) (string, error) { - container, err := r.storageImageServer.GetStore().Container(id) - if err != nil { - if errors.Cause(err) == storage.ErrContainerUnknown { - return "", ErrInvalidContainerID - } - return "", err - } - return r.storageImageServer.GetStore().ContainerDirectory(container.ID) -} - -func (r *runtimeService) GetRunDir(id string) (string, error) { - container, err := r.storageImageServer.GetStore().Container(id) - if err != nil { - if errors.Cause(err) == storage.ErrContainerUnknown { - return "", ErrInvalidContainerID - } - return "", err - } - return r.storageImageServer.GetStore().ContainerRunDirectory(container.ID) -} - -// GetRuntimeService returns a RuntimeServer that uses the passed-in image -// service to pull and manage images, and its store to manage containers based -// on those images. -func GetRuntimeService(storageImageServer ImageServer, pauseImage string) RuntimeServer { - return &runtimeService{ - storageImageServer: storageImageServer, - pauseImage: pauseImage, - } -} diff --git a/vendor/github.com/cri-o/ocicni/pkg/ocicni/noop.go b/vendor/github.com/cri-o/ocicni/pkg/ocicni/noop.go deleted file mode 100644 index 9f315a7c6..000000000 --- a/vendor/github.com/cri-o/ocicni/pkg/ocicni/noop.go +++ /dev/null @@ -1,24 +0,0 @@ -package ocicni - -type cniNoOp struct { -} - -func (noop *cniNoOp) Name() string { - return "CNINoOp" -} - -func (noop *cniNoOp) SetUpPod(network PodNetwork) error { - return nil -} - -func (noop *cniNoOp) TearDownPod(network PodNetwork) error { - return nil -} - -func (noop *cniNoOp) GetPodNetworkStatus(network PodNetwork) (string, error) { - return "", nil -} - -func (noop *cniNoOp) Status() error { - return nil -} diff --git a/vendor/github.com/cri-o/ocicni/pkg/ocicni/ocicni.go b/vendor/github.com/cri-o/ocicni/pkg/ocicni/ocicni.go index 03918bfa4..8c7ce5571 100644 --- a/vendor/github.com/cri-o/ocicni/pkg/ocicni/ocicni.go +++ b/vendor/github.com/cri-o/ocicni/pkg/ocicni/ocicni.go @@ -3,6 +3,7 @@ package ocicni import ( "errors" "fmt" + "os" "os/exec" "sort" "strings" @@ -139,33 +140,11 @@ func (plugin *cniNetworkPlugin) monitorNetDir() { <-plugin.monitorNetDirChan } -// InitCNI takes the plugin directory and cni directories where the cni files should be searched for -// Returns a valid plugin object and any error +// InitCNI takes the plugin directory and CNI directories where the CNI config +// files should be searched for. If no valid CNI configs exist, network requests +// will fail until valid CNI config files are present in the config directory. func InitCNI(pluginDir string, cniDirs ...string) (CNIPlugin, error) { - plugin := probeNetworkPluginsWithVendorCNIDirPrefix(pluginDir, cniDirs, "") - var err error - plugin.nsenterPath, err = exec.LookPath("nsenter") - if err != nil { - return nil, err - } - - // check if a default network exists, otherwise dump the CNI search and return a noop plugin - _, err = getDefaultCNINetwork(plugin.pluginDir, plugin.cniDirs, plugin.vendorCNIDirPrefix) - if err != nil { - if err != errMissingDefaultNetwork { - logrus.Warningf("Error in finding usable CNI plugin - %v", err) - // create a noop plugin instead - return &cniNoOp{}, nil - } - - // We do not have a default network, we start the monitoring thread. - go plugin.monitorNetDir() - } - - return plugin, nil -} - -func probeNetworkPluginsWithVendorCNIDirPrefix(pluginDir string, cniDirs []string, vendorCNIDirPrefix string) *cniNetworkPlugin { + vendorCNIDirPrefix := "" plugin := &cniNetworkPlugin{ defaultNetwork: nil, loNetwork: getLoNetwork(cniDirs, vendorCNIDirPrefix), @@ -176,11 +155,26 @@ func probeNetworkPluginsWithVendorCNIDirPrefix(pluginDir string, cniDirs []strin pods: make(map[string]*podLock), } - // sync NetworkConfig in best effort during probing. + var err error + plugin.nsenterPath, err = exec.LookPath("nsenter") + if err != nil { + return nil, err + } + + // Fail loudly if plugin directory doesn't exist, because fsnotify watcher + // won't be able to watch it. + if _, err := os.Stat(pluginDir); err != nil { + return nil, err + } + if err := plugin.syncNetworkConfig(); err != nil { - logrus.Error(err) + // We do not have a valid default network, so start the + // monitoring thread. Network setup/teardown requests + // will fail until we have a valid default network. + go plugin.monitorNetDir() } - return plugin + + return plugin, nil } func getDefaultCNINetwork(pluginDir string, cniDirs []string, vendorCNIDirPrefix string) (*cniNetwork, error) { @@ -308,9 +302,9 @@ func (plugin *cniNetworkPlugin) Name() string { return CNIPluginName } -func (plugin *cniNetworkPlugin) SetUpPod(podNetwork PodNetwork) error { +func (plugin *cniNetworkPlugin) SetUpPod(podNetwork PodNetwork) (cnitypes.Result, error) { if err := plugin.checkInitialized(); err != nil { - return err + return nil, err } plugin.podLock(podNetwork).Lock() @@ -319,16 +313,16 @@ func (plugin *cniNetworkPlugin) SetUpPod(podNetwork PodNetwork) error { _, err := plugin.loNetwork.addToNetwork(podNetwork) if err != nil { logrus.Errorf("Error while adding to cni lo network: %s", err) - return err + return nil, err } - _, err = plugin.getDefaultNetwork().addToNetwork(podNetwork) + result, err := plugin.getDefaultNetwork().addToNetwork(podNetwork) if err != nil { logrus.Errorf("Error while adding to cni network: %s", err) - return err + return nil, err } - return err + return result, err } func (plugin *cniNetworkPlugin) TearDownPod(podNetwork PodNetwork) error { diff --git a/vendor/github.com/cri-o/ocicni/pkg/ocicni/types.go b/vendor/github.com/cri-o/ocicni/pkg/ocicni/types.go index a272e92e7..60816d179 100644 --- a/vendor/github.com/cri-o/ocicni/pkg/ocicni/types.go +++ b/vendor/github.com/cri-o/ocicni/pkg/ocicni/types.go @@ -1,5 +1,9 @@ package ocicni +import ( + "github.com/containernetworking/cni/pkg/types" +) + const ( // DefaultInterfaceName is the string to be used for the interface name inside the net namespace DefaultInterfaceName = "eth0" @@ -49,7 +53,7 @@ type CNIPlugin interface { // SetUpPod is the method called after the sandbox container of // the pod has been created but before the other containers of the // pod are launched. - SetUpPod(network PodNetwork) error + SetUpPod(network PodNetwork) (types.Result, error) // TearDownPod is the method called before a pod's sandbox container will be deleted TearDownPod(network PodNetwork) error |