Example #1
0
func addServices(p *project.Project, enabled map[interface{}]interface{}, configs map[string]*composeConfig.ServiceConfigV1) map[interface{}]interface{} {
	serviceConfigsV2, _ := composeConfig.ConvertServices(configs)

	// Note: we ignore errors while loading services
	unchanged := true
	for name, serviceConfig := range serviceConfigsV2 {
		hash := composeConfig.GetServiceHash(name, serviceConfig)

		if enabled[name] == hash {
			continue
		}

		if err := p.AddConfig(name, serviceConfig); err != nil {
			log.Infof("Failed loading service %s", name)
			continue
		}

		if unchanged {
			enabled = util.MapCopy(enabled)
			unchanged = false
		}
		enabled[name] = hash
	}
	return enabled
}
Example #2
0
func (s *Service) createContainer(ctx context.Context, namer Namer, oldContainer string, configOverride *config.ServiceConfig, oneOff bool) (*composecontainer.Container, error) {
	serviceConfig := s.serviceConfig
	if configOverride != nil {
		serviceConfig.Command = configOverride.Command
		serviceConfig.Tty = configOverride.Tty
		serviceConfig.StdinOpen = configOverride.StdinOpen
	}
	configWrapper, err := ConvertToAPI(serviceConfig, s.context.Context, s.clientFactory)
	if err != nil {
		return nil, err
	}
	configWrapper.Config.Image = s.imageName()

	containerName, containerNumber := namer.Next()

	configWrapper.Config.Labels[labels.SERVICE.Str()] = s.name
	configWrapper.Config.Labels[labels.PROJECT.Str()] = s.project.Name
	configWrapper.Config.Labels[labels.HASH.Str()] = config.GetServiceHash(s.name, serviceConfig)
	configWrapper.Config.Labels[labels.ONEOFF.Str()] = strings.Title(strconv.FormatBool(oneOff))
	configWrapper.Config.Labels[labels.NUMBER.Str()] = fmt.Sprintf("%d", containerNumber)
	configWrapper.Config.Labels[labels.VERSION.Str()] = project.ComposeVersion

	err = s.populateAdditionalHostConfig(configWrapper.HostConfig)
	if err != nil {
		return nil, err
	}

	// FIXME(vdemeester): oldContainer should be a Container instead of a string
	client := s.clientFactory.Create(s)
	if oldContainer != "" {
		info, err := client.ContainerInspect(ctx, oldContainer)
		if err != nil {
			return nil, err
		}
		configWrapper.HostConfig.Binds = util.Merge(configWrapper.HostConfig.Binds, volumeBinds(configWrapper.Config.Volumes, &info))
	}

	logrus.Debugf("Creating container %s %#v", containerName, configWrapper)
	// FIXME(vdemeester): long-term will be container.Create(…)
	container, err := composecontainer.Create(ctx, client, containerName, configWrapper.Config, configWrapper.HostConfig, configWrapper.NetworkingConfig)
	if err != nil {
		return nil, err
	}
	s.project.Notify(events.ContainerCreated, s.name, map[string]string{
		"name": containerName,
	})
	return container, nil
}
Example #3
0
// 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
}
Example #4
0
func (c *Container) getHash() string {
	return config.GetServiceHash(c.service.Name(), c.service.Config())
}