Beispiel #1
0
// Main runs the Command specified by req, and fills in resp. A single command
// is run at a time.
func (j *Jujuc) Main(req Request, resp *Response) error {
	if req.CommandName == "" {
		return badReqErrorf("command not specified")
	}
	if !filepath.IsAbs(req.Dir) {
		return badReqErrorf("Dir is not absolute")
	}
	c, err := j.getCmd(req.ContextId, req.CommandName)
	if err != nil {
		return badReqErrorf("%s", err)
	}
	var stdin, stdout, stderr bytes.Buffer
	ctx := &cmd.Context{
		Dir:    req.Dir,
		Stdin:  &stdin,
		Stdout: &stdout,
		Stderr: &stderr,
	}
	j.mu.Lock()
	defer j.mu.Unlock()
	log.Infof("worker/uniter/jujuc: running hook tool %q %q", req.CommandName, req.Args)
	log.Debugf("worker/uniter/jujuc: hook context id %q; dir %q", req.ContextId, req.Dir)
	resp.Code = cmd.Main(c, ctx, req.Args)
	resp.Stdout = stdout.Bytes()
	resp.Stderr = stderr.Bytes()
	return nil
}
func (s *RelationListSuite) TestRelationListHelp(c *C) {
	template := `
usage: relation-list [options] %s
purpose: list relation units

options:
--format  (= smart)
    specify output format (json|smart|yaml)
-o, --output (= "")
    specify an output file
%s`[1:]

	for relid, t := range map[int]struct {
		usage, doc string
	}{
		-1: {"<id>", ""},
		0:  {"[<id>]", "\nCurrent default relation id is \"peer0:0\".\n"},
	} {
		c.Logf("test relid %d", relid)
		hctx := s.GetHookContext(c, relid, "")
		com, err := jujuc.NewCommand(hctx, "relation-list")
		c.Assert(err, IsNil)
		ctx := dummyContext(c)
		code := cmd.Main(com, ctx, []string{"--help"})
		c.Assert(code, Equals, 0)
		c.Assert(bufferString(ctx.Stdout), Equals, "")
		expect := fmt.Sprintf(template, t.usage, t.doc)
		c.Assert(bufferString(ctx.Stderr), Equals, expect)

	}
}
Beispiel #3
0
func (s *SSHSuite) TestSSHCommand(c *C) {
	m := s.makeMachines(3, c)
	ch := coretesting.Charms.Dir("series", "dummy")
	curl := charm.MustParseURL(
		fmt.Sprintf("local:series/%s-%d", ch.Meta().Name, ch.Revision()),
	)
	bundleURL, err := url.Parse("http://bundles.example.com/dummy-1")
	c.Assert(err, IsNil)
	dummy, err := s.State.AddCharm(ch, curl, bundleURL, "dummy-1-sha256")
	c.Assert(err, IsNil)
	srv, err := s.State.AddService("mysql", dummy)
	c.Assert(err, IsNil)
	s.addUnit(srv, m[0], c)

	srv, err = s.State.AddService("mongodb", dummy)
	c.Assert(err, IsNil)
	s.addUnit(srv, m[1], c)
	s.addUnit(srv, m[2], c)

	for _, t := range sshTests {
		c.Logf("testing juju ssh %s", t.args)
		ctx := &cmd.Context{c.MkDir(), &bytes.Buffer{}, &bytes.Buffer{}, &bytes.Buffer{}}
		code := cmd.Main(&SSHCommand{}, ctx, t.args)
		c.Check(code, Equals, 0)
		c.Check(ctx.Stderr.(*bytes.Buffer).String(), Equals, "")
		c.Check(ctx.Stdout.(*bytes.Buffer).String(), Equals, t.result)
	}
}
Beispiel #4
0
func (s *BootstrapSuite) TestAutoSync(c *gc.C) {
	// Prepare a mock storage for testing and store the
	// dummy tools in there.
	restore := createToolsStore(c)
	defer restore()

	// Change the tools location to be the test location and also
	// the version and ensure their later restoring.
	origVersion := version.Current
	version.Current.Number = version.MustParse("1.2.3")
	defer func() { version.Current = origVersion }()

	// Create home with dummy provider and remove all
	// of its tools.
	env, fake := makeEmptyFakeHome(c)
	defer fake.Restore()

	// Bootstrap the environment now detects the missing
	// tools and automatically synchronizes them from the
	// storage above.
	ctx := coretesting.Context(c)
	code := cmd.Main(&BootstrapCommand{}, ctx, nil)
	c.Check(code, gc.Equals, 0)

	// Now check the available tools which are the 1.0.0 tools.
	checkTools(c, env, v100All)
}
Beispiel #5
0
func (s *RelationIdsSuite) TestHelp(c *C) {
	template := `
usage: %s
purpose: list all relation ids with the given relation name

options:
--format  (= smart)
    specify output format (json|smart|yaml)
-o, --output (= "")
    specify an output file
%s`[1:]

	for relid, t := range map[int]struct {
		usage, doc string
	}{
		-1: {"relation-ids [options] <name>", ""},
		0:  {"relation-ids [options] [<name>]", "\nCurrent default relation name is \"x\".\n"},
		3:  {"relation-ids [options] [<name>]", "\nCurrent default relation name is \"y\".\n"},
	} {
		c.Logf("relid %d", relid)
		hctx := s.GetHookContext(c, relid, "")
		com, err := jujuc.NewCommand(hctx, "relation-ids")
		c.Assert(err, IsNil)
		ctx := testing.Context(c)
		code := cmd.Main(com, ctx, []string{"--help"})
		c.Assert(code, Equals, 0)
		expect := fmt.Sprintf(template, t.usage, t.doc)
		c.Assert(bufferString(ctx.Stdout), Equals, expect)
		c.Assert(bufferString(ctx.Stderr), Equals, "")
	}
}
Beispiel #6
0
func assertLogs(c *C, ctx jujuc.Context, badge string) {
	loggo.ConfigureLoggers("juju=DEBUG")
	writer := &loggo.TestWriter{}
	old_writer, err := loggo.ReplaceDefaultWriter(writer)
	c.Assert(err, IsNil)
	defer loggo.ReplaceDefaultWriter(old_writer)
	msg1 := "the chickens"
	msg2 := "are 110% AWESOME"
	com, err := jujuc.NewCommand(ctx, "juju-log")
	c.Assert(err, IsNil)
	for _, t := range commonLogTests {
		writer.Clear()
		c.Assert(err, IsNil)

		var args []string
		if t.debugFlag {
			args = []string{"--debug", msg1, msg2}
		} else {
			args = []string{msg1, msg2}
		}
		code := cmd.Main(com, &cmd.Context{}, args)
		c.Assert(code, Equals, 0)
		c.Assert(writer.Log, HasLen, 1)
		c.Assert(writer.Log[0].Level, Equals, t.level)
		c.Assert(writer.Log[0].Message, Equals, fmt.Sprintf("%s: %s %s", badge, msg1, msg2))
	}
}
Beispiel #7
0
func (s *ConfigSuite) TestGetConfig(c *C) {
	sch := s.AddTestingCharm(c, "dummy")
	svc, err := s.State.AddService("dummy-service", sch)
	c.Assert(err, IsNil)
	err = svc.UpdateConfigSettings(charm.Settings{"title": "Nearly There"})
	c.Assert(err, IsNil)
	for _, t := range getTests {
		ctx := coretesting.Context(c)
		code := cmd.Main(&GetCommand{}, ctx, []string{t.service})
		c.Check(code, Equals, 0)
		c.Assert(ctx.Stderr.(*bytes.Buffer).String(), Equals, "")
		// round trip via goyaml to avoid being sucked into a quagmire of
		// map[interface{}]interface{} vs map[string]interface{}. This is
		// also required if we add json support to this command.
		buf, err := goyaml.Marshal(t.expected)
		c.Assert(err, IsNil)
		expected := make(map[string]interface{})
		err = goyaml.Unmarshal(buf, &expected)
		c.Assert(err, IsNil)

		actual := make(map[string]interface{})
		err = goyaml.Unmarshal(ctx.Stdout.(*bytes.Buffer).Bytes(), &actual)
		c.Assert(err, IsNil)
		c.Assert(actual, DeepEquals, expected)
	}
}
Beispiel #8
0
func assertLogs(c *C, ctx jujuc.Context, badge string) {
	msg1 := "the chickens"
	msg2 := "are 110% AWESOME"
	com, err := jujuc.NewCommand(ctx, "juju-log")
	c.Assert(err, IsNil)
	for _, t := range commonLogTests {
		buf, pop := pushLog(t.debugEnabled)
		defer pop()

		var args []string
		if t.debugFlag {
			args = []string{"--debug", msg1, msg2}
		} else {
			args = []string{msg1, msg2}
		}
		code := cmd.Main(com, &cmd.Context{}, args)
		c.Assert(code, Equals, 0)

		if t.target == "" {
			c.Assert(buf.String(), Equals, "")
		} else {
			expect := fmt.Sprintf("%s %s: %s %s\n", t.target, badge, msg1, msg2)
			c.Assert(buf.String(), Equals, expect)
		}
	}
}
Beispiel #9
0
func (s *CmdSuite) TestMainRunSilentError(c *C) {
	ctx := dummyContext(c)
	result := cmd.Main(&TestCommand{Name: "verb"}, ctx, []string{"--option", "silent-error"})
	c.Assert(result, Equals, 1)
	c.Assert(bufferString(ctx.Stdout), Equals, "")
	c.Assert(bufferString(ctx.Stderr), Equals, "")
}
Beispiel #10
0
func (s *CmdSuite) TestMainSuccess(c *C) {
	ctx := dummyContext(c)
	result := cmd.Main(&TestCommand{Name: "verb"}, ctx, []string{"--option", "success!"})
	c.Assert(result, Equals, 0)
	c.Assert(bufferString(ctx.Stdout), Equals, "success!\n")
	c.Assert(bufferString(ctx.Stderr), Equals, "")
}
Beispiel #11
0
func (s *CmdSuite) TestMainRunError(c *C) {
	ctx := testing.Context(c)
	result := cmd.Main(&TestCommand{Name: "verb"}, ctx, []string{"--option", "error"})
	c.Assert(result, Equals, 1)
	c.Assert(bufferString(ctx.Stdout), Equals, "")
	c.Assert(bufferString(ctx.Stderr), Equals, "error: BAM!\n")
}
func (s *RelationListSuite) TestRelationList(c *C) {
	for i, t := range relationListTests {
		c.Logf("test %d: %s", i, t.summary)
		hctx := s.GetHookContext(c, t.relid, "")
		setMembers(hctx.rels[0], t.members0)
		setMembers(hctx.rels[1], t.members1)
		com, err := jujuc.NewCommand(hctx, "relation-list")
		c.Assert(err, IsNil)
		ctx := dummyContext(c)
		code := cmd.Main(com, ctx, t.args)
		c.Logf(bufferString(ctx.Stderr))
		c.Assert(code, Equals, t.code)
		if code == 0 {
			c.Assert(bufferString(ctx.Stderr), Equals, "")
			expect := t.out
			if expect != "" {
				expect = expect + "\n"
			}
			c.Assert(bufferString(ctx.Stdout), Equals, expect)
		} else {
			c.Assert(bufferString(ctx.Stdout), Equals, "")
			expect := fmt.Sprintf(`(.|\n)*error: %s\n`, t.out)
			c.Assert(bufferString(ctx.Stderr), Matches, expect)
		}
	}
}
Beispiel #13
0
func runStatus(c *C, args ...string) (code int, stdout, stderr []byte) {
	ctx := coretesting.Context(c)
	code = cmd.Main(&StatusCommand{}, ctx, args)
	stdout = ctx.Stdout.(*bytes.Buffer).Bytes()
	stderr = ctx.Stderr.(*bytes.Buffer).Bytes()
	return
}
Beispiel #14
0
func (s *RelationListSuite) TestRelationListHelp(c *C) {
	template := `
usage: relation-list [options]
purpose: list relation units

options:
--format  (= smart)
    specify output format (json|smart|yaml)
-o, --output (= "")
    specify an output file
-r  (= %s)
    specify a relation by id
%s`[1:]

	for relid, t := range map[int]struct {
		usage, doc string
	}{
		-1: {"", "\n-r must be specified when not in a relation hook\n"},
		0:  {"peer0:0", ""},
	} {
		c.Logf("test relid %d", relid)
		hctx := s.GetHookContext(c, relid, "")
		com, err := jujuc.NewCommand(hctx, "relation-list")
		c.Assert(err, IsNil)
		ctx := testing.Context(c)
		code := cmd.Main(com, ctx, []string{"--help"})
		c.Assert(code, Equals, 0)
		expect := fmt.Sprintf(template, t.usage, t.doc)
		c.Assert(bufferString(ctx.Stdout), Equals, expect)
		c.Assert(bufferString(ctx.Stderr), Equals, "")
	}
}
func (s *ValidateMetadataSuite) TestOpenstackLocalMetadataNoMatch(c *gc.C) {
	s.makeLocalMetadata(c, "1234", "region-2", "raring", "some-auth-url")
	ctx := coretesting.Context(c)
	metadataDir := config.JujuHomePath("")
	code := cmd.Main(
		&ValidateImageMetadataCommand{}, ctx, []string{
			"-p", "openstack", "-s", "precise", "-r", "region-2",
			"-u", "some-auth-url", "-d", metadataDir},
	)
	c.Assert(code, gc.Equals, 1)
	code = cmd.Main(
		&ValidateImageMetadataCommand{}, ctx, []string{
			"-p", "openstack", "-s", "raring", "-r", "region-3",
			"-u", "some-auth-url", "-d", metadataDir},
	)
	c.Assert(code, gc.Equals, 1)
}
func (s *ValidateMetadataSuite) TestEc2LocalMetadataNoMatch(c *gc.C) {
	s.setupEc2LocalMetadata(c, "us-east-1")
	ctx := coretesting.Context(c)
	metadataDir := config.JujuHomePath("")
	code := cmd.Main(
		&ValidateImageMetadataCommand{}, ctx, []string{
			"-p", "ec2", "-s", "raring", "-r", "us-west-1",
			"-u", "https://ec2.us-west-1.amazonaws.com", "-d", metadataDir},
	)
	c.Assert(code, gc.Equals, 1)
	code = cmd.Main(
		&ValidateImageMetadataCommand{}, ctx, []string{
			"-p", "ec2", "-s", "precise", "-r", "region",
			"-u", "https://ec2.region.amazonaws.com", "-d", metadataDir},
	)
	c.Assert(code, gc.Equals, 1)
}
Beispiel #17
0
// Main registers subcommands for the jujud executable, and hands over control
// to the cmd package. This function is not redundant with main, because it
// provides an entry point for testing with arbitrary command line arguments.
func Main(args []string) {
	jujud := &cmd.SuperCommand{Name: "jujud", Doc: jujudDoc, Log: &cmd.Log{}}
	jujud.Register(&BootstrapCommand{})
	jujud.Register(&MachineAgent{})
	jujud.Register(&UnitAgent{})
	jujud.Register(&VersionCommand{})
	os.Exit(cmd.Main(jujud, cmd.DefaultContext(), args[1:]))
}
func (s *SuperCommandSuite) TestDescription(c *C) {
	jc := cmd.NewSuperCommand(cmd.SuperCommandParams{Name: "jujutest", Purpose: "blow up the death star"})
	jc.Register(&TestCommand{Name: "blah"})
	ctx := testing.Context(c)
	code := cmd.Main(jc, ctx, []string{"blah", "--description"})
	c.Assert(code, Equals, 0)
	c.Assert(bufferString(ctx.Stdout), Equals, "blow up the death star\n")
}
Beispiel #19
0
func runCmdLine(c *C, com cmd.Command, args ...string) (code int, stdout, stderr string) {
	ctx := coretesting.Context(c)
	code = cmd.Main(com, ctx, args)
	stdout = ctx.Stdout.(*bytes.Buffer).String()
	stderr = ctx.Stderr.(*bytes.Buffer).String()
	c.Logf("args:   %#v\ncode:   %d\nstdout: %q\nstderr: %q", args, code, stdout, stderr)
	return
}
func (s *ImageMetadataSuite) TestImageMetadataBadArgs(c *gc.C) {
	defer testing.MakeEmptyFakeHome(c).Restore()
	for i, t := range errTests {
		c.Logf("test: %d", i)
		ctx := testing.Context(c)
		code := cmd.Main(&ImageMetadataCommand{}, ctx, t.args)
		c.Check(code, gc.Equals, 2)
	}
}
Beispiel #21
0
func (s *CmdSuite) TestMainHelp(c *C) {
	for _, arg := range []string{"-h", "--help"} {
		ctx := dummyContext(c)
		result := cmd.Main(&TestCommand{Name: "verb"}, ctx, []string{arg})
		c.Assert(result, Equals, 0)
		c.Assert(bufferString(ctx.Stdout), Equals, "")
		c.Assert(bufferString(ctx.Stderr), Equals, fullHelp)
	}
}
func (s *SuperCommandSuite) TestHelpWithPrefix(c *C) {
	jc := cmd.NewSuperCommand(cmd.SuperCommandParams{Name: "jujutest", UsagePrefix: "juju"})
	jc.Register(&TestCommand{Name: "blah"})
	ctx := testing.Context(c)
	code := cmd.Main(jc, ctx, []string{"blah", "--help"})
	c.Assert(code, Equals, 0)
	stripped := strings.Replace(bufferString(ctx.Stdout), "\n", "", -1)
	c.Assert(stripped, Matches, ".*usage: juju jujutest blah.*blah-doc.*")
}
Beispiel #23
0
func (s *CmdSuite) TestStdin(c *C) {
	const phrase = "Do you, Juju?"
	ctx := dummyContext(c)
	ctx.Stdin = bytes.NewBuffer([]byte(phrase))
	result := cmd.Main(&TestCommand{Name: "verb"}, ctx, []string{"--option", "echo"})
	c.Assert(result, Equals, 0)
	c.Assert(bufferString(ctx.Stdout), Equals, phrase)
	c.Assert(bufferString(ctx.Stderr), Equals, "")
}
Beispiel #24
0
func (s *ConfigGetSuite) TestAllPlusKey(c *C) {
	hctx := s.GetHookContext(c, -1, "")
	com, err := jujuc.NewCommand(hctx, "config-get")
	c.Assert(err, IsNil)
	ctx := testing.Context(c)
	code := cmd.Main(com, ctx, []string{"--all", "--format", "json", "monsters"})
	c.Assert(code, Equals, 2)
	c.Assert(bufferString(ctx.Stderr), Equals, "error: cannot use argument --all together with key \"monsters\"\n")
}
func (*BootstrapSuite) TestMissingEnvironment(c *C) {
	defer testing.MakeFakeHomeNoEnvironments(c, "empty").Restore()
	ctx := testing.Context(c)
	code := cmd.Main(&BootstrapCommand{}, ctx, nil)
	c.Check(code, Equals, 1)
	errStr := ctx.Stderr.(*bytes.Buffer).String()
	strippedErr := strings.Replace(errStr, "\n", "", -1)
	c.Assert(strippedErr, Matches, ".*No juju environment configuration file exists.*")
}
Beispiel #26
0
func (s *CmdSuite) TestMainInitError(c *C) {
	for _, t := range initErrorTests {
		ctx := dummyContext(c)
		result := cmd.Main(t.c, ctx, []string{"--unknown"})
		c.Assert(result, Equals, 2)
		c.Assert(bufferString(ctx.Stdout), Equals, "")
		expected := "error: flag provided but not defined: --unknown\n"
		c.Assert(bufferString(ctx.Stderr), Equals, expected)
	}
}
func (s *ImageMetadataSuite) TestImageMetadataFilesDefaultArch(c *gc.C) {
	defer testing.MakeEmptyFakeHome(c).Restore()

	ctx := testing.Context(c)
	code := cmd.Main(
		&ImageMetadataCommand{}, ctx, []string{"-i", "1234", "-r", "region", "-u", "endpoint", "-s", "raring"})
	c.Assert(code, gc.Equals, 0)
	errOut := ctx.Stdout.(*bytes.Buffer).String()
	s.assertCommandOutput(c, errOut, "raring", "amd64", defaultIndexFileName, defaultImageFileName)
}
Beispiel #28
0
func (s *SuperCommandSuite) TestLogging(c *C) {
	jc := cmd.NewSuperCommand(cmd.SuperCommandParams{Name: "jujutest", Log: &cmd.Log{}})
	jc.Register(&TestCommand{Name: "blah"})
	ctx := testing.Context(c)
	code := cmd.Main(jc, ctx, []string{"blah", "--option", "error", "--debug"})
	c.Assert(code, Equals, 1)
	c.Assert(bufferString(ctx.Stderr), Matches, `^.* ERROR .* command failed: BAM!
error: BAM!
`)
}
Beispiel #29
0
func (s *UnitGetSuite) TestOutputFormat(c *C) {
	for _, t := range unitGetTests {
		com := s.createCommand(c)
		ctx := testing.Context(c)
		code := cmd.Main(com, ctx, t.args)
		c.Assert(code, Equals, 0)
		c.Assert(bufferString(ctx.Stderr), Equals, "")
		c.Assert(bufferString(ctx.Stdout), Matches, t.out)
	}
}
func (s *ImageMetadataSuite) TestImageMetadataFilesUsingEnvEndpoint(c *gc.C) {
	defer testing.MakeEmptyFakeHome(c).Restore()

	os.Setenv("OS_AUTH_URL", "endpoint")
	ctx := testing.Context(c)
	code := cmd.Main(
		&ImageMetadataCommand{}, ctx, []string{"-i", "1234", "-r", "region"})
	c.Assert(code, gc.Equals, 0)
	errOut := ctx.Stdout.(*bytes.Buffer).String()
	s.assertCommandOutput(c, errOut, "precise", "amd64", defaultIndexFileName, defaultImageFileName)
}