func StartApparatchik(dockerClient *docker.Client) (*Apparatchik, error) { dockerEventsChannel := make(chan *docker.APIEvents, 20) err := dockerClient.AddEventListener(dockerEventsChannel) if err != nil { return nil, err } apparatchick := &Apparatchik{ applications: map[string]*Application{}, dockerClient: dockerClient, dockerEventsChannel: dockerEventsChannel, Emitter: emission.NewEmitter(), } apparatchick.Emitter.SetMaxListeners(MaxListeners) // call HandleDockerEvent for every new docker event // in a separate go-routine go func() { for evt := range dockerEventsChannel { apparatchick.HandleDockerEvent(evt) } }() apparatchick.Emitter.Emit("applications", apparatchick.applicatioNames()) return apparatchick, nil }
func NewApplication(applicationName string, applicationConfiguration *ApplicationConfiguration, dockerClient *docker.Client) *Application { fileName := "/applications/" + applicationName + ".json" json, err := json.Marshal(applicationConfiguration) if err != nil { panic(err) } ioutil.WriteFile(fileName, json, 0644) emitter := emission.NewEmitter() emitter.SetMaxListeners(MaxListeners) app := &Application{ Name: applicationName, Configuration: applicationConfiguration, Goals: map[string]*Goal{}, MainGoal: applicationConfiguration.MainGoal, ApplicationFileName: fileName, DockerClient: dockerClient, Emitter: emitter, } app.startGoals() app.Emit("update", app.Status()) return app }
func NewGoal(application *Application, goalName string, applicationName string, configs map[string]*GoalConfiguration, dockerClient *docker.Client) *Goal { config := configs[goalName] emitter := emission.NewEmitter() emitter.SetMaxListeners(MaxListeners) goal := &Goal{ application: application, Name: goalName, ApplicationName: applicationName, DockerClient: dockerClient, CurrentStatus: "not_running", RunAfterStatuses: map[string]string{}, LinksStatuses: map[string]string{}, AuthConfig: config.AuthConfig, transitionLog: []TransitionLogEntry{}, UpstreamGoalStatuses: map[string]string{}, SmartRestart: config.SmartRestart, CreateContainerOptions: docker.CreateContainerOptions{ Name: containerName(applicationName, goalName, config.ContainerName), Config: &docker.Config{ Image: config.Image, Cmd: config.Command, ExposedPorts: map[docker.Port]struct{}{}, Env: []string{}, Labels: config.Labels, WorkingDir: config.WorkingDir, Entrypoint: config.Entrypoint, User: config.User, Hostname: config.Hostname, Domainname: config.Domainname, MacAddress: config.MacAddress, OpenStdin: config.StdinOpen, Tty: config.Tty, VolumeDriver: config.VolumeDrvier, AttachStdin: config.AttachStdin, AttachStdout: config.AttachStdout, AttachStderr: config.AttachStderr, }, HostConfig: &docker.HostConfig{ ExtraHosts: config.ExtraHosts, PortBindings: map[docker.Port][]docker.PortBinding{}, Binds: []string{}, CapAdd: config.CapAdd, CapDrop: config.CapDrop, DNSSearch: config.DNSSearch, Devices: []docker.Device{}, SecurityOpt: config.SecurityOpt, Memory: config.MemLimit, MemorySwap: config.MemSwapLimit, Privileged: config.Privileged, CPUShares: config.CpuShares, CPUSetCPUs: config.CpuSet, CPUSetMEMs: config.CpuSet, ReadonlyRootfs: config.ReadOnly, }, }, Emitter: emitter, } if config.Restart != "" { goal.CreateContainerOptions.HostConfig.RestartPolicy = docker.RestartPolicy{Name: config.Restart} } for _, deviceString := range config.Devices { parts := strings.Split(deviceString, ":") perm := "mrw" hostDevice := parts[0] containerDevice := parts[0] if len(parts) == 3 { perm = parts[2] containerDevice = parts[1] } else if len(parts) == 2 { if len(parts[1]) > 3 { containerDevice = parts[1] } else { containerDevice = parts[0] perm = parts[1] } } goal.CreateContainerOptions.HostConfig.Devices = append(goal.CreateContainerOptions.HostConfig.Devices, docker.Device{ PathOnHost: hostDevice, PathInContainer: containerDevice, CgroupPermissions: perm}) } if len(config.Dns) != 0 { goal.CreateContainerOptions.HostConfig.DNS = config.Dns } if config.Net != "" { goal.CreateContainerOptions.HostConfig.NetworkMode = config.Net } if config.LogDriver != "" { goal.CreateContainerOptions.HostConfig.LogConfig = docker.LogConfig{ Type: config.LogDriver, Config: config.LogConfig, } } for k, v := range config.Environment { goal.CreateContainerOptions.Config.Env = append(goal.CreateContainerOptions.Config.Env, k+"="+v) } for _, bind := range config.Volumes { parts := strings.Split(bind, ":") if len(parts) == 1 { goal.CreateContainerOptions.HostConfig.Binds = append(goal.CreateContainerOptions.HostConfig.Binds, replaceRelativePath(parts[0]+":"+parts[0])) } else if len(parts) == 2 { if parts[1] == "rw" || parts[1] == "ro" { goal.CreateContainerOptions.HostConfig.Binds = append(goal.CreateContainerOptions.HostConfig.Binds, replaceRelativePath(parts[0]+":"+parts[0]+":"+parts[1])) } else { goal.CreateContainerOptions.HostConfig.Binds = append(goal.CreateContainerOptions.HostConfig.Binds, replaceRelativePath(bind)) } } else { goal.CreateContainerOptions.HostConfig.Binds = append(goal.CreateContainerOptions.HostConfig.Binds, replaceRelativePath(bind)) } } for _, name := range config.RunAfter { goal.RunAfterStatuses[name] = "unknown" } for _, link := range config.Links { parts := strings.Split(link, ":") name := parts[0] alias := name if len(parts) > 1 { alias = parts[1] } goal.LinksStatuses[name] = "unknown" goal.CreateContainerOptions.HostConfig.Links = append(goal.CreateContainerOptions.HostConfig.Links, containerName(applicationName, name, configs[name].ContainerName)+":"+alias) } for _, link := range config.ExternalLinks { parts := strings.Split(link, ":") name := parts[0] alias := name if len(parts) > 1 { alias = parts[1] } goal.CreateContainerOptions.HostConfig.Links = append(goal.CreateContainerOptions.HostConfig.Links, name+":"+alias) } for _, port := range config.Ports { protoParts := strings.Split(port, "/") proto := "tcp" if len(protoParts) == 2 { proto = protoParts[1] } parts := strings.Split(protoParts[0], ":") hostPort := "" containerPort := parts[0] if len(parts) == 2 { hostPort = parts[0] containerPort = parts[1] portBinding := docker.PortBinding{HostPort: hostPort} goal.CreateContainerOptions.HostConfig.PortBindings[docker.Port(containerPort+"/"+proto)] = []docker.PortBinding{portBinding} } else { goal.CreateContainerOptions.HostConfig.PortBindings[docker.Port(containerPort+"/"+proto)] = []docker.PortBinding{} } } for _, port := range config.Expose { protoParts := strings.Split(port, "/") proto := "tcp" if len(protoParts) == 2 { proto = protoParts[1] } goal.CreateContainerOptions.Config.ExposedPorts[docker.Port(protoParts[0]+"/"+proto)] = struct{}{} } goal.FetchImage() goal.broadcastStatus() return goal }