func (cmd *GuardianCommand) wireVolumeCreator(logger lager.Logger, graphRoot string, insecureRegistries, persistentImages []string) gardener.VolumeCreator { if graphRoot == "" { return gardener.NoopVolumeCreator{} } if cmd.Bin.ImagePlugin.Path() != "" { defaultRootFS, err := url.Parse(cmd.Containers.DefaultRootFSDir.Path()) if err != nil { logger.Fatal("failed-to-parse-default-rootfs", err) } return imageplugin.New(cmd.Bin.ImagePlugin.Path(), linux_command_runner.New(), defaultRootFS, idMappings) } logger = logger.Session("volume-creator", lager.Data{"graphRoot": graphRoot}) runner := &logging.Runner{CommandRunner: linux_command_runner.New(), Logger: logger} if err := os.MkdirAll(graphRoot, 0755); err != nil { logger.Fatal("failed-to-create-graph-directory", err) } dockerGraphDriver, err := graphdriver.New(graphRoot, nil) if err != nil { logger.Fatal("failed-to-construct-graph-driver", err) } backingStoresPath := filepath.Join(graphRoot, "backing_stores") if err := os.MkdirAll(backingStoresPath, 0660); err != nil { logger.Fatal("failed-to-mkdir-backing-stores", err) } quotaedGraphDriver := "aed_aufs.QuotaedDriver{ GraphDriver: dockerGraphDriver, Unmount: quotaed_aufs.Unmount, BackingStoreMgr: "aed_aufs.BackingStore{ RootPath: backingStoresPath, Logger: logger.Session("backing-store-mgr"), }, LoopMounter: "aed_aufs.Loop{ Retrier: retrier.New(retrier.ConstantBackoff(200, 500*time.Millisecond), nil), Logger: logger.Session("loop-mounter"), }, Retrier: retrier.New(retrier.ConstantBackoff(200, 500*time.Millisecond), nil), RootPath: graphRoot, Logger: logger.Session("quotaed-driver"), } dockerGraph, err := graph.NewGraph(graphRoot, quotaedGraphDriver) if err != nil { logger.Fatal("failed-to-construct-graph", err) } var cake layercake.Cake = &layercake.Docker{ Graph: dockerGraph, Driver: quotaedGraphDriver, } if cake.DriverName() == "aufs" { cake = &layercake.AufsCake{ Cake: cake, Runner: runner, GraphRoot: graphRoot, } } repoFetcher := repository_fetcher.Retryable{ RepositoryFetcher: &repository_fetcher.CompositeFetcher{ LocalFetcher: &repository_fetcher.Local{ Cake: cake, DefaultRootFSPath: cmd.Containers.DefaultRootFSDir.Path(), IDProvider: repository_fetcher.LayerIDProvider{}, }, RemoteFetcher: repository_fetcher.NewRemote( logger, cmd.Docker.Registry, cake, distclient.NewDialer(insecureRegistries), repository_fetcher.VerifyFunc(repository_fetcher.Verify), ), }, Logger: logger, } rootFSNamespacer := &rootfs_provider.UidNamespacer{ Translator: rootfs_provider.NewUidTranslator( idMappings, // uid idMappings, // gid ), } retainer := cleaner.NewRetainer() ovenCleaner := cleaner.NewOvenCleaner(retainer, cleaner.NewThreshold(int64(cmd.Graph.CleanupThresholdInMegabytes)*1024*1024), ) imageRetainer := &repository_fetcher.ImageRetainer{ GraphRetainer: retainer, DirectoryRootfsIDProvider: repository_fetcher.LayerIDProvider{}, DockerImageIDFetcher: repoFetcher, NamespaceCacheKey: rootFSNamespacer.CacheKey(), Logger: logger, } // spawn off in a go function to avoid blocking startup // worst case is if an image is immediately created and deleted faster than // we can retain it we'll garbage collect it when we shouldn't. This // is an OK trade-off for not having garden startup block on dockerhub. go imageRetainer.Retain(persistentImages) layerCreator := rootfs_provider.NewLayerCreator(cake, rootfs_provider.SimpleVolumeCreator{}, rootFSNamespacer) quotaManager := "a_manager.AUFSQuotaManager{ BaseSizer: quota_manager.NewAUFSBaseSizer(cake), DiffSizer: "a_manager.AUFSDiffSizer{ AUFSDiffPathFinder: quotaedGraphDriver, }, } return rootfs_provider.NewCakeOrdinator(cake, repoFetcher, layerCreator, rootfs_provider.NewMetricsAdapter(quotaManager.GetUsage, quotaedGraphDriver.GetMntPath), ovenCleaner) }
fakeNamespacer *fake_namespacer.FakeNamespacer fakeVolumeCreator *FakeVolumeCreator name string provider *rootfs_provider.ContainerLayerCreator ) BeforeEach(func() { fakeCake = new(fake_cake.FakeCake) fakeVolumeCreator = &FakeVolumeCreator{} fakeNamespacer = &fake_namespacer.FakeNamespacer{} name = "some-name" provider = rootfs_provider.NewLayerCreator( fakeCake, fakeVolumeCreator, fakeNamespacer, ) }) Describe("Create", func() { Context("when the namespace parameter is false", func() { It("creates a graph entry with it as the parent", func() { fakeCake.PathReturns("/some/graph/driver/mount/point", nil) mountpoint, envvars, err := provider.Create( lagertest.NewTestLogger("test"), "some-id", &repository_fetcher.Image{ ImageID: "some-image-id", Env: []string{"env1=env1value", "env2=env2value"},