예제 #1
0
func createContainer(ctx context.Context, dockerCli *command.DockerCli, config *container.Config, hostConfig *container.HostConfig, networkingConfig *networktypes.NetworkingConfig, cidfile, name string) (*types.ContainerCreateResponse, error) {
	stderr := dockerCli.Err()

	var containerIDFile *cidFile
	if cidfile != "" {
		var err error
		if containerIDFile, err = newCIDFile(cidfile); err != nil {
			return nil, err
		}
		defer containerIDFile.Close()
	}

	var trustedRef reference.Canonical
	_, ref, err := reference.ParseIDOrReference(config.Image)
	if err != nil {
		return nil, err
	}
	if ref != nil {
		ref = reference.WithDefaultTag(ref)

		if ref, ok := ref.(reference.NamedTagged); ok && command.IsTrusted() {
			var err error
			trustedRef, err = image.TrustedReference(ctx, dockerCli, ref)
			if err != nil {
				return nil, err
			}
			config.Image = trustedRef.String()
		}
	}

	//create the container
	response, err := dockerCli.Client().ContainerCreate(ctx, config, hostConfig, networkingConfig, name)

	//if image not found try to pull it
	if err != nil {
		if apiclient.IsErrImageNotFound(err) && ref != nil {
			fmt.Fprintf(stderr, "Unable to find image '%s' locally\n", ref.String())

			// we don't want to write to stdout anything apart from container.ID
			if err = pullImage(ctx, dockerCli, config.Image, stderr); err != nil {
				return nil, err
			}
			if ref, ok := ref.(reference.NamedTagged); ok && trustedRef != nil {
				if err := image.TagTrusted(ctx, dockerCli, trustedRef, ref); err != nil {
					return nil, err
				}
			}
			// Retry
			var retryErr error
			response, retryErr = dockerCli.Client().ContainerCreate(ctx, config, hostConfig, networkingConfig, name)
			if retryErr != nil {
				return nil, retryErr
			}
		} else {
			return nil, err
		}
	}

	for _, warning := range response.Warnings {
		fmt.Fprintf(stderr, "WARNING: %s\n", warning)
	}
	if containerIDFile != nil {
		if err = containerIDFile.Write(response.ID); err != nil {
			return nil, err
		}
	}
	return &response, nil
}
예제 #2
0
파일: install.go 프로젝트: docker/docker
func runInstall(dockerCli *command.DockerCli, opts pluginOptions) error {
	// Parse name using distribution reference package to support name
	// containing both tag and digest. Names with both tag and digest
	// will be treated by the daemon as a pull by digest with
	// an alias for the tag (if no alias is provided).
	ref, err := distreference.ParseNamed(opts.name)
	if err != nil {
		return err
	}

	alias := ""
	if opts.alias != "" {
		aref, err := reference.ParseNamed(opts.alias)
		if err != nil {
			return err
		}
		aref = reference.WithDefaultTag(aref)
		if _, ok := aref.(reference.NamedTagged); !ok {
			return fmt.Errorf("invalid name: %s", opts.alias)
		}
		alias = aref.String()
	}
	ctx := context.Background()

	index, err := getRepoIndexFromUnnormalizedRef(ref)
	if err != nil {
		return err
	}

	remote := ref.String()

	_, isCanonical := ref.(distreference.Canonical)
	if command.IsTrusted() && !isCanonical {
		if alias == "" {
			alias = ref.String()
		}
		var nt reference.NamedTagged
		named, err := reference.ParseNamed(ref.Name())
		if err != nil {
			return err
		}
		if tagged, ok := ref.(distreference.Tagged); ok {
			nt, err = reference.WithTag(named, tagged.Tag())
			if err != nil {
				return err
			}
		} else {
			named = reference.WithDefaultTag(named)
			nt = named.(reference.NamedTagged)
		}

		trusted, err := image.TrustedReference(ctx, dockerCli, nt, newRegistryService())
		if err != nil {
			return err
		}
		remote = trusted.String()
	}

	authConfig := command.ResolveAuthConfig(ctx, dockerCli, index)

	encodedAuth, err := command.EncodeAuthToBase64(authConfig)
	if err != nil {
		return err
	}

	registryAuthFunc := command.RegistryAuthenticationPrivilegedFunc(dockerCli, index, "plugin install")

	options := types.PluginInstallOptions{
		RegistryAuth:          encodedAuth,
		RemoteRef:             remote,
		Disabled:              opts.disable,
		AcceptAllPermissions:  opts.grantPerms,
		AcceptPermissionsFunc: acceptPrivileges(dockerCli, opts.name),
		// TODO: Rename PrivilegeFunc, it has nothing to do with privileges
		PrivilegeFunc: registryAuthFunc,
		Args:          opts.args,
	}

	responseBody, err := dockerCli.Client().PluginInstall(ctx, alias, options)
	if err != nil {
		if strings.Contains(err.Error(), "target is image") {
			return errors.New(err.Error() + " - Use `docker image pull`")
		}
		return err
	}
	defer responseBody.Close()
	if err := jsonmessage.DisplayJSONMessagesToStream(responseBody, dockerCli.Out(), nil); err != nil {
		return err
	}
	fmt.Fprintf(dockerCli.Out(), "Installed plugin %s\n", opts.name) // todo: return proper values from the API for this result
	return nil
}