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