// convertToContainerDef transforms each service in the compose yml // to an equivalent container definition func convertToContainerDef(inputCfg *libcompose.ServiceConfig, volumes map[string]string, outputContDef *ecs.ContainerDefinition) error { // setting memory var mem int64 if inputCfg.MemLimit != 0 { mem = inputCfg.MemLimit / kiB / kiB // convert bytes to MiB } if mem == 0 { mem = defaultMemLimit } // convert environment variables // TODO, read env file environment := []*ecs.KeyValuePair{} for _, env := range inputCfg.Environment.Slice() { parts := strings.SplitN(env, "=", 2) name := &parts[0] var value *string if len(parts) > 1 { value = &parts[1] } environment = append(environment, &ecs.KeyValuePair{ Name: name, Value: value, }) } // convert port mappings portMappings, err := convertToPortMappings(*outputContDef.Name, inputCfg.Ports) if err != nil { return err } // convert volumes from volumesFrom := []*ecs.VolumeFrom{} for _, val := range inputCfg.VolumesFrom { volumeFrom := &ecs.VolumeFrom{ SourceContainer: aws.String(val), } volumesFrom = append(volumesFrom, volumeFrom) } // convert mount points mountPoints, err := convertToMountPoints(inputCfg.Volumes, volumes) if err != nil { return err } // populating container definition, offloading the validation to aws-sdk outputContDef.Cpu = aws.Int64(inputCfg.CpuShares) outputContDef.Memory = aws.Int64(mem) outputContDef.EntryPoint = aws.StringSlice(inputCfg.Entrypoint.Slice()) outputContDef.Command = aws.StringSlice(inputCfg.Command.Slice()) outputContDef.Environment = environment outputContDef.Image = aws.String(inputCfg.Image) outputContDef.Links = aws.StringSlice(inputCfg.Links.Slice()) //TODO, read from external links outputContDef.MountPoints = mountPoints outputContDef.PortMappings = portMappings outputContDef.VolumesFrom = volumesFrom return nil }
func containerDef(family *string, containerPort *int64, hostPort *int64, image *string, cpu *int64, memory *int64, essential bool, links []*string) *ecs.ContainerDefinition { portMapping := &ecs.PortMapping{ ContainerPort: containerPort, HostPort: hostPort, Protocol: aws.String("tcp"), } mountPoint := &ecs.MountPoint{ ContainerPath: aws.String("/var/www/" + (*family) + "-vol"), SourceVolume: aws.String(*family + "-vol"), ReadOnly: aws.Bool(false), } c := ecs.ContainerDefinition{} c.Name = aws.String(*family + "-app") c.Image = image c.Cpu = cpu c.Memory = memory c.Essential = aws.Bool(essential) c.Links = links if *hostPort != 0 { c.PortMappings = []*ecs.PortMapping{portMapping} } c.MountPoints = []*ecs.MountPoint{mountPoint} return &c }
// // Called by createTask() above. Given a filename, parse the JSON file and create a ContainerDefinition // struct that can be passed to the SDK to create the task definition. // func makeTaskDefinition(taskFile string) (ecs.ContainerDefinition, string) { var taskJSON TaskDefn // Do it the easy way and read in the whole file. A JSON file's not going to be very large. fileBytes, err := ioutil.ReadFile(taskFile) CheckError(fmt.Sprintf("Error reading task file %s", taskFile), err) err = json.Unmarshal(fileBytes, &taskJSON) CheckError(fmt.Sprintf("Error reading task file %s", taskFile), err) // TODO: Support more than one if it's ever needed. if len(taskJSON.ContainerDefinitions) > 1 { fmt.Println("Right now I only support a single ContainerDefinition, sorry. Please edit and try again.") os.Exit(1) } // Now let's construct our Container Definition object, which is a lot of boring copying of fields. var defn ecs.ContainerDefinition defn.Cpu = &taskJSON.ContainerDefinitions[0].CPU var commands = make([]*string, 0) for i := 0; i < len(taskJSON.ContainerDefinitions[0].Command); i++ { commands = append(commands, &taskJSON.ContainerDefinitions[0].Command[i]) } defn.Command = commands var entrypoints = make([]*string, 0) for i := 0; i < len(taskJSON.ContainerDefinitions[0].EntryPoint); i++ { entrypoints = append(entrypoints, &taskJSON.ContainerDefinitions[0].EntryPoint[i]) } defn.EntryPoint = entrypoints var environments = make([]*ecs.KeyValuePair, 0) for i := 0; i < len(taskJSON.ContainerDefinitions[0].Environment); i++ { var keyval ecs.KeyValuePair keyval.Name = taskJSON.ContainerDefinitions[0].Environment[i].Name keyval.Value = taskJSON.ContainerDefinitions[0].Environment[i].Value environments = append(environments, &keyval) } defn.Environment = environments defn.Essential = &taskJSON.ContainerDefinitions[0].Essential defn.Image = &taskJSON.ContainerDefinitions[0].Image defn.Memory = &taskJSON.ContainerDefinitions[0].Memory defn.Name = &taskJSON.ContainerDefinitions[0].Name var ports = make([]*ecs.PortMapping, 0) for i := 0; i < len(taskJSON.ContainerDefinitions[0].PortMappings); i++ { var portmap ecs.PortMapping portmap.ContainerPort = taskJSON.ContainerDefinitions[0].PortMappings[i].ContainerPort portmap.HostPort = taskJSON.ContainerDefinitions[0].PortMappings[i].HostPort ports = append(ports, &portmap) } defn.PortMappings = ports return defn, taskJSON.Family }
func consulDefinition(hostname *string, serverIP *string, advertiseIP *string) *ecs.ContainerDefinition { c := ecs.ContainerDefinition{} c.Name = aws.String("kinja-consul-agent") c.Hostname = hostname c.Image = aws.String("progrium/consul") c.Cpu = aws.Int64(156) c.Memory = aws.Int64(256) c.Essential = aws.Bool(true) c.PortMappings = []*ecs.PortMapping{ &ecs.PortMapping{ ContainerPort: aws.Int64(8301), HostPort: aws.Int64(8301), Protocol: aws.String("tcp"), }, &ecs.PortMapping{ ContainerPort: aws.Int64(8301), HostPort: aws.Int64(8301), Protocol: aws.String("udp"), }, &ecs.PortMapping{ ContainerPort: aws.Int64(8400), HostPort: aws.Int64(8400), Protocol: aws.String("tcp"), }, &ecs.PortMapping{ ContainerPort: aws.Int64(8500), HostPort: aws.Int64(8500), Protocol: aws.String("tcp"), }, &ecs.PortMapping{ ContainerPort: aws.Int64(53), HostPort: aws.Int64(53), Protocol: aws.String("udp"), }, } c.MountPoints = []*ecs.MountPoint{ &ecs.MountPoint{ ContainerPath: aws.String("/data"), SourceVolume: aws.String("consul-vol"), ReadOnly: aws.Bool(false), }, &ecs.MountPoint{ ContainerPath: aws.String("/var/run/docker.sock"), SourceVolume: aws.String("consul-socket"), ReadOnly: aws.Bool(false), }, &ecs.MountPoint{ ContainerPath: aws.String("/etc/consul"), SourceVolume: aws.String("consul-config"), ReadOnly: aws.Bool(false), }, } session := sess.InitSession() c.Command = []*string{ aws.String("--join " + *serverIP), //aws.String("--advertise $(curl -s http://169.254.169.254/latest/meta-data/local-ipv4)"), aws.String("--advertise " + *advertiseIP), aws.String("-dc " + *session.Config.Region), aws.String("--config-file /etc/consul/consul.json"), } return &c }
// convertToContainerDef transforms each service in the compose yml // to an equivalent container definition func convertToContainerDef(inputCfg *libcompose.ServiceConfig, volumes map[string]string, outputContDef *ecs.ContainerDefinition) error { // setting memory var mem int64 if inputCfg.MemLimit != 0 { mem = inputCfg.MemLimit / kiB / kiB // convert bytes to MiB } if mem == 0 { mem = defaultMemLimit } // convert environment variables // TODO, read env file environment := []*ecs.KeyValuePair{} for _, env := range inputCfg.Environment.Slice() { parts := strings.SplitN(env, "=", 2) name := &parts[0] var value *string if len(parts) > 1 { value = &parts[1] } environment = append(environment, &ecs.KeyValuePair{ Name: name, Value: value, }) } // convert port mappings portMappings, err := convertToPortMappings(*outputContDef.Name, inputCfg.Ports) if err != nil { return err } // convert volumes from volumesFrom := []*ecs.VolumeFrom{} for _, val := range inputCfg.VolumesFrom { volumeFrom := &ecs.VolumeFrom{ SourceContainer: aws.String(val), } volumesFrom = append(volumesFrom, volumeFrom) } // convert mount points mountPoints, err := convertToMountPoints(inputCfg.Volumes, volumes) if err != nil { return err } // convert extra hosts extraHosts, err := convertToExtraHosts(inputCfg.ExtraHosts) if err != nil { return err } // convert log configuration var logConfig *ecs.LogConfiguration if inputCfg.LogDriver != "" { logConfig = &ecs.LogConfiguration{ LogDriver: aws.String(inputCfg.LogDriver), Options: aws.StringMap(inputCfg.LogOpt), } } // convert ulimits ulimits, err := convertToULimits(inputCfg.ULimits) if err != nil { return err } // populating container definition, offloading the validation to aws-sdk outputContDef.Cpu = aws.Int64(inputCfg.CpuShares) outputContDef.Command = aws.StringSlice(inputCfg.Command.Slice()) outputContDef.DnsSearchDomains = aws.StringSlice(inputCfg.DNSSearch.Slice()) outputContDef.DnsServers = aws.StringSlice(inputCfg.DNS.Slice()) outputContDef.DockerLabels = aws.StringMap(inputCfg.Labels.MapParts()) outputContDef.DockerSecurityOptions = aws.StringSlice(inputCfg.SecurityOpt) outputContDef.EntryPoint = aws.StringSlice(inputCfg.Entrypoint.Slice()) outputContDef.Environment = environment outputContDef.ExtraHosts = extraHosts if inputCfg.Hostname != "" { outputContDef.Hostname = aws.String(inputCfg.Hostname) } outputContDef.Image = aws.String(inputCfg.Image) outputContDef.Links = aws.StringSlice(inputCfg.Links.Slice()) //TODO, read from external links outputContDef.LogConfiguration = logConfig outputContDef.Memory = aws.Int64(mem) outputContDef.MountPoints = mountPoints outputContDef.Privileged = aws.Bool(inputCfg.Privileged) outputContDef.PortMappings = portMappings outputContDef.ReadonlyRootFilesystem = aws.Bool(inputCfg.ReadOnly) outputContDef.Ulimits = ulimits if inputCfg.User != "" { outputContDef.User = aws.String(inputCfg.User) } outputContDef.VolumesFrom = volumesFrom if inputCfg.WorkingDir != "" { outputContDef.WorkingDirectory = aws.String(inputCfg.WorkingDir) } return nil }
func main() { fmt.Printf("Drone AWS ECS Plugin built at %s\n", buildDate) workspace := drone.Workspace{} repo := drone.Repo{} build := drone.Build{} vargs := Params{} plugin.Param("workspace", &workspace) plugin.Param("repo", &repo) plugin.Param("build", &build) plugin.Param("vargs", &vargs) plugin.MustParse() if len(vargs.AccessKey) == 0 { fmt.Println("Please provide an access key") os.Exit(1) return } if len(vargs.SecretKey) == 0 { fmt.Println("Please provide a secret key") os.Exit(1) return } if len(vargs.Region) == 0 { fmt.Println("Please provide a region") os.Exit(1) return } if len(vargs.Family) == 0 { fmt.Println("Please provide a task definition family name") os.Exit(1) return } if len(vargs.Image) == 0 { fmt.Println("Please provide an image name") os.Exit(1) return } if len(vargs.Tag) == 0 { vargs.Tag = "latest" } if len(vargs.Service) == 0 { fmt.Println("Please provide a service name") os.Exit(1) return } if vargs.Memory == 0 { vargs.Memory = 128 } svc := ecs.New( session.New(&aws.Config{ Region: aws.String(vargs.Region), Credentials: credentials.NewStaticCredentials(vargs.AccessKey, vargs.SecretKey, ""), })) Image := vargs.Image + ":" + vargs.Tag definition := ecs.ContainerDefinition{ Command: []*string{}, DnsSearchDomains: []*string{}, DnsServers: []*string{}, DockerLabels: map[string]*string{}, DockerSecurityOptions: []*string{}, EntryPoint: []*string{}, Environment: []*ecs.KeyValuePair{}, Essential: aws.Bool(true), ExtraHosts: []*ecs.HostEntry{}, Image: aws.String(Image), Links: []*string{}, Memory: aws.Int64(vargs.Memory), MountPoints: []*ecs.MountPoint{}, Name: aws.String(vargs.Family + "-container"), PortMappings: []*ecs.PortMapping{}, Ulimits: []*ecs.Ulimit{}, //User: aws.String("String"), VolumesFrom: []*ecs.VolumeFrom{}, //WorkingDirectory: aws.String("String"), } // Port mappings for _, portMapping := range vargs.PortMappings.Slice() { cleanedPortMapping := strings.Trim(portMapping, " ") parts := strings.SplitN(cleanedPortMapping, " ", 2) hostPort, hostPortErr := strconv.ParseInt(parts[0], 10, 64) if hostPortErr != nil { fmt.Println(hostPortErr.Error()) os.Exit(1) return } containerPort, containerPortError := strconv.ParseInt(parts[1], 10, 64) if containerPortError != nil { fmt.Println(containerPortError.Error()) os.Exit(1) return } pair := ecs.PortMapping{ ContainerPort: aws.Int64(containerPort), HostPort: aws.Int64(hostPort), Protocol: aws.String("TransportProtocol"), } definition.PortMappings = append(definition.PortMappings, &pair) } // Environment variables for _, envVar := range vargs.Environment.Slice() { parts := strings.SplitN(envVar, "=", 2) pair := ecs.KeyValuePair{ Name: aws.String(strings.Trim(parts[0], " ")), Value: aws.String(strings.Trim(parts[1], " ")), } definition.Environment = append(definition.Environment, &pair) } params := &ecs.RegisterTaskDefinitionInput{ ContainerDefinitions: []*ecs.ContainerDefinition{ &definition, }, Family: aws.String(vargs.Family), Volumes: []*ecs.Volume{}, } resp, err := svc.RegisterTaskDefinition(params) if err != nil { fmt.Println(err.Error()) os.Exit(1) return } val := *(resp.TaskDefinition.TaskDefinitionArn) sparams := &ecs.UpdateServiceInput{ Service: aws.String(vargs.Service), TaskDefinition: aws.String(val), } sresp, serr := svc.UpdateService(sparams) if serr != nil { fmt.Println(serr.Error()) return } fmt.Println(sresp) fmt.Println(resp) }
// convertToContainerDef transforms each service in the compose yml // to an equivalent container definition func convertToContainerDef(context *project.Context, inputCfg *config.ServiceConfig, volumes map[string]string, outputContDef *ecs.ContainerDefinition) error { // setting memory var mem int64 if inputCfg.MemLimit != 0 { mem = int64(inputCfg.MemLimit) / kiB / kiB // convert bytes to MiB } if mem == 0 { mem = defaultMemLimit } // convert environment variables environment := convertToKeyValuePairs(context, inputCfg.Environment, *outputContDef.Name) // convert port mappings portMappings, err := convertToPortMappings(*outputContDef.Name, inputCfg.Ports) if err != nil { return err } // convert volumes from volumesFrom, err := convertToVolumesFrom(inputCfg.VolumesFrom) if err != nil { return err } // convert mount points mountPoints, err := convertToMountPoints(inputCfg.Volumes, volumes) if err != nil { return err } // convert extra hosts extraHosts, err := convertToExtraHosts(inputCfg.ExtraHosts) if err != nil { return err } // convert log configuration var logConfig *ecs.LogConfiguration if inputCfg.Logging.Driver != "" { logConfig = &ecs.LogConfiguration{ LogDriver: aws.String(inputCfg.Logging.Driver), Options: aws.StringMap(inputCfg.Logging.Options), } } // convert ulimits ulimits, err := convertToULimits(inputCfg.Ulimits) if err != nil { return err } // populating container definition, offloading the validation to aws-sdk outputContDef.Cpu = aws.Int64(int64(inputCfg.CPUShares)) outputContDef.Command = aws.StringSlice(inputCfg.Command) outputContDef.DnsSearchDomains = aws.StringSlice(inputCfg.DNSSearch) outputContDef.DnsServers = aws.StringSlice(inputCfg.DNS) outputContDef.DockerLabels = aws.StringMap(inputCfg.Labels) outputContDef.DockerSecurityOptions = aws.StringSlice(inputCfg.SecurityOpt) outputContDef.EntryPoint = aws.StringSlice(inputCfg.Entrypoint) outputContDef.Environment = environment outputContDef.ExtraHosts = extraHosts if inputCfg.Hostname != "" { outputContDef.Hostname = aws.String(inputCfg.Hostname) } outputContDef.Image = aws.String(inputCfg.Image) outputContDef.Links = aws.StringSlice(inputCfg.Links) //TODO, read from external links outputContDef.LogConfiguration = logConfig outputContDef.Memory = aws.Int64(mem) outputContDef.MountPoints = mountPoints outputContDef.Privileged = aws.Bool(inputCfg.Privileged) outputContDef.PortMappings = portMappings outputContDef.ReadonlyRootFilesystem = aws.Bool(inputCfg.ReadOnly) outputContDef.Ulimits = ulimits if inputCfg.User != "" { outputContDef.User = aws.String(inputCfg.User) } outputContDef.VolumesFrom = volumesFrom if inputCfg.WorkingDir != "" { outputContDef.WorkingDirectory = aws.String(inputCfg.WorkingDir) } return nil }