Created
November 25, 2015 05:39
-
-
Save lox/a8f77c7afcec6cbabf25 to your computer and use it in GitHub Desktop.
Convert from docker-compose.yml to ecs task definition in golang
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package transform | |
import ( | |
"errors" | |
"fmt" | |
"strconv" | |
"strings" | |
"github.com/aws/aws-sdk-go/aws" | |
"github.com/aws/aws-sdk-go/service/ecs" | |
"github.com/docker/libcompose/docker" | |
"github.com/docker/libcompose/project" | |
) | |
func TransformComposeFile(composeFile string, projectName string) (ecs.TaskDefinition, error) { | |
task := ecs.TaskDefinition{ | |
ContainerDefinitions: []*ecs.ContainerDefinition{}, | |
Volumes: []*ecs.Volume{}, | |
} | |
project, err := docker.NewProject(&docker.Context{ | |
Context: project.Context{ | |
ComposeFile: composeFile, | |
ProjectName: projectName, | |
}}) | |
if err != nil { | |
return task, err | |
} | |
for name, config := range project.Configs { | |
var def = ecs.ContainerDefinition{} | |
if config.Name != "" { | |
def.Name = aws.String(config.Name) | |
} | |
if config.Image != "" { | |
def.Image = aws.String(config.Image) | |
} | |
if config.Hostname != "" { | |
def.Hostname = aws.String(config.Hostname) | |
} | |
if config.WorkingDir != "" { | |
def.WorkingDirectory = aws.String(config.WorkingDir) | |
} | |
if config.CPUShares > 0 { | |
def.Cpu = aws.Int64(config.CPUShares) | |
} | |
if config.MemLimit > 0 { | |
def.Memory = aws.Int64(config.MemLimit) | |
} | |
if config.Privileged { | |
def.Privileged = aws.Bool(config.Privileged) | |
} | |
if slice := config.DNS.Slice(); len(slice) > 0 { | |
for _, dns := range slice { | |
def.DnsServers = append(def.DnsServers, aws.String(dns)) | |
} | |
} | |
if slice := config.DNSSearch.Slice(); len(slice) > 0 { | |
for _, item := range slice { | |
def.DnsSearchDomains = append(def.DnsSearchDomains, aws.String(item)) | |
} | |
} | |
if cmds := config.Command.Slice(); len(cmds) > 0 { | |
def.Command = []*string{} | |
for _, command := range cmds { | |
def.Command = append(def.Command, aws.String(command)) | |
} | |
} | |
if cmds := config.Entrypoint.Slice(); len(cmds) > 0 { | |
def.EntryPoint = []*string{} | |
for _, command := range cmds { | |
def.EntryPoint = append(def.EntryPoint, aws.String(command)) | |
} | |
} | |
if slice := config.Environment.Slice(); len(slice) > 0 { | |
def.Environment = []*ecs.KeyValuePair{} | |
for _, val := range slice { | |
parts := strings.SplitN(val, "=", 2) | |
def.Environment = append(def.Environment, &ecs.KeyValuePair{ | |
Name: aws.String(parts[0]), | |
Value: aws.String(parts[1]), | |
}) | |
} | |
} | |
if ports := config.Ports; len(ports) > 0 { | |
def.PortMappings = []*ecs.PortMapping{} | |
for _, val := range ports { | |
parts := strings.Split(val, ":") | |
mapping := &ecs.PortMapping{} | |
// TODO: support host to map to | |
if len(parts) > 0 { | |
portInt, err := strconv.ParseInt(parts[0], 10, 64) | |
if err != nil { | |
return task, err | |
} | |
mapping.ContainerPort = aws.Int64(portInt) | |
} | |
if len(parts) > 1 { | |
hostParts := strings.Split(parts[1], "/") | |
portInt, err := strconv.ParseInt(hostParts[0], 10, 64) | |
if err != nil { | |
return task, err | |
} | |
mapping.HostPort = aws.Int64(portInt) | |
// handle the protocol at the end of the mapping | |
if len(hostParts) > 1 { | |
mapping.Protocol = aws.String(hostParts[1]) | |
} | |
} | |
if len(parts) == 0 || len(parts) > 2 { | |
return task, errors.New("Unsupported port mapping " + val) | |
} | |
def.PortMappings = append(def.PortMappings, mapping) | |
} | |
} | |
if links := config.Links.Slice(); len(links) > 0 { | |
def.Links = []*string{} | |
for _, link := range links { | |
def.Links = append(def.Links, aws.String(link)) | |
} | |
} | |
if vols := config.Volumes; len(vols) > 0 { | |
def.MountPoints = []*ecs.MountPoint{} | |
for idx, vol := range vols { | |
parts := strings.Split(vol, ":") | |
volumeName := fmt.Sprintf("%s-vol%d", name, idx) | |
volume := ecs.Volume{ | |
Host: &ecs.HostVolumeProperties{ | |
SourcePath: aws.String(parts[0]), | |
}, | |
Name: aws.String(volumeName), | |
} | |
mount := ecs.MountPoint{ | |
SourceVolume: aws.String(volumeName), | |
ContainerPath: aws.String(parts[1]), | |
} | |
if len(parts) == 3 && parts[2] == "ro" { | |
mount.ReadOnly = aws.Bool(true) | |
} | |
task.Volumes = append(task.Volumes, &volume) | |
def.MountPoints = append(def.MountPoints, &mount) | |
} | |
} | |
if volsFrom := config.VolumesFrom; len(volsFrom) > 0 { | |
def.VolumesFrom = []*ecs.VolumeFrom{} | |
for _, container := range volsFrom { | |
def.VolumesFrom = append(def.VolumesFrom, &ecs.VolumeFrom{ | |
SourceContainer: aws.String(container), | |
}) | |
} | |
} | |
if config.Build != "" { | |
return task, errors.New("Build directive not supported") | |
} | |
if config.Dockerfile != "" { | |
return task, errors.New("Dockerfile directive not supported") | |
} | |
if config.DomainName != "" { | |
return task, errors.New("DomainName directive not supported") | |
} | |
if config.VolumeDriver != "" { | |
return task, errors.New("VolumeDriver directive not supported") | |
} | |
task.ContainerDefinitions = append(task.ContainerDefinitions, &def) | |
// Not Implemented | |
// CapAdd:[]string(nil), | |
// CapDrop:[]string(nil), | |
// CPUSet:"", | |
// ContainerName:"", | |
// Devices:[]string(nil), | |
// EnvFile:project.Stringorslice{parts:[]string(nil)}, | |
// Labels:project.SliceorMap{parts:map[string]string(nil)}, | |
// LogDriver:"", | |
// MemSwapLimit:0, | |
// Net:"", | |
// Pid:"", | |
// Uts:"", | |
// Ipc:"", | |
// Restart:"", | |
// ReadOnly:false, | |
// StdinOpen:false, | |
// SecurityOpt:[]string(nil), | |
// Tty:false, | |
// User:"", | |
// Expose:[]string(nil), | |
// ExternalLinks:[]string(nil), | |
// LogOpt:map[string]string(nil), | |
// ExtraHosts:[]string(nil)} | |
} | |
return task, nil | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
That moment when you realize you are shooting to the wrong duck.