github.com/MOXA-ISD/edge-library-libcompose@v0.4.1-0.20200417083957-c90441e63650/docker/project.go (about) 1 package docker 2 3 import ( 4 "golang.org/x/net/context" 5 6 "github.com/docker/docker/api/types" 7 "github.com/docker/docker/api/types/filters" 8 "github.com/docker/libcompose/config" 9 "github.com/docker/libcompose/docker/auth" 10 "github.com/docker/libcompose/docker/client" 11 "github.com/docker/libcompose/docker/ctx" 12 "github.com/docker/libcompose/docker/network" 13 "github.com/docker/libcompose/docker/service" 14 "github.com/docker/libcompose/docker/volume" 15 "github.com/docker/libcompose/labels" 16 "github.com/docker/libcompose/project" 17 ) 18 19 // NewProject creates a Project with the specified context. 20 func NewProject(context *ctx.Context, parseOptions *config.ParseOptions) (project.APIProject, error) { 21 22 if err := context.LookupConfig(); err != nil { 23 logrus.Errorf("Failed to load docker config: %v", err) 24 } 25 26 if context.AuthLookup == nil { 27 context.AuthLookup = auth.NewConfigLookup(context.ConfigFile) 28 } 29 30 if context.ServiceFactory == nil { 31 context.ServiceFactory = service.NewFactory(context) 32 } 33 34 if context.ClientFactory == nil { 35 factory, err := client.NewDefaultFactory(client.Options{}) 36 if err != nil { 37 return nil, err 38 } 39 context.ClientFactory = factory 40 } 41 42 if context.NetworksFactory == nil { 43 networksFactory := &network.DockerFactory{ 44 ClientFactory: context.ClientFactory, 45 } 46 context.NetworksFactory = networksFactory 47 } 48 49 if context.VolumesFactory == nil { 50 volumesFactory := &volume.DockerFactory{ 51 ClientFactory: context.ClientFactory, 52 } 53 context.VolumesFactory = volumesFactory 54 } 55 56 // FIXME(vdemeester) Remove the context duplication ? 57 runtime := &Project{ 58 clientFactory: context.ClientFactory, 59 } 60 p := project.NewProject(&context.Context, runtime, parseOptions) 61 62 err := p.Parse() 63 if err != nil { 64 return nil, err 65 } 66 67 return p, err 68 } 69 70 // Project implements project.RuntimeProject and define docker runtime specific methods. 71 type Project struct { 72 clientFactory client.Factory 73 } 74 75 // RemoveOrphans implements project.RuntimeProject.RemoveOrphans. 76 // It will remove orphan containers that are part of the project but not to any services. 77 func (p *Project) RemoveOrphans(ctx context.Context, projectName string, serviceConfigs *config.ServiceConfigs) error { 78 client := p.clientFactory.Create(nil) 79 filter := filters.NewArgs() 80 filter.Add("label", labels.PROJECT.EqString(projectName)) 81 containers, err := client.ContainerList(ctx, types.ContainerListOptions{ 82 Filters: filter, 83 }) 84 if err != nil { 85 return err 86 } 87 currentServices := map[string]struct{}{} 88 for _, serviceName := range serviceConfigs.Keys() { 89 currentServices[serviceName] = struct{}{} 90 } 91 for _, container := range containers { 92 serviceLabel := container.Labels[labels.SERVICE.Str()] 93 if _, ok := currentServices[serviceLabel]; !ok { 94 if err := client.ContainerKill(ctx, container.ID, "SIGKILL"); err != nil { 95 return err 96 } 97 if err := client.ContainerRemove(ctx, container.ID, types.ContainerRemoveOptions{ 98 Force: true, 99 }); err != nil { 100 return err 101 } 102 } 103 } 104 return nil 105 }