// Exists return whether or not the service image already exists func Exists(ctx context.Context, clt client.ImageAPIClient, image string) (bool, error) { _, err := InspectImage(ctx, clt, image) if err != nil { if client.IsErrImageNotFound(err) { return false, nil } return false, err } return true, nil }
// OutOfSync checks if the container is out of sync with the service definition. // It looks if the the service hash container label is the same as the computed one. func (s *Service) OutOfSync(ctx context.Context, c *container.Container) (bool, error) { if c.ImageConfig() != s.serviceConfig.Image { logrus.Debugf("Images for %s do not match %s!=%s", c.Name(), c.ImageConfig(), s.serviceConfig.Image) return true, nil } expectedHash := config.GetServiceHash(s.name, s.Config()) if c.Hash() != expectedHash { logrus.Debugf("Hashes for %s do not match %s!=%s", c.Name(), c.Hash(), expectedHash) return true, nil } image, err := image.InspectImage(ctx, s.clientFactory.Create(s), c.ImageConfig()) if err != nil { if client.IsErrImageNotFound(err) { logrus.Debugf("Image %s do not exist, do not know if it's out of sync", c.Image()) return false, nil } return false, err } logrus.Debugf("Checking existing image name vs id: %s == %s", image.ID, c.Image()) return image.ID != c.Image(), err }
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 }