示例#1
0
func (*NewConnSuite) TestNewConnFromName(c *C) {
	home := c.MkDir()
	defer os.Setenv("HOME", os.Getenv("HOME"))
	os.Setenv("HOME", home)
	conn, err := juju.NewConnFromName("")
	c.Assert(conn, IsNil)
	c.Assert(err, ErrorMatches, ".*: no such file or directory")

	if err := os.Mkdir(filepath.Join(home, ".juju"), 0755); err != nil {
		c.Fatal("Could not create directory structure")
	}
	envs := filepath.Join(home, ".juju", "environments.yaml")
	err = ioutil.WriteFile(envs, []byte(`
default:
    erewhemos
environments:
    erewhemos:
        type: dummy
        state-server: true
        authorized-keys: i-am-a-key
        admin-secret: conn-from-name-secret
`), 0644)

	err = ioutil.WriteFile(filepath.Join(home, ".juju", "erewhemos-cert.pem"), []byte(coretesting.CACert), 0600)
	c.Assert(err, IsNil)
	err = ioutil.WriteFile(filepath.Join(home, ".juju", "erewhemos-private-key.pem"), []byte(coretesting.CAKey), 0600)
	c.Assert(err, IsNil)

	// Just run through a few operations on the dummy provider and verify that
	// they behave as expected.
	conn, err = juju.NewConnFromName("")
	c.Assert(err, ErrorMatches, "dummy environment not bootstrapped")

	environ, err := environs.NewFromName("")
	c.Assert(err, IsNil)
	err = environs.Bootstrap(environ, false, panicWrite)
	c.Assert(err, IsNil)

	conn, err = juju.NewConnFromName("")
	c.Assert(err, IsNil)
	defer conn.Close()
	c.Assert(conn.Environ, NotNil)
	c.Assert(conn.Environ.Name(), Equals, "erewhemos")
	c.Assert(conn.State, NotNil)

	// Reset the admin password so the state db can be reused.
	err = conn.State.SetAdminMongoPassword("")
	c.Assert(err, IsNil)
	// Close the conn (thereby closing its state) a couple of times to
	// verify that multiple closes will not panic. We ignore the error,
	// as the underlying State will return an error the second
	// time.
	conn.Close()
	conn.Close()
}
示例#2
0
func (c *StatusCommand) Run(ctx *cmd.Context) error {
	conn, err := juju.NewConnFromName(c.EnvName)
	if err != nil {
		return err
	}
	defer conn.Close()

	var context statusContext
	if context.machines, err = fetchAllMachines(conn.State); err != nil {
		return err
	}
	if context.services, context.units, err = fetchAllServicesAndUnits(conn.State); err != nil {
		return err
	}
	context.instances, err = fetchAllInstances(conn.Environ)
	if err != nil {
		// We cannot see instances from the environment, but
		// there's still lots of potentially useful info to print.
		fmt.Fprintf(ctx.Stderr, "cannot retrieve instances from the environment: %v\n", err)
	}
	result := struct {
		Machines map[string]machineStatus `json:"machines"`
		Services map[string]serviceStatus `json:"services"`
	}{
		Machines: context.processMachines(),
		Services: context.processServices(),
	}
	return c.out.Write(ctx, result)
}
示例#3
0
func (c *SetEnvironmentCommand) Run(ctx *cmd.Context) error {
	conn, err := juju.NewConnFromName(c.EnvName)
	if err != nil {
		return err
	}
	defer conn.Close()

	// Here is the magic around setting the attributes:
	// TODO(thumper): get this magic under test somewhere, and update other call-sites to use it.
	// Get the existing environment config from the state.
	oldConfig, err := conn.State.EnvironConfig()
	if err != nil {
		return err
	}
	// Apply the attributes specified for the command to the state config.
	newConfig, err := oldConfig.Apply(c.values)
	if err != nil {
		return err
	}
	// Now validate this new config against the existing config via the provider.
	provider := conn.Environ.Provider()
	newProviderConfig, err := provider.Validate(newConfig, oldConfig)
	if err != nil {
		return err
	}
	// Now try to apply the new validated config.
	return conn.State.SetEnvironConfig(newProviderConfig)
}
示例#4
0
// Run fetches the configuration of the service and formats
// the result as a YAML string.
func (c *GetCommand) Run(ctx *cmd.Context) error {
	conn, err := juju.NewConnFromName(c.EnvName)
	if err != nil {
		return err
	}
	defer conn.Close()
	svc, err := conn.State.Service(c.ServiceName)
	if err != nil {
		return err
	}
	svcfg, err := svc.Config()
	if err != nil {
		return err
	}
	charm, _, err := svc.Charm()
	if err != nil {
		return err
	}
	chcfg := charm.Config().Options

	config := merge(svcfg.Map(), chcfg)

	result := map[string]interface{}{
		"service":  svc.Name(),
		"charm":    charm.Meta().Name,
		"settings": config,
	}
	return c.out.Write(ctx, result)
}
示例#5
0
func (c *GetEnvironmentCommand) Run(ctx *cmd.Context) error {
	conn, err := juju.NewConnFromName(c.EnvName)
	if err != nil {
		return err
	}
	defer conn.Close()

	// Get the existing environment config from the state.
	config, err := conn.State.EnvironConfig()
	if err != nil {
		return err
	}
	attrs := config.AllAttrs()

	// If no key specified, write out the whole lot.
	if c.key == "" {
		return c.out.Write(ctx, attrs)
	}

	value, found := attrs[c.key]
	if found {
		return c.out.Write(ctx, value)
	}

	return fmt.Errorf("Key %q not found in %q environment.", c.key, config.Name())
}
示例#6
0
// Run updates the configuration of a service.
func (c *SetCommand) Run(ctx *cmd.Context) error {
	conn, err := juju.NewConnFromName(c.EnvName)
	if err != nil {
		return err
	}
	defer conn.Close()
	service, err := conn.State.Service(c.ServiceName)
	if err != nil {
		return err
	}
	ch, _, err := service.Charm()
	if err != nil {
		return err
	}
	var settings charm.Settings
	if c.SettingsYAML.Path != "" {
		settingsYAML, err := c.SettingsYAML.Read(ctx)
		if err != nil {
			return err
		}
		settings, err = ch.Config().ParseSettingsYAML(settingsYAML, c.ServiceName)
		if err != nil {
			return err
		}
	} else if len(c.SettingsStrings) > 0 {
		settings, err = ch.Config().ParseSettingsStrings(c.SettingsStrings)
		if err != nil {
			return err
		}
	} else {
		return nil
	}
	return service.UpdateConfigSettings(settings)
}
示例#7
0
// Run resolves c.Target to a machine, or host of a unit and
// forks ssh with c.Args, if provided.
func (c *SCPCommand) Run(ctx *cmd.Context) error {
	var err error
	c.Conn, err = juju.NewConnFromName(c.EnvName)
	if err != nil {
		return err
	}
	defer c.Close()

	// translate arguments in the form 0:/somepath or service/0:/somepath into
	// ubuntu@machine:/somepath so they can be presented to scp.
	for i := range c.Args {
		// BUG(dfc) This will not work for IPv6 addresses like 2001:db8::1:2:/somepath.
		if v := strings.SplitN(c.Args[i], ":", 2); len(v) > 1 {
			host, err := c.hostFromTarget(v[0])
			if err != nil {
				return err
			}
			c.Args[i] = "ubuntu@" + host + ":" + v[1]
		}
	}

	args := []string{"-o", "StrictHostKeyChecking no", "-o", "PasswordAuthentication no"}
	args = append(args, c.Args...)
	cmd := exec.Command("scp", args...)
	cmd.Stdin = ctx.Stdin
	cmd.Stdout = ctx.Stdout
	cmd.Stderr = ctx.Stderr
	c.Close()
	return cmd.Run()
}
示例#8
0
func (c *AddMachineCommand) Run(_ *cmd.Context) error {
	conn, err := juju.NewConnFromName(c.EnvName)
	if err != nil {
		return err
	}
	defer conn.Close()

	series := c.Series
	if series == "" {
		conf, err := conn.State.EnvironConfig()
		if err != nil {
			return err
		}
		series = conf.DefaultSeries()
	}
	params := state.AddMachineParams{
		ParentId:      c.MachineId,
		ContainerType: c.ContainerType,
		Series:        series,
		Constraints:   c.Constraints,
		Jobs:          []state.MachineJob{state.JobHostUnits},
	}
	m, err := conn.State.AddMachineWithConstraints(&params)
	if err == nil {
		if c.ContainerType == "" {
			log.Infof("created machine %v", m)
		} else {
			log.Infof("created %q container on machine %v", c.ContainerType, m)
		}
	}
	return err
}
示例#9
0
func (*NewConnSuite) TestNewConnFromNameNotSetGetsDefault(c *C) {
	defer coretesting.MakeSampleHome(c).Restore()
	bootstrapEnv(c, "")
	conn, err := juju.NewConnFromName("")
	c.Assert(err, IsNil)
	defer conn.Close()
	c.Assert(conn.Environ.Name(), Equals, coretesting.SampleEnvName)
}
示例#10
0
func (c *DestroyMachineCommand) Run(_ *cmd.Context) error {
	conn, err := juju.NewConnFromName(c.EnvName)
	if err != nil {
		return err
	}
	defer conn.Close()
	return conn.State.DestroyMachines(c.MachineIds...)
}
示例#11
0
// Run connects to the environment specified on the command line
// and calls conn.DestroyUnits.
func (c *DestroyUnitCommand) Run(_ *cmd.Context) (err error) {
	conn, err := juju.NewConnFromName(c.EnvName)
	if err != nil {
		return err
	}
	defer conn.Close()
	return conn.DestroyUnits(c.UnitNames...)
}
示例#12
0
// Run updates the configuration of a service
func (c *SetCommand) Run(ctx *cmd.Context) error {
	var unvalidated = make(map[string]string)
	var remove []string
	contents, err := c.Config.Read(ctx)
	if err != nil && err != cmd.ErrNoPath {
		return err
	}
	if len(contents) > 0 {
		if err := goyaml.Unmarshal(contents, &unvalidated); err != nil {
			return err
		}
	} else {
		unvalidated, remove, err = parse(c.Options)
		if err != nil {
			return err
		}
	}
	conn, err := juju.NewConnFromName(c.EnvName)
	if err != nil {
		return err
	}
	defer conn.Close()
	srv, err := conn.State.Service(c.ServiceName)
	if err != nil {
		return err
	}
	charm, _, err := srv.Charm()
	if err != nil {
		return err
	}
	// 1. Validate will convert this partial configuration
	// into a full configuration by inserting charm defaults
	// for missing values.
	validated, err := charm.Config().Validate(unvalidated)
	if err != nil {
		return err
	}
	// 2. strip out the additional default keys added in the previous step.
	validated = strip(validated, unvalidated)
	cfg, err := srv.Config()
	if err != nil {
		return err
	}
	// 3. Update any keys that remain after validation and filtering.
	if len(validated) > 0 {
		log.Debugf("cmd/juju: updating configuration items: %v", validated)
		cfg.Update(validated)
	}
	// 4. Delete any removed keys.
	if len(remove) > 0 {
		log.Debugf("cmd/juju: removing configuration items: %v", remove)
		for _, k := range remove {
			cfg.Delete(k)
		}
	}
	_, err = cfg.Write()
	return err
}
示例#13
0
// Run changes the juju-managed firewall to hide any
// ports that were also explicitly marked by units as closed.
func (c *UnexposeCommand) Run(_ *cmd.Context) error {
	conn, err := juju.NewConnFromName(c.EnvName)
	if err != nil {
		return err
	}
	defer conn.Close()
	params := params.ServiceUnexpose{ServiceName: c.ServiceName}
	return statecmd.ServiceUnexpose(conn.State, params)
}
示例#14
0
func (*NewConnSuite) TestConnMultipleCloseOk(c *C) {
	defer coretesting.MakeSampleHome(c).Restore()
	bootstrapEnv(c, "")
	// Error return from here is tested in TestNewConnFromNameNotSetGetsDefault.
	conn, _ := juju.NewConnFromName("")
	conn.Close()
	conn.Close()
	conn.Close()
}
示例#15
0
func (*NewConnSuite) TestNewConnFromNameNotDefault(c *C) {
	defer coretesting.MakeMultipleEnvHome(c).Restore()
	// The default environment is "erewhemos", so make sure we get what we ask for.
	const envName = "erewhemos-2"
	bootstrapEnv(c, envName)
	conn, err := juju.NewConnFromName(envName)
	c.Assert(err, IsNil)
	defer conn.Close()
	c.Assert(conn.Environ.Name(), Equals, envName)
}
示例#16
0
// Run connects to the environment specified on the command line and destroys
// units therein.
func (c *DestroyUnitCommand) Run(_ *cmd.Context) (err error) {
	conn, err := juju.NewConnFromName(c.EnvName)
	if err != nil {
		return err
	}
	defer conn.Close()
	params := params.DestroyServiceUnits{
		UnitNames: c.UnitNames,
	}
	return statecmd.DestroyServiceUnits(conn.State, params)
}
示例#17
0
// Run changes the version proposed for the juju tools.
func (c *UpgradeJujuCommand) Run(_ *cmd.Context) (err error) {
	conn, err := juju.NewConnFromName(c.EnvName)
	if err != nil {
		return err
	}
	defer conn.Close()
	defer func() {
		if err == errUpToDate {
			log.Noticef(err.Error())
			err = nil
		}
	}()

	// Determine the version to upgrade to, uploading tools if necessary.
	env := conn.Environ
	cfg, err := conn.State.EnvironConfig()
	if err != nil {
		return err
	}
	v, err := c.initVersions(cfg, env)
	if err != nil {
		return err
	}
	if c.UploadTools {
		series := getUploadSeries(cfg, c.Series)
		if err := v.uploadTools(env.Storage(), series); err != nil {
			return err
		}
	}
	if err := v.validate(); err != nil {
		return err
	}
	log.Infof("upgrade version chosen: %s", v.chosen)
	// TODO(fwereade): this list may be incomplete, pending tools.Upload change.
	log.Infof("available tools: %s", v.tools)

	// Write updated config back to state if necessary. Note that this is
	// crackful and racy, because we have no idea what incompatible agent-
	// version might be set by another administrator in the meantime. If
	// this happens, tough: I'm not going to pretend to do it right when
	// I'm not.
	// TODO(fwereade): Do this right. Warning: scope unclear.
	cfg, err = cfg.Apply(map[string]interface{}{
		"agent-version": v.chosen.String(),
	})
	if err != nil {
		return err
	}
	if err := conn.State.SetEnvironConfig(cfg); err != nil {
		return err
	}
	log.Noticef("started upgrade to %s", v.chosen)
	return nil
}
示例#18
0
// Run changes the juju-managed firewall to hide any
// ports that were also explicitly marked by units as closed.
func (c *UnexposeCommand) Run(_ *cmd.Context) error {
	conn, err := juju.NewConnFromName(c.EnvName)
	if err != nil {
		return err
	}
	defer conn.Close()
	svc, err := conn.State.Service(c.ServiceName)
	if err != nil {
		return err
	}
	return svc.ClearExposed()
}
示例#19
0
func (c *ResolvedCommand) Run(_ *cmd.Context) error {
	conn, err := juju.NewConnFromName(c.EnvName)
	if err != nil {
		return err
	}
	defer conn.Close()
	unit, err := conn.State.Unit(c.UnitName)
	if err != nil {
		return err
	}
	return unit.Resolve(c.Retry)
}
示例#20
0
func (c *AddRelationCommand) Run(_ *cmd.Context) error {
	conn, err := juju.NewConnFromName(c.EnvName)
	if err != nil {
		return err
	}
	defer conn.Close()
	params := params.AddRelation{
		Endpoints: c.Endpoints,
	}
	_, err = statecmd.AddRelation(conn.State, params)
	return err
}
示例#21
0
func (c *AddRelationCommand) Run(_ *cmd.Context) error {
	conn, err := juju.NewConnFromName(c.EnvName)
	if err != nil {
		return err
	}
	defer conn.Close()
	eps, err := conn.State.InferEndpoints(c.Endpoints)
	if err != nil {
		return err
	}
	_, err = conn.State.AddRelation(eps...)
	return err
}
示例#22
0
// Run connects to the environment specified on the command line
// and calls conn.AddUnits.
func (c *AddUnitCommand) Run(_ *cmd.Context) error {
	conn, err := juju.NewConnFromName(c.EnvName)
	if err != nil {
		return err
	}
	defer conn.Close()
	service, err := conn.State.Service(c.ServiceName)
	if err != nil {
		return err
	}
	_, err = conn.AddUnits(service, c.NumUnits)
	return err

}
示例#23
0
// Run connects to the environment specified on the command line
// and calls conn.AddUnits.
func (c *AddUnitCommand) Run(_ *cmd.Context) error {
	conn, err := juju.NewConnFromName(c.EnvName)
	if err != nil {
		return err
	}
	defer conn.Close()

	params := params.AddServiceUnits{
		ServiceName:   c.ServiceName,
		NumUnits:      c.NumUnits,
		ToMachineSpec: c.ToMachineSpec,
	}
	_, err = statecmd.AddServiceUnits(conn.State, params)
	return err
}
示例#24
0
func (c *SetConstraintsCommand) Run(_ *cmd.Context) (err error) {
	conn, err := juju.NewConnFromName(c.EnvName)
	if err != nil {
		return err
	}
	defer conn.Close()
	if c.ServiceName == "" {
		return conn.State.SetEnvironConstraints(c.Constraints)
	}
	params := params.SetServiceConstraints{
		ServiceName: c.ServiceName,
		Constraints: c.Constraints,
	}
	return statecmd.SetServiceConstraints(conn.State, params)
}
示例#25
0
func (c *DestroyRelationCommand) Run(_ *cmd.Context) error {
	conn, err := juju.NewConnFromName(c.EnvName)
	if err != nil {
		return err
	}
	defer conn.Close()
	eps, err := conn.State.InferEndpoints(c.Endpoints)
	if err != nil {
		return err
	}
	rel, err := conn.State.EndpointsRelation(eps...)
	if err != nil {
		return err
	}
	return rel.Destroy()
}
示例#26
0
func (c *StatusCommand) Run(ctx *cmd.Context) error {
	conn, err := juju.NewConnFromName(c.EnvName)
	if err != nil {
		return fmt.Errorf(connectionError, c.EnvName, err)
	}
	defer conn.Close()

	var context statusContext
	unitMatcher, err := newUnitMatcher(c.patterns)
	if err != nil {
		return err
	}
	if context.services, context.units, err = fetchAllServicesAndUnits(conn.State, unitMatcher); err != nil {
		return err
	}

	// Filter machines by units in scope.
	var machineIds *set.Strings
	if !unitMatcher.matchesAny() {
		machineIds, err = fetchUnitMachineIds(context.units)
		if err != nil {
			return err
		}
	}
	if context.machines, err = fetchMachines(conn.State, machineIds); err != nil {
		return err
	}

	context.instances, err = fetchAllInstances(conn.Environ)
	if err != nil {
		// We cannot see instances from the environment, but
		// there's still lots of potentially useful info to print.
		fmt.Fprintf(ctx.Stderr, "cannot retrieve instances from the environment: %v\n", err)
	}
	result := struct {
		Environment string                   `json:"environment"`
		Machines    map[string]machineStatus `json:"machines"`
		Services    map[string]serviceStatus `json:"services"`
	}{
		Environment: conn.Environ.Name(),
		Machines:    context.processMachines(),
		Services:    context.processServices(),
	}
	return c.out.Write(ctx, result)
}
示例#27
0
// Run changes the version proposed for the juju tools.
func (c *UpgradeJujuCommand) Run(_ *cmd.Context) error {
	var err error
	c.conn, err = juju.NewConnFromName(c.EnvName)
	if err != nil {
		return err
	}
	defer c.conn.Close()

	cfg, err := c.conn.State.EnvironConfig()
	if err != nil {
		return err
	}
	c.agentVersion = cfg.AgentVersion()
	c.toolsList, err = environs.ListTools(c.conn.Environ, c.agentVersion.Major)
	if err != nil {
		return err
	}
	if c.UploadTools {
		var forceVersion *version.Number
		if c.BumpVersion {
			vers := c.bumpedVersion()
			forceVersion = &vers.Number
			c.Version = vers.Number
		}
		tools, err := putTools(c.conn.Environ.Storage(), forceVersion)
		if err != nil {
			return err
		}
		c.toolsList.Private = append(c.toolsList.Private, tools)
	}
	if c.Version == (version.Number{}) {
		c.Version, err = c.newestVersion()
		if err != nil {
			return fmt.Errorf("cannot find newest version: %v", err)
		}
	}
	if c.Version.Major != c.agentVersion.Major {
		return fmt.Errorf("cannot upgrade major versions yet")
	}
	if c.Version == c.agentVersion && c.Development == cfg.Development() {
		return nil
	}
	return SetAgentVersion(c.conn.State, c.Version, c.Development)
}
示例#28
0
func (c *NatCommand) Connect(target string) error {
	var err error
	c.Conn, err = juju.NewConnFromName(c.EnvName)
	if err != nil {
		return fmt.Errorf("Unable to connect to environment %q: %v", c.EnvName, err)
	}
	defer c.Conn.Close()

	if !names.IsMachine(target) && !names.IsUnit(target) {
		return fmt.Errorf("invalid target: %q", target)
	}

	c.MachineMap = make(map[string]*state.Machine)
	st := c.Conn.State

	machines, err := st.AllMachines()
	for _, m := range machines {
		c.MachineMap[m.Id()] = m
	}

	services, err := st.AllServices()
	if err != nil {
		return err
	}
	for _, s := range services {
		units, err := s.AllUnits()
		if err != nil {
			return err
		}
		for _, u := range units {
			uc, err := c.UnitContainment(u)
			if err == ErrNoContainer {
				continue
			} else if err != nil {
				log.Println(err)
				continue
			}
			c.ContainedUnits = append(c.ContainedUnits, *uc)
		}
	}
	return nil
}
示例#29
0
// Run resolves c.Target to a machine, to the address of a i
// machine or unit forks ssh passing any arguments provided.
func (c *SSHCommand) Run(ctx *cmd.Context) error {
	var err error
	c.Conn, err = juju.NewConnFromName(c.EnvName)
	if err != nil {
		return err
	}
	defer c.Close()
	host, err := c.hostFromTarget(c.Target)
	if err != nil {
		return err
	}
	args := []string{"-l", "ubuntu", "-t", "-o", "StrictHostKeyChecking no", "-o", "PasswordAuthentication no", host}
	args = append(args, c.Args...)
	cmd := exec.Command("ssh", args...)
	cmd.Stdin = ctx.Stdin
	cmd.Stdout = ctx.Stdout
	cmd.Stderr = ctx.Stderr
	c.Close()
	return cmd.Run()
}
示例#30
0
func (s *JujuConnSuite) setUpConn(c *C) {
	if s.RootDir != "" {
		panic("JujuConnSuite.setUpConn without teardown")
	}
	s.RootDir = c.MkDir()
	s.oldHome = os.Getenv("HOME")
	home := filepath.Join(s.RootDir, "/home/ubuntu")
	err := os.MkdirAll(home, 0777)
	c.Assert(err, IsNil)
	os.Setenv("HOME", home)

	dataDir := filepath.Join(s.RootDir, "/var/lib/juju")
	err = os.MkdirAll(dataDir, 0777)
	c.Assert(err, IsNil)

	err = os.Mkdir(filepath.Join(home, ".juju"), 0777)
	c.Assert(err, IsNil)

	err = ioutil.WriteFile(filepath.Join(home, ".juju", "environments.yaml"), config, 0600)
	c.Assert(err, IsNil)

	err = ioutil.WriteFile(filepath.Join(home, ".juju", "dummyenv-cert.pem"), []byte(testing.CACert), 0666)
	c.Assert(err, IsNil)

	err = ioutil.WriteFile(filepath.Join(home, ".juju", "dummyenv-private-key.pem"), []byte(testing.CAKey), 0600)
	c.Assert(err, IsNil)

	environ, err := environs.NewFromName("dummyenv")
	c.Assert(err, IsNil)
	// sanity check we've got the correct environment.
	c.Assert(environ.Name(), Equals, "dummyenv")
	c.Assert(environs.Bootstrap(environ, false, panicWrite), IsNil)

	conn, err := juju.NewConnFromName("dummyenv")
	c.Assert(err, IsNil)
	s.Conn = conn
	s.State = conn.State
	c.Assert(err, IsNil)
}