Docker template generator
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

docker.go 2.2KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586
  1. package main
  2. import (
  3. "fmt"
  4. "github.com/docker/docker/api/types"
  5. "github.com/docker/docker/api/types/events"
  6. "github.com/docker/docker/api/types/filters"
  7. "golang.org/x/net/context"
  8. )
  9. type DockerClient interface {
  10. Events(ctx context.Context, options types.EventsOptions) (<-chan events.Message, <-chan error)
  11. ContainerList(ctx context.Context, options types.ContainerListOptions) ([]types.Container, error)
  12. ContainerInspect(ctx context.Context, containerID string) (types.ContainerJSON, error)
  13. }
  14. func monitorContainers(client DockerClient, stop <-chan struct{}, addedFn func(*Container), removedFn func(string)) error {
  15. ctx, cancel := context.WithCancel(context.Background())
  16. stream, errors := startEventStream(client, ctx)
  17. if err := publishExistingContainers(client, ctx, addedFn); err != nil {
  18. cancel()
  19. return err
  20. }
  21. for {
  22. select {
  23. case event := <-stream:
  24. if event.Action == "create" {
  25. err, container := inspectContainer(client, ctx, event.Actor.ID)
  26. if err != nil {
  27. cancel()
  28. return err
  29. }
  30. addedFn(&container)
  31. } else {
  32. removedFn(event.Actor.Attributes["name"])
  33. }
  34. case err := <-errors:
  35. cancel()
  36. return err
  37. case <-stop:
  38. cancel()
  39. return nil
  40. }
  41. }
  42. }
  43. func startEventStream(client DockerClient, ctx context.Context) (<-chan events.Message, <-chan error) {
  44. args := filters.NewArgs()
  45. args.Add("type", "container")
  46. args.Add("event", "create")
  47. args.Add("event", "destroy")
  48. return client.Events(ctx, types.EventsOptions{Filters: args})
  49. }
  50. func publishExistingContainers(client DockerClient, ctx context.Context, addedFn func(*Container)) error {
  51. containers, err := client.ContainerList(ctx, types.ContainerListOptions{})
  52. if err != nil {
  53. return fmt.Errorf("unable to list containers: %s", err.Error())
  54. }
  55. for _, container := range containers {
  56. addedFn(&Container{
  57. Id: container.ID,
  58. Name: container.Names[0][1:],
  59. Labels: container.Labels,
  60. })
  61. }
  62. return nil
  63. }
  64. func inspectContainer(client DockerClient, ctx context.Context, id string) (error, Container) {
  65. container, err := client.ContainerInspect(ctx, id)
  66. if err != nil {
  67. return err, Container{}
  68. }
  69. return nil, Container{
  70. Id: container.ID,
  71. Name: container.Name[1:],
  72. Labels: container.Config.Labels,
  73. }
  74. }