commit f06a041ee09c213930950ecc1b2ea77d3a1bb292 Author: Nathan LaFreniere Date: Sat Dec 12 16:06:57 2015 -0800 initial commit diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..f581574 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +drone-rancher diff --git a/DOCS.md b/DOCS.md new file mode 100644 index 0000000..4022347 --- /dev/null +++ b/DOCS.md @@ -0,0 +1,24 @@ +Use the rancher plugin to upgrade a service in [rancher](http://rancher.com). + +The following parameters are used to configure this plugin: + +- `url` - url to your rancher server, including protocol and port +- `access_key` - rancher api access key +- `secret_key` - rancher api secret key +- `service` - name of rancher service to act on +- `docker_image` - new image to assign to service, including tag (`drone/drone:latest`) +- `start_first` - start the new container before stopping the old one, defaults to `true` + +The following is a sample Rancher configuration in your `.drone.yml` file: + +```yaml +deploy: + rancher: + url: https://example.rancher.com + access_key: 1234567abcdefg + secret_key: abcdefg1234567 + service: drone/drone + docker_image: drone/drone:latest +``` + +Note that if your `service` is part of a stack, you should use the notation `stackname/servicename` as this will make sure that the found service is part of the correct stack. If no stack is specified, this plugin will update the first service with a matching name which may not be what you want. diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..7c22f64 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,11 @@ +# Docker image for the Drone build runner +# +# CGO_ENABLED=0 go build -a -tags netgo +# docker build --rm=true -t plugins/drone-rancher . + +FROM gliderlabs/alpine:3.1 +RUN apk add --update \ + ca-certificates +ADD drone-rancher /bin/ +ENTRYPOINT ["/bin/drone-rancher"] + diff --git a/logo.svg b/logo.svg new file mode 100644 index 0000000..92ca024 --- /dev/null +++ b/logo.svg @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/main.go b/main.go new file mode 100644 index 0000000..2a002c8 --- /dev/null +++ b/main.go @@ -0,0 +1,115 @@ +package main + +import ( + "fmt" + "os" + "strings" + + "github.com/drone/drone-go/plugin" + "github.com/rancher/go-rancher/client" +) + +type Rancher struct { + Url string `json:"url"` + AccessKey string `json:"access_key"` + SecretKey string `json:"secret_key"` + Service string `json:"service"` + Image string `json:"docker_image"` + StartFirst bool `json:"start_first"` +} + +func main() { + vargs := Rancher{StartFirst: true} + + plugin.Param("vargs", &vargs) + err := plugin.Parse() + if err != nil { + fmt.Println(err) + os.Exit(1) + } + + if len(vargs.Url) == 0 || len(vargs.AccessKey) == 0 || len(vargs.SecretKey) == 0 || len(vargs.Service) == 0 { + return + } + + if !strings.HasPrefix(vargs.Image, "docker:") { + vargs.Image = fmt.Sprintf("docker:%s", vargs.Image) + } + + var wantedService, wantedStack string + if strings.Contains(vargs.Service, "/") { + parts := strings.SplitN(vargs.Service, "/", 2) + wantedStack = parts[0] + wantedService = parts[1] + } else { + wantedService = vargs.Service + } + + rancher, err := client.NewRancherClient(&client.ClientOpts{ + Url: vargs.Url, + AccessKey: vargs.AccessKey, + SecretKey: vargs.SecretKey, + }) + + if err != nil { + fmt.Printf("Failed to create rancher client: %s\n", err) + os.Exit(1) + } + + var stackId string + if wantedStack != "" { + environments, err := rancher.Environment.List(&client.ListOpts{}) + if err != nil { + fmt.Printf("Failed to list rancher environments: %s\n", err) + os.Exit(1) + } + + for _, env := range environments.Data { + if env.Name == wantedStack { + stackId = env.Id + } + } + + if stackId == "" { + fmt.Printf("Unable to find stack %s\n", wantedStack) + os.Exit(1) + } + } + + services, err := rancher.Service.List(&client.ListOpts{}) + if err != nil { + fmt.Printf("Failed to list rancher services: %s\n", err) + os.Exit(1) + } + + found := false + var service client.Service + for _, svc := range services.Data { + if svc.Name == wantedService && ((wantedStack != "" && svc.EnvironmentId == stackId) || wantedStack == "") { + service = svc + found = true + } + } + + if !found { + fmt.Printf("Unable to find service %s\n", vargs.Service) + os.Exit(1) + } + + service.LaunchConfig.ImageUuid = vargs.Image + upgrade := &client.ServiceUpgrade{} + upgrade.InServiceStrategy = &client.InServiceUpgradeStrategy{ + LaunchConfig: service.LaunchConfig, + SecondaryLaunchConfigs: service.SecondaryLaunchConfigs, + StartFirst: vargs.StartFirst, + } + upgrade.ToServiceStrategy = &client.ToServiceUpgradeStrategy{} + + _, err = rancher.Service.ActionUpgrade(&service, upgrade) + if err != nil { + fmt.Printf("Unable to upgrade service %s\n", vargs.Service) + os.Exit(1) + } + + fmt.Printf("Upgraded %s to %s\n", vargs.Service, vargs.Image) +}