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) }
fakeCake = new(fake_cake.FakeCake) fakeCake.GetStub = func(id layercake.ID) (*image.Image, error) { if _, ok := existingLayers[id.GraphID()]; ok { return &image.Image{Size: 33}, nil } return nil, errors.New("doesnt exist") } fakeVerifier = new(fakes.FakeVerifier) fakeVerifier.VerifyStub = func(r io.Reader, d digest.Digest) (io.ReadCloser, error) { return &verified{Reader: r}, nil } remote = repository_fetcher.NewRemote(lagertest.NewTestLogger("test"), defaultDockerRegistryHost, fakeCake, fakeDialer, fakeVerifier) }) Context("when the URL has a host", func() { It("dials that host", func() { _, err := remote.Fetch(parseURL("docker://some-host/some/repo#some-tag"), 1234) Expect(err).NotTo(HaveOccurred()) _, host, _ := fakeDialer.DialArgsForCall(0) Expect(host).To(Equal("some-host")) }) }) Context("when the host is empty", func() { It("uses the default host", func() { _, err := remote.Fetch(parseURL("docker:///some/repo#some-tag"), 1234)