-
Notifications
You must be signed in to change notification settings - Fork 2
/
main.go
89 lines (80 loc) · 2.24 KB
/
main.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
package main
import (
"context"
"flag"
"fmt"
"os"
"time"
"github.com/docker/docker/api/types"
"github.com/docker/docker/client"
"github.com/sirupsen/logrus"
)
var (
log = logrus.NewEntry(logrus.New())
verbose = flag.Bool("v", false, "verbose")
timeout = flag.Int("t", 5, "timeout (seconds)")
)
func main() {
flag.Parse()
if len(flag.Args()) == 0 {
fmt.Println("Usage: " + os.Args[0] + " [flags] containerId1 containerName2 ... containerNameN")
flag.PrintDefaults()
os.Exit(1)
}
if *verbose {
log.Logger.SetLevel(logrus.DebugLevel)
}
include := make(map[string]struct{})
for _, incl := range os.Args[1:] {
include[incl] = struct{}{}
}
cli, err := client.NewClientWithOpts()
if err != nil {
log.WithError(err).Fatal("can't create docker client")
}
containers, err := cli.ContainerList(context.Background(), types.ContainerListOptions{
All: true,
})
if err != nil {
log.WithError(err).Fatalf("can't list containers")
}
ctx, cancel := context.WithTimeout(context.Background(), time.Second*time.Duration(*timeout))
defer cancel()
for _, container := range containers {
pullRestart := func() {
log.Debugf("inspecting container %s", container.ID)
inspected, err := cli.ContainerInspect(ctx, container.ID)
if err != nil {
log.WithError(err).Errorf("can't inspect container %s", container.ID)
return
}
log.Debugf("pulling a new image for container %s", imageString(&inspected))
if imageId, err := pull(ctx, cli, &container); err != nil {
log.WithError(err).Errorf("can't pull/restart container %s", imageString(&inspected))
} else {
log.Infof("received image id: %s", imageId)
if err := restart(ctx, cli, &inspected, imageId); err != nil {
log.WithError(err).Errorf("can't restart container %s", imageString(&inspected))
}
}
}
if _, ok := include[container.ID[:12]]; ok {
pullRestart()
} else if _, ok := include[container.ID]; ok || findByName(include, container) {
pullRestart()
} else {
continue
}
}
}
func findByName(include map[string]struct{}, c types.Container) bool {
for _, name := range c.Names {
if _, ok := include[name[1:]]; ok {
return true
}
}
return false
}
func imageString(c *types.ContainerJSON) string {
return c.ID + " : [" + c.Name + "]"
}