Esempio n. 1
0
func (s *getSuite) TestCommandGetsSettedValues(c *C) {
	// Set a value via the `snapctl set` command
	_, _, err := ctlcmd.Run(s.mockContext, []string{"set", "foo=bar"})
	c.Check(err, IsNil)

	stdout, stderr, err := ctlcmd.Run(s.mockContext, []string{"get", "foo"})
	c.Check(err, IsNil)
	c.Check(string(stderr), Equals, "")
	c.Check(string(stdout), Equals, "\"bar\"")
}
Esempio n. 2
0
func (s *getSuite) TestCommandMultipleKeys(c *C) {
	// Set a value via the `snapctl set` command
	_, _, err := ctlcmd.Run(s.mockContext, []string{"set", "test-key=test-value"})
	c.Check(err, IsNil)

	stdout, stderr, err := ctlcmd.Run(s.mockContext, []string{"get", "initial-key", "test-key"})
	c.Check(err, IsNil)
	c.Check(string(stderr), Equals, "")
	c.Check(string(stdout), Equals, `{
	"initial-key": "initial-value",
	"test-key": "test-value"
}`)
}
Esempio n. 3
0
func (s *getSuite) TestGetTests(c *C) {
	for _, test := range getTests {
		c.Logf("Test: %s", test.args)

		mockHandler := hooktest.NewMockHandler()

		state := state.New(nil)
		state.Lock()

		task := state.NewTask("test-task", "my test task")
		setup := &hookstate.HookSetup{Snap: "test-snap", Revision: snap.R(1), Hook: "test-hook"}

		var err error
		mockContext, err := hookstate.NewContext(task, setup, mockHandler)
		c.Check(err, IsNil)

		// Initialize configuration
		t := configstate.NewTransaction(state)
		t.Set("test-snap", "test-key1", "test-value1")
		t.Set("test-snap", "test-key2", 2)
		t.Commit()

		state.Unlock()

		stdout, stderr, err := ctlcmd.Run(mockContext, strings.Fields(test.args))
		if test.error != "" {
			c.Check(err, ErrorMatches, test.error)
		} else {
			c.Check(err, IsNil)
			c.Check(string(stderr), Equals, "")
			c.Check(string(stdout), Equals, test.stdout)
		}
	}
}
Esempio n. 4
0
func (s *setSuite) TestCommandSavesDeltasOnly(c *C) {
	// Setup an initial configuration
	s.mockContext.State().Lock()
	transaction, err := configstate.NewTransaction(s.mockContext.State())
	c.Check(err, IsNil)
	transaction.Set("test-snap", "test-key1", "test-value1")
	transaction.Set("test-snap", "test-key2", "test-value2")
	transaction.Commit()
	s.mockContext.State().Unlock()

	stdout, stderr, err := ctlcmd.Run(s.mockContext, []string{"set", "test-key2=test-value3"})
	c.Check(err, IsNil)
	c.Check(string(stdout), Equals, "")
	c.Check(string(stderr), Equals, "")

	// Notify the context that we're done. This should save the config.
	s.mockContext.Lock()
	defer s.mockContext.Unlock()
	c.Check(s.mockContext.Done(), IsNil)

	// Verify that the global config has been updated, but only test-key2
	transaction, err = configstate.NewTransaction(s.mockContext.State())
	c.Check(err, IsNil)
	var value string
	c.Check(transaction.Get("test-snap", "test-key1", &value), IsNil)
	c.Check(value, Equals, "test-value1")
	c.Check(transaction.Get("test-snap", "test-key2", &value), IsNil)
	c.Check(value, Equals, "test-value3")
}
Esempio n. 5
0
func (s *setSuite) TestCommand(c *C) {
	stdout, stderr, err := ctlcmd.Run(s.mockContext, []string{"set", "foo=bar", "baz=qux"})
	c.Check(err, IsNil)
	c.Check(string(stdout), Equals, "")
	c.Check(string(stderr), Equals, "")

	// Verify that the previous set doesn't modify the global state
	s.mockContext.State().Lock()
	transaction, err := configstate.NewTransaction(s.mockContext.State())
	s.mockContext.State().Unlock()
	c.Check(err, IsNil)
	var value string
	c.Check(transaction.Get("test-snap", "foo", &value), ErrorMatches, ".*snap.*has no.*configuration.*")
	c.Check(transaction.Get("test-snap", "baz", &value), ErrorMatches, ".*snap.*has no.*configuration.*")

	// Notify the context that we're done. This should save the config.
	s.mockContext.Lock()
	defer s.mockContext.Unlock()
	c.Check(s.mockContext.Done(), IsNil)

	// Verify that the global config has been updated.
	transaction, err = configstate.NewTransaction(s.mockContext.State())
	c.Check(err, IsNil)
	c.Check(transaction.Get("test-snap", "foo", &value), IsNil)
	c.Check(value, Equals, "bar")
	c.Check(transaction.Get("test-snap", "baz", &value), IsNil)
	c.Check(value, Equals, "qux")
}
Esempio n. 6
0
func runSnapctl(c *Command, r *http.Request, user *auth.UserState) Response {
	var snapctlOptions client.SnapCtlOptions
	decoder := json.NewDecoder(r.Body)
	if err := decoder.Decode(&snapctlOptions); err != nil {
		return BadRequest("cannot decode snapctl request: %s", err)
	}

	if len(snapctlOptions.Args) == 0 {
		return BadRequest("snapctl cannot run without args")
	}

	// Right now snapctl is only used for hooks. If at some point it grows
	// beyond that, this probably shouldn't go straight to the HookManager.
	context, _ := c.d.overlord.HookManager().Context(snapctlOptions.ContextID)
	stdout, stderr, err := ctlcmd.Run(context, snapctlOptions.Args)
	if err != nil {
		if e, ok := err.(*flags.Error); ok && e.Type == flags.ErrHelp {
			stdout = []byte(e.Error())
		} else {
			return BadRequest("error running snapctl: %s", err)
		}
	}

	result := map[string]string{
		"stdout": string(stdout),
		"stderr": string(stderr),
	}

	return SyncResponse(result, nil)
}
Esempio n. 7
0
func (s *ctlcmdSuite) TestCommandOutput(c *C) {
	mockCommand := ctlcmd.AddMockCommand("mock")
	defer ctlcmd.RemoveCommand("mock")

	mockCommand.FakeStdout = "test stdout"
	mockCommand.FakeStderr = "test stderr"

	stdout, stderr, err := ctlcmd.Run(s.mockContext, []string{"mock", "foo"})
	c.Check(err, IsNil)
	c.Check(string(stdout), Equals, "test stdout")
	c.Check(string(stderr), Equals, "test stderr")
	c.Check(mockCommand.Args, DeepEquals, []string{"foo"})
}
Esempio n. 8
0
func (s *deviceMgrSuite) TestFullDeviceRegistrationHappyPrepareDeviceHook(c *C) {
	r1 := devicestate.MockKeyLength(752)
	defer r1()

	mockServer := s.mockServer(c, "REQID-1")
	defer mockServer.Close()

	r2 := hookstate.MockRunHook(func(ctx *hookstate.Context, _ *tomb.Tomb) ([]byte, error) {
		c.Assert(ctx.HookName(), Equals, "prepare-device")

		// snapctl set the registration params
		_, _, err := ctlcmd.Run(ctx, []string{"set", fmt.Sprintf("device-service.url=%q", mockServer.URL+"/identity/api/v1/")})
		c.Assert(err, IsNil)

		h, err := json.Marshal(map[string]string{
			"x-extra-header": "extra",
		})
		c.Assert(err, IsNil)
		_, _, err = ctlcmd.Run(ctx, []string{"set", fmt.Sprintf("device-service.headers=%s", string(h))})
		c.Assert(err, IsNil)

		_, _, err = ctlcmd.Run(ctx, []string{"set", fmt.Sprintf("registration.proposed-serial=%q", "Y9999")})
		c.Assert(err, IsNil)

		d, err := yaml.Marshal(map[string]string{
			"mac": "00:00:00:00:ff:00",
		})
		c.Assert(err, IsNil)
		_, _, err = ctlcmd.Run(ctx, []string{"set", fmt.Sprintf("registration.body=%q", d)})
		c.Assert(err, IsNil)

		return nil, nil
	})
	defer r2()

	// setup state as will be done by first-boot
	// & have a gadget with a prepare-device hook
	s.state.Lock()
	defer s.state.Unlock()

	s.setupGadget(c, `
name: gadget
type: gadget
version: gadget
hooks:
    prepare-device:
`, "")

	auth.SetDevice(s.state, &auth.DeviceState{
		Brand: "canonical",
		Model: "pc",
	})

	// runs the whole device registration process
	s.state.Unlock()
	s.settle()
	s.state.Lock()

	var becomeOperational *state.Change
	for _, chg := range s.state.Changes() {
		if chg.Kind() == "become-operational" {
			becomeOperational = chg
			break
		}
	}
	c.Assert(becomeOperational, NotNil)

	c.Check(becomeOperational.Status().Ready(), Equals, true)
	c.Check(becomeOperational.Err(), IsNil)

	device, err := auth.Device(s.state)
	c.Assert(err, IsNil)
	c.Check(device.Brand, Equals, "canonical")
	c.Check(device.Model, Equals, "pc")
	c.Check(device.Serial, Equals, "Y9999")

	a, err := s.db.Find(asserts.SerialType, map[string]string{
		"brand-id": "canonical",
		"model":    "pc",
		"serial":   "Y9999",
	})
	c.Assert(err, IsNil)
	serial := a.(*asserts.Serial)

	var details map[string]interface{}
	err = yaml.Unmarshal(serial.Body(), &details)
	c.Assert(err, IsNil)

	c.Check(details, DeepEquals, map[string]interface{}{
		"mac": "00:00:00:00:ff:00",
	})

	privKey, err := s.mgr.KeypairManager().Get(serial.DeviceKey().ID())
	c.Assert(err, IsNil)
	c.Check(privKey, NotNil)

	c.Check(device.KeyID, Equals, privKey.PublicKey().ID())
}
Esempio n. 9
0
func (s *getSuite) TestCommandWithoutContext(c *C) {
	_, _, err := ctlcmd.Run(nil, []string{"get", "foo"})
	c.Check(err, ErrorMatches, ".*cannot get without a context.*")
}
Esempio n. 10
0
func (s *getSuite) TestCommandWithNoConfig(c *C) {
	stdout, stderr, err := ctlcmd.Run(s.mockContext, []string{"get", "foo"})
	c.Check(err, ErrorMatches, ".*snap.*has no.*configuration option.*")
	c.Check(string(stderr), Equals, "")
	c.Check(string(stdout), Equals, "")
}
Esempio n. 11
0
func (s *getSuite) TestCommand(c *C) {
	stdout, stderr, err := ctlcmd.Run(s.mockContext, []string{"get", "initial-key"})
	c.Check(err, IsNil)
	c.Check(string(stderr), Equals, "")
	c.Check(string(stdout), Equals, "\"initial-value\"")
}
Esempio n. 12
0
func (s *setSuite) TestInvalidArguments(c *C) {
	_, _, err := ctlcmd.Run(s.mockContext, []string{"set", "foo", "bar"})
	c.Check(err, ErrorMatches, ".*invalid parameter.*want key=value.*")
}
Esempio n. 13
0
func (s *ctlcmdSuite) TestNonExistingCommand(c *C) {
	stdout, stderr, err := ctlcmd.Run(s.mockContext, []string{"foo"})
	c.Check(string(stdout), Equals, "")
	c.Check(string(stderr), Equals, "")
	c.Check(err, ErrorMatches, ".*[Uu]nknown command.*")
}