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.3KB

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