Beispiel #1
0
// ServiceGet returns the configuration for the named service.
func ServiceGet(st *state.State, p params.ServiceGet) (params.ServiceGetResults, error) {
	service, err := st.Service(p.ServiceName)
	if err != nil {
		return params.ServiceGetResults{}, err
	}
	settings, err := service.ConfigSettings()
	if err != nil {
		return params.ServiceGetResults{}, err
	}
	charm, _, err := service.Charm()
	if err != nil {
		return params.ServiceGetResults{}, err
	}
	configInfo := describe(settings, charm.Config())
	var constraints constraints.Value
	if service.IsPrincipal() {
		constraints, err = service.Constraints()
		if err != nil {
			return params.ServiceGetResults{}, err
		}
	}
	return params.ServiceGetResults{
		Service:     p.ServiceName,
		Charm:       charm.Meta().Name,
		Config:      configInfo,
		Constraints: constraints,
	}, nil
}
Beispiel #2
0
// UpdateConfigSettings changes a service's charm config settings. Values set
// to nil will be deleted; unknown and invalid values will return an error.
func (s *Service) UpdateConfigSettings(changes charm.Settings) error {
	charm, _, err := s.Charm()
	if err != nil {
		return err
	}
	changes, err = charm.Config().ValidateSettings(changes)
	if err != nil {
		return err
	}
	// TODO(fwereade) state.Settings is itself really problematic in just
	// about every use case. This needs to be resolved some time; but at
	// least the settings docs are keyed by charm url as well as service
	// name, so the actual impact of a race is non-threatening.
	node, err := readSettings(s.st, s.settingsKey())
	if err != nil {
		return err
	}
	for name, value := range changes {
		if value == nil {
			node.Delete(name)
		} else {
			node.Set(name, value)
		}
	}
	_, err = node.Write()
	return err
}
Beispiel #3
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)
}
Beispiel #4
0
func (s *clientSuite) TestClientServiceDeployPrincipal(c *C) {
	// TODO(fwereade): test ToMachineSpec directly on srvClient, when we
	// manage to extract it as a package and can thus do it conveniently.
	store, restore := makeMockCharmStore()
	defer restore()
	curl, bundle := addCharm(c, store, "dummy")
	mem4g := constraints.MustParse("mem=4G")
	err := s.APIState.Client().ServiceDeploy(
		curl.String(), "service", 3, "", mem4g,
	)
	c.Assert(err, IsNil)
	service, err := s.State.Service("service")
	c.Assert(err, IsNil)
	charm, force, err := service.Charm()
	c.Assert(err, IsNil)
	c.Assert(force, Equals, false)
	c.Assert(charm.URL(), DeepEquals, curl)
	c.Assert(charm.Meta(), DeepEquals, bundle.Meta())
	c.Assert(charm.Config(), DeepEquals, bundle.Config())

	cons, err := service.Constraints()
	c.Assert(err, IsNil)
	c.Assert(cons, DeepEquals, mem4g)
	units, err := service.AllUnits()
	c.Assert(err, IsNil)
	for _, unit := range units {
		mid, err := unit.AssignedMachineId()
		c.Assert(err, IsNil)
		machine, err := s.State.Machine(mid)
		c.Assert(err, IsNil)
		cons, err := machine.Constraints()
		c.Assert(err, IsNil)
		c.Assert(cons, DeepEquals, mem4g)
	}
}
Beispiel #5
0
// CharmInfo returns information about the requested charm.
func (c *Client) CharmInfo(args params.CharmInfo) (api.CharmInfo, error) {
	curl, err := charm.ParseURL(args.CharmURL)
	if err != nil {
		return api.CharmInfo{}, err
	}
	charm, err := c.api.state.Charm(curl)
	if err != nil {
		return api.CharmInfo{}, err
	}
	info := api.CharmInfo{
		Revision: charm.Revision(),
		URL:      curl.String(),
		Config:   charm.Config(),
		Meta:     charm.Meta(),
	}
	return info, nil
}
Beispiel #6
0
// ConfigSettings returns the complete set of service charm config settings
// available to the unit. Unset values will be replaced with the default
// value for the associated option, and may thus be nil when no default is
// specified.
func (u *Unit) ConfigSettings() (charm.Settings, error) {
	if u.doc.CharmURL == nil {
		return nil, fmt.Errorf("unit charm not set")
	}
	settings, err := readSettings(u.st, serviceSettingsKey(u.doc.Service, u.doc.CharmURL))
	if err != nil {
		return nil, err
	}
	charm, err := u.st.Charm(u.doc.CharmURL)
	if err != nil {
		return nil, err
	}
	result := charm.Config().DefaultSettings()
	for name, value := range settings.Map() {
		result[name] = value
	}
	return result, nil
}
Beispiel #7
0
func (s *clientSuite) TestClientServiceDeploySubordinate(c *C) {
	store, restore := makeMockCharmStore()
	defer restore()
	curl, bundle := addCharm(c, store, "logging")
	err := s.APIState.Client().ServiceDeploy(
		curl.String(), "service-name", 0, "", constraints.Value{},
	)
	service, err := s.State.Service("service-name")
	c.Assert(err, IsNil)
	charm, force, err := service.Charm()
	c.Assert(err, IsNil)
	c.Assert(force, Equals, false)
	c.Assert(charm.URL(), DeepEquals, curl)
	c.Assert(charm.Meta(), DeepEquals, bundle.Meta())
	c.Assert(charm.Config(), DeepEquals, bundle.Config())

	units, err := service.AllUnits()
	c.Assert(err, IsNil)
	c.Assert(units, HasLen, 0)
}
Beispiel #8
0
func (s *clientSuite) TestClientCharmInfo(c *C) {
	// Use wordpress for tests so that we can compare Provides and Requires.
	charm := s.AddTestingCharm(c, "wordpress")
	for i, t := range clientCharmInfoTests {
		c.Logf("test %d. %s", i, t.about)
		info, err := s.APIState.Client().CharmInfo(t.url)
		if t.err != "" {
			c.Assert(err, ErrorMatches, t.err)
			continue
		}
		c.Assert(err, IsNil)
		expected := &api.CharmInfo{
			Revision: charm.Revision(),
			URL:      charm.URL().String(),
			Config:   charm.Config(),
			Meta:     charm.Meta(),
		}
		c.Assert(info, DeepEquals, expected)
	}
}