func (s *imageURLSuite) TestImageURL(c *gc.C) { imageURLGetter := container.NewImageURLGetter("host:port", "12345", []byte("cert")) imageURL, err := imageURLGetter.ImageURL(instance.LXC, "trusty", "amd64") c.Assert(err, gc.IsNil) c.Assert(imageURL, gc.Equals, "https://host:port/environment/12345/images/lxc/trusty/amd64/trusty-released-amd64-root.tar.gz") c.Assert(imageURLGetter.CACert(), gc.DeepEquals, []byte("cert")) }
func (s *imageURLSuite) assertImageURLForStream(c *gc.C, stream string) { imageURLGetter := container.NewImageURLGetter( container.ImageURLGetterConfig{ ServerRoot: "host:port", ModelUUID: "12345", CACert: []byte("cert"), CloudimgBaseUrl: "", Stream: stream, ImageDownloadFunc: container.ImageDownloadURL, }) imageURL, err := imageURLGetter.ImageURL(instance.LXC, "trusty", "amd64") c.Assert(err, gc.IsNil) c.Assert(imageURL, gc.Equals, fmt.Sprintf("https://host:port/model/12345/images/lxc/trusty/amd64/trusty-%s-amd64-root.tar.gz", stream)) c.Assert(imageURLGetter.CACert(), gc.DeepEquals, []byte("cert")) }
func (s *imageURLSuite) TestImageURLOtherBase(c *gc.C) { var calledBaseURL string baseURL := "other://cloud-images" mockFunc := func(kind instance.ContainerType, series, arch, cloudimgBaseUrl string) (string, error) { calledBaseURL = cloudimgBaseUrl return "omg://wat/trusty-released-amd64-root.tar.gz", nil } imageURLGetter := container.NewImageURLGetter( container.ImageURLGetterConfig{ "host:port", "12345", []byte("cert"), baseURL, mockFunc, }) imageURL, err := imageURLGetter.ImageURL(instance.LXC, "trusty", "amd64") c.Assert(err, gc.IsNil) c.Assert(imageURL, gc.Equals, "https://host:port/model/12345/images/lxc/trusty/amd64/trusty-released-amd64-root.tar.gz") c.Assert(imageURLGetter.CACert(), gc.DeepEquals, []byte("cert")) c.Assert(calledBaseURL, gc.Equals, baseURL) }
// SetConfig is specified in the Environ interface. func (env *localEnviron) SetConfig(cfg *config.Config) error { ecfg, err := providerInstance.newConfig(cfg) if err != nil { logger.Errorf("failed to create new environ config: %v", err) return errors.Trace(err) } env.localMutex.Lock() defer env.localMutex.Unlock() env.config = ecfg env.name = ecfg.Name() containerType := ecfg.container() managerConfig := container.ManagerConfig{ container.ConfigName: env.config.namespace(), container.ConfigLogDir: env.config.logDir(), } var imageURLGetter container.ImageURLGetter if containerType == instance.LXC { if useLxcClone, ok := cfg.LXCUseClone(); ok { managerConfig["use-clone"] = fmt.Sprint(useLxcClone) } if useLxcCloneAufs, ok := cfg.LXCUseCloneAUFS(); ok { managerConfig["use-aufs"] = fmt.Sprint(useLxcCloneAufs) } // For lxc containers, we cache image tarballs in the environment storage, so here // we construct a URL getter. if uuid, ok := ecfg.UUID(); ok { var caCert []byte = nil if cert, ok := cfg.CACert(); ok { caCert = []byte(cert) } baseUrl := ecfg.CloudImageBaseURL() imageURLGetter = container.NewImageURLGetter( // Explicitly call the non-named constructor so if anyone // adds additional fields, this fails. container.ImageURLGetterConfig{ ecfg.stateServerAddr(), uuid, caCert, baseUrl, container.ImageDownloadURL, }) } } env.containerManager, err = factory.NewContainerManager( containerType, managerConfig, imageURLGetter) if err != nil { return errors.Trace(err) } // When the localEnviron value is created on the client // side, the bootstrap-ip attribute will not exist, // because it is only set *within* the running // environment, not in the configuration created by // Prepare. if addr := ecfg.bootstrapIPAddress(); addr != "" { env.bridgeAddress = addr return nil } // If we get to here, it is because we haven't yet bootstrapped an // environment, and saved the config in it, or we are running a command // from the command line, so it is ok to work on the assumption that we // have direct access to the directories. if err := env.config.createDirs(); err != nil { return errors.Trace(err) } // Record the network bridge address and create a filestorage. if err := env.resolveBridgeAddress(cfg); err != nil { return errors.Trace(err) } return nil }
// updateSupportedContainers records in state that a machine can run the specified containers. // It starts a watcher and when a container of a given type is first added to the machine, // the watcher is killed, the machine is set up to be able to start containers of the given type, // and a suitable provisioner is started. func (a *MachineAgent) updateSupportedContainers( runner worker.Runner, st api.Connection, containers []instance.ContainerType, agentConfig agent.Config, ) error { pr := st.Provisioner() tag := agentConfig.Tag().(names.MachineTag) machine, err := pr.Machine(tag) if errors.IsNotFound(err) || err == nil && machine.Life() == params.Dead { return worker.ErrTerminateAgent } if err != nil { return errors.Annotatef(err, "cannot load machine %s from state", tag) } if len(containers) == 0 { if err := machine.SupportsNoContainers(); err != nil { return errors.Annotatef(err, "clearing supported containers for %s", tag) } return nil } if err := machine.SetSupportedContainers(containers...); err != nil { return errors.Annotatef(err, "setting supported containers for %s", tag) } initLock, err := cmdutil.HookExecutionLock(agentConfig.DataDir()) if err != nil { return err } // Start the watcher to fire when a container is first requested on the machine. modelUUID, err := st.ModelTag() if err != nil { return err } watcherName := fmt.Sprintf("%s-container-watcher", machine.Id()) // There may not be a CA certificate private key available, and without // it we can't ensure that other Juju nodes can connect securely, so only // use an image URL getter if there's a private key. var imageURLGetter container.ImageURLGetter if agentConfig.Value(agent.AllowsSecureConnection) == "true" { cfg, err := pr.ModelConfig() if err != nil { return errors.Annotate(err, "unable to get environ config") } imageURLGetter = container.NewImageURLGetter( // Explicitly call the non-named constructor so if anyone // adds additional fields, this fails. container.ImageURLGetterConfig{ ServerRoot: st.Addr(), ModelUUID: modelUUID.Id(), CACert: []byte(agentConfig.CACert()), CloudimgBaseUrl: cfg.CloudImageBaseURL(), Stream: cfg.ImageStream(), ImageDownloadFunc: container.ImageDownloadURL, }) } params := provisioner.ContainerSetupParams{ Runner: runner, WorkerName: watcherName, SupportedContainers: containers, ImageURLGetter: imageURLGetter, Machine: machine, Provisioner: pr, Config: agentConfig, InitLock: initLock, } handler := provisioner.NewContainerSetupHandler(params) a.startWorkerAfterUpgrade(runner, watcherName, func() (worker.Worker, error) { w, err := watcher.NewStringsWorker(watcher.StringsConfig{ Handler: handler, }) if err != nil { return nil, errors.Annotatef(err, "cannot start %s worker", watcherName) } return w, nil }) return nil }