Skip to content

Instantly share code, notes, and snippets.

@alexellis
Last active December 5, 2022 23:46
Show Gist options
  • Save alexellis/e11321b8fbfc595c208ea3e74bf5e54b to your computer and use it in GitHub Desktop.
Save alexellis/e11321b8fbfc595c208ea3e74bf5e54b to your computer and use it in GitHub Desktop.
Run a one-shot job on Docker Swarm Mode
FROM golang:1.7.3
RUN mkdir -p /go/src/github.com/alexellis2/jaas
WORKDIR /go/src/github.com/alexellis2/jaas
COPY ./app.go ./
RUN go get -v -d
RUN go build
# Run service, block until complete. Check output of container:
alexr:jaas alex$ go build && ./jaas -image alexellis2/cows:latest
Service created: bumoso47nxfq8jr7tbqt7hi1q
ID: bumoso47nxfq8jr7tbqt7hi1q State: 2016-12-19 01:48:58.414268594 +0000 UTC
.....................
0
complete
alexr:jaas alex$ docker service ps bumoso47nxfq8jr7tbqt7hi1q
ID NAME IMAGE NODE DESIRED STATE CURRENT STATE ERROR
d8ywqcdl90pi8yr0s09opbo0e stoic_leakey.1 alexellis2/cows:latest moby Shutdown Complete 7 hours ago
alexr:jaas alex$ docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
0eb6558b8ada alexellis2/cows:latest "node show_cow.js" 7 hours ago Exited (0) 19 seconds ago stoic_leakey.1.d8ywqcdl90pi8yr0s09opbo0e
7cd7cd320e2e alexellis2/gotask:latest "./gotask" 7 hours ago Exited (0) 3 minutes ago pensive_yalow.1.d7d700430bgy3hhh1b07hhobk
25f8cf37cd90 alexellis2/gotask:latest "./gotask" 7 hours ago Exited (0) 3 minutes ago evil_volhard.1.a5q3l2pgyhykouh7zvszuvqog
alexr:jaas alex$ docker logs 0eb
__// \__
/^^^)^^/ ) ( \^^(^^^\
/( _( ^/ \^ )_ )\
/ \ // | / \ | \ / \
/ \ O/ \O // \
( )/\ //\( )
/\ // \ /\
/ / /W COW-TOW W\ \ \
* \( )/ *
\_ _//
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
alexr:jaas alex$
# With a timeout
alexr:jaas alex$ go build && ./jaas -image alexellis2/gotask:latest -timeout 4
Service created: 2t88b04zou8aawbvtu8y1m9nk
ID: 2t88b04zou8aawbvtu8y1m9nk State: 2016-12-19 01:46:17.107590238 +0000 UTC
....Timing out after 4 ticks.
alexr:jaas alex$
package main
import (
"flag"
"fmt"
"log"
"time"
"github.com/docker/docker/api/types"
"github.com/docker/docker/api/types/filters"
"github.com/docker/docker/api/types/swarm"
"github.com/docker/docker/client"
"io/ioutil"
"golang.org/x/net/context"
)
// Enable Docker's experimental mode in 1.13-rc before continuing.
func main() {
var image string
var timeout int
flag.StringVar(&image, "image", "", "Docker image name")
flag.IntVar(&timeout, "timeout", 0, "ticks until we time out the service")
flag.Parse()
if len(image) == 0 {
fmt.Println("Provide an image name")
return
}
var c *client.Client
var err error
c, err = client.NewEnvClient()
if err != nil {
log.Fatal("Error with Docker client.")
}
spec := makeSpec(image)
createOptions := types.ServiceCreateOptions{}
createResponse, _ := c.ServiceCreate(context.Background(), spec, createOptions)
fmt.Printf("Service created: %s\n", createResponse.ID)
dump(c, createResponse.ID, timeout)
}
func makeSpec(image string) swarm.ServiceSpec {
max := uint64(1)
spec := swarm.ServiceSpec{
TaskTemplate: swarm.TaskSpec{
RestartPolicy: &swarm.RestartPolicy{
MaxAttempts: &max,
Condition: swarm.RestartPolicyConditionNone,
},
ContainerSpec: swarm.ContainerSpec{
Image: image,
},
},
}
return spec
}
func dump(c *client.Client, id string, timeout int) {
filters2 := filters.NewArgs()
filters2.Add("id", id)
opts := types.ServiceListOptions{
Filters: filters2,
}
list, _ := c.ServiceList(context.Background(), opts)
for _, item := range list {
ticks := 0
fmt.Println("ID: ", item.ID, "State: ", item.UpdatedAt)
for {
time.Sleep(500 * time.Millisecond)
ticks++
if showTasks(c, item.ID) {
return
}
if timeout > 0 && ticks >= timeout {
fmt.Printf("Timing out after %d ticks.", ticks)
return
}
}
}
}
func showTasks(c *client.Client, id string) bool {
filters1 := filters.NewArgs()
filters1.Add("service", id)
// fmt.Println("Task filter: ", id)
val, _ := c.TaskList(context.Background(), types.TaskListOptions{
Filters: filters1,
})
var done bool
for _, v := range val {
if v.Status.State == swarm.TaskStateComplete {
fmt.Println("\n")
fmt.Println(v.Status.ContainerStatus.ExitCode)
fmt.Println(v.Status.State)
logRequest, _ := c.ServiceLogs(context.Background(), id, types.ContainerLogsOptions{
Follow: false,
ShowStdout: true,
ShowStderr: true,
Timestamps: true,
Details: false,
})
defer logRequest.Close()
// , ShowStderr: true, ShowStdout: true})
res, _ := ioutil.ReadAll(logRequest)
fmt.Println(string(res[:]))
done = true
} else {
fmt.Printf(".")
}
}
return done
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment