func (ovs *overlordSuite) TestNew(c *C) { restore := patch.Mock(42, nil) defer restore() o, err := overlord.New() c.Assert(err, IsNil) c.Check(o, NotNil) c.Check(o.SnapManager(), NotNil) c.Check(o.AssertManager(), NotNil) c.Check(o.InterfaceManager(), NotNil) c.Check(o.DeviceManager(), NotNil) s := o.State() c.Check(s, NotNil) c.Check(o.Engine().State(), Equals, s) s.Lock() defer s.Unlock() var patchLevel int s.Get("patch-level", &patchLevel) c.Check(patchLevel, Equals, 42) // store is setup sto := snapstate.Store(s) c.Check(sto, FitsTypeOf, &store.Store{}) }
func (ms *mgrsSuite) SetUpTest(c *C) { ms.tempdir = c.MkDir() dirs.SetRootDir(ms.tempdir) err := os.MkdirAll(filepath.Dir(dirs.SnapStateFile), 0755) c.Assert(err, IsNil) os.Setenv("SNAPPY_SQUASHFS_UNPACK_FOR_TESTS", "1") // create a fake systemd environment os.MkdirAll(filepath.Join(dirs.SnapServicesDir, "multi-user.target.wants"), 0755) ms.prevctlCmd = systemd.SystemctlCmd systemd.SystemctlCmd = func(cmd ...string) ([]byte, error) { return []byte("ActiveState=inactive\n"), nil } ms.aa = testutil.MockCommand(c, "apparmor_parser", "") ms.udev = testutil.MockCommand(c, "udevadm", "") ms.umount = testutil.MockCommand(c, "umount", "") ms.snapDiscardNs = testutil.MockCommand(c, "snap-discard-ns", "") dirs.LibExecDir = ms.snapDiscardNs.BinDir() ms.storeSigning = assertstest.NewStoreStack("can0nical", rootPrivKey, storePrivKey) ms.restoreTrusted = sysdb.InjectTrusted(ms.storeSigning.Trusted) ms.devAcct = assertstest.NewAccount(ms.storeSigning, "devdevev", map[string]interface{}{ "account-id": "devdevdev", }, "") err = ms.storeSigning.Add(ms.devAcct) c.Assert(err, IsNil) o, err := overlord.New() c.Assert(err, IsNil) ms.o = o }
func (ovs *overlordSuite) TestTrivialSettle(c *C) { restoreIntv := overlord.MockEnsureInterval(1 * time.Minute) defer restoreIntv() o, err := overlord.New() c.Assert(err, IsNil) se := o.Engine() s := se.State() rm1 := newRunnerManager(s) se.AddManager(rm1) defer o.Engine().Stop() s.Lock() defer s.Unlock() chg := s.NewChange("chg", "...") t1 := s.NewTask("runMgr1", "1...") chg.AddTask(t1) s.Unlock() o.Settle() s.Lock() c.Check(t1.Status(), Equals, state.DoneStatus) var v int err = s.Get("runMgr1Mark", &v) c.Check(err, IsNil) }
func (ovs *overlordSuite) TestEnsureBeforeSleepy(c *C) { restoreIntv := overlord.MockEnsureInterval(10 * time.Minute) defer restoreIntv() o, err := overlord.New() c.Assert(err, IsNil) ensure := func(s *state.State) error { overlord.MockEnsureNext(o, time.Now().Add(-10*time.Hour)) s.EnsureBefore(0) return nil } witness := &witnessManager{ state: o.State(), expectedEnsure: 2, ensureCalled: make(chan struct{}), ensureCallback: ensure, } se := o.Engine() se.AddManager(witness) o.Loop() defer o.Stop() select { case <-witness.ensureCalled: case <-time.After(2 * time.Second): c.Fatal("Ensure calls not happening") } }
func (ovs *overlordSuite) TestEnsureLoopPrune(c *C) { restoreIntv := overlord.MockPruneInterval(10*time.Millisecond, 5*time.Millisecond, 5*time.Millisecond) defer restoreIntv() o, err := overlord.New() c.Assert(err, IsNil) st := o.State() st.Lock() t1 := st.NewTask("foo", "...") chg1 := st.NewChange("abort", "...") chg1.AddTask(t1) chg2 := st.NewChange("prune", "...") chg2.SetStatus(state.DoneStatus) st.Unlock() o.Loop() time.Sleep(50 * time.Millisecond) err = o.Stop() c.Assert(err, IsNil) st.Lock() defer st.Unlock() c.Assert(st.Change(chg1.ID()), Equals, chg1) c.Assert(st.Change(chg2.ID()), IsNil) c.Assert(t1.Status(), Equals, state.HoldStatus) }
func (s *FirstBootTestSuite) SetUpTest(c *C) { tempdir := c.MkDir() dirs.SetRootDir(tempdir) // mock the world! err := os.MkdirAll(filepath.Join(dirs.SnapSeedDir, "snaps"), 0755) c.Assert(err, IsNil) err = os.MkdirAll(filepath.Join(dirs.SnapSeedDir, "assertions"), 0755) c.Assert(err, IsNil) err = os.MkdirAll(dirs.SnapServicesDir, 0755) c.Assert(err, IsNil) os.Setenv("SNAPPY_SQUASHFS_UNPACK_FOR_TESTS", "1") s.systemctl = testutil.MockCommand(c, "systemctl", "") s.mockUdevAdm = testutil.MockCommand(c, "udevadm", "") err = ioutil.WriteFile(filepath.Join(dirs.SnapSeedDir, "seed.yaml"), nil, 0644) c.Assert(err, IsNil) rootPrivKey, _ := assertstest.GenerateKey(1024) storePrivKey, _ := assertstest.GenerateKey(752) s.storeSigning = assertstest.NewStoreStack("can0nical", rootPrivKey, storePrivKey) s.restore = sysdb.InjectTrusted(s.storeSigning.Trusted) s.brandPrivKey, _ = assertstest.GenerateKey(752) s.brandSigning = assertstest.NewSigningDB("my-brand", s.brandPrivKey) ovld, err := overlord.New() c.Assert(err, IsNil) s.overlord = ovld }
func (ovs *overlordSuite) TestEnsureLoopRunAndStop(c *C) { restoreIntv := overlord.MockEnsureInterval(10 * time.Millisecond) defer restoreIntv() o, err := overlord.New() c.Assert(err, IsNil) witness := &witnessManager{ state: o.State(), expectedEnsure: 3, ensureCalled: make(chan struct{}), } o.Engine().AddManager(witness) o.Loop() defer o.Stop() t0 := time.Now() select { case <-witness.ensureCalled: case <-time.After(2 * time.Second): c.Fatal("Ensure calls not happening") } c.Check(time.Since(t0) >= 10*time.Millisecond, Equals, true) err = o.Stop() c.Assert(err, IsNil) }
func (ovs *overlordSuite) TestNewWithPatches(c *C) { p := func(s *state.State) error { s.Set("patched", true) return nil } patch.Mock(1, map[int]func(*state.State) error{1: p}) fakeState := []byte(fmt.Sprintf(`{"data":{"patch-level":0}}`)) err := ioutil.WriteFile(dirs.SnapStateFile, fakeState, 0600) c.Assert(err, IsNil) o, err := overlord.New() c.Assert(err, IsNil) state := o.State() c.Assert(err, IsNil) state.Lock() defer state.Unlock() var level int err = state.Get("patch-level", &level) c.Assert(err, IsNil) c.Check(level, Equals, 1) var b bool err = state.Get("patched", &b) c.Assert(err, IsNil) c.Check(b, Equals, true) }
func (x *cmdBooted) Execute(args []string) error { if len(args) > 0 { return ErrExtraArgs } if release.OnClassic { fmt.Fprintf(Stdout, i18n.G("Ignoring 'booted' on classic")) return nil } bootloader, err := partition.FindBootloader() if err != nil { return fmt.Errorf(i18n.G("cannot mark boot successful: %s"), err) } if err := partition.MarkBootSuccessful(bootloader); err != nil { return err } ovld, err := overlord.New() if err != nil { return err } return boot.UpdateRevisions(ovld) }
func (s *FirstBootTestSuite) TestImportAssertionsFromSeedHappy(c *C) { ovld, err := overlord.New() c.Assert(err, IsNil) st := ovld.State() // add a bunch of assert files assertsChain := s.makeModelAssertionChain(c) for i, as := range assertsChain { fn := filepath.Join(dirs.SnapSeedDir, "assertions", strconv.Itoa(i)) err := ioutil.WriteFile(fn, asserts.Encode(as), 0644) c.Assert(err, IsNil) } // import them err = boot.ImportAssertionsFromSeed(st) c.Assert(err, IsNil) // verify that the model was added st.Lock() defer st.Unlock() db := assertstate.DB(st) as, err := db.Find(asserts.ModelType, map[string]string{ "series": "16", "brand-id": "my-brand", "model": "my-model", }) c.Assert(err, IsNil) _, ok := as.(*asserts.Model) c.Check(ok, Equals, true) ds, err := auth.Device(st) c.Assert(err, IsNil) c.Check(ds.Brand, Equals, "my-brand") c.Check(ds.Model, Equals, "my-model") }
func (ovs *overlordSuite) TestNewWithInvalidState(c *C) { fakeState := []byte(``) err := ioutil.WriteFile(dirs.SnapStateFile, fakeState, 0600) c.Assert(err, IsNil) _, err = overlord.New() c.Assert(err, ErrorMatches, "EOF") }
func (ovs *overlordSuite) TestTrivialRunAndStop(c *C) { o, err := overlord.New() c.Assert(err, IsNil) o.Loop() err = o.Stop() c.Assert(err, IsNil) }
// New Daemon func New() (*Daemon, error) { ovld, err := overlord.New() if err != nil { return nil, err } return &Daemon{ overlord: ovld, // TODO: Decide when this should be disabled by default. enableInternalInterfaceActions: true, }, nil }
func (ovs *overlordSuite) TestRequestRestartHandler(c *C) { o, err := overlord.New() c.Assert(err, IsNil) restartRequested := false o.SetRestartHandler(func(t state.RestartType) { restartRequested = true }) o.State().RequestRestart(state.RestartDaemon) c.Check(restartRequested, Equals, true) }
func (bs *bootedSuite) SetUpTest(c *C) { dirs.SetRootDir(c.MkDir()) err := os.MkdirAll(filepath.Dir(dirs.SnapStateFile), 0755) c.Assert(err, IsNil) // booted is not running on classic release.MockOnClassic(false) bs.bootloader = boottest.NewMockBootloader("mock", c.MkDir()) bs.bootloader.BootVars["snap_core"] = "ubuntu-core_2.snap" bs.bootloader.BootVars["snap_kernel"] = "canonical-pc-linux_2.snap" partition.ForceBootloader(bs.bootloader) ovld, err := overlord.New() c.Assert(err, IsNil) bs.overlord = ovld }
func (ovs *overlordSuite) TestCheckpoint(c *C) { oldUmask := syscall.Umask(0) defer syscall.Umask(oldUmask) o, err := overlord.New() c.Assert(err, IsNil) s := o.State() s.Lock() s.Set("mark", 1) s.Unlock() st, err := os.Stat(dirs.SnapStateFile) c.Assert(err, IsNil) c.Assert(st.Mode(), Equals, os.FileMode(0600)) content, err := ioutil.ReadFile(dirs.SnapStateFile) c.Assert(err, IsNil) c.Check(string(content), testutil.Contains, `"mark":1`) }
func (s *FirstBootTestSuite) TestImportAssertionsFromSeedNoModelAsserts(c *C) { ovld, err := overlord.New() c.Assert(err, IsNil) st := ovld.State() assertsChain := s.makeModelAssertionChain(c) for _, as := range assertsChain { if as.Type() != asserts.ModelType { fn := filepath.Join(dirs.SnapSeedDir, "assertions", "model") err := ioutil.WriteFile(fn, asserts.Encode(as), 0644) c.Assert(err, IsNil) break } } // try import and verify that its rejects because other assertions are // missing err = boot.ImportAssertionsFromSeed(st) c.Assert(err, ErrorMatches, "need a model assertion") }
func (s *FirstBootTestSuite) TestImportAssertionsFromSeedTwoModelAsserts(c *C) { ovld, err := overlord.New() c.Assert(err, IsNil) st := ovld.State() // write out two model assertions model := s.makeModelAssertion(c, "my-model") fn := filepath.Join(dirs.SnapSeedDir, "assertions", "model") err = ioutil.WriteFile(fn, asserts.Encode(model), 0644) c.Assert(err, IsNil) model2 := s.makeModelAssertion(c, "my-second-model") fn = filepath.Join(dirs.SnapSeedDir, "assertions", "model2") err = ioutil.WriteFile(fn, asserts.Encode(model2), 0644) c.Assert(err, IsNil) // try import and verify that its rejects because other assertions are // missing err = boot.ImportAssertionsFromSeed(st) c.Assert(err, ErrorMatches, "cannot add more than one model assertion") }
func (ovs *overlordSuite) TestSettleExplicitEnsureBefore(c *C) { restoreIntv := overlord.MockEnsureInterval(1 * time.Minute) defer restoreIntv() o, err := overlord.New() c.Assert(err, IsNil) se := o.Engine() s := se.State() rm1 := newRunnerManager(s) rm1.ensureCallback = func() { s.Lock() defer s.Unlock() v := 0 s.Get("ensureCount", &v) s.Set("ensureCount", v+1) } se.AddManager(rm1) defer o.Engine().Stop() s.Lock() defer s.Unlock() chg := s.NewChange("chg", "...") t := s.NewTask("runMgrEnsureBefore", "...") chg.AddTask(t) s.Unlock() o.Settle() s.Lock() c.Check(t.Status(), Equals, state.DoneStatus) var v int err = s.Get("ensureCount", &v) c.Check(err, IsNil) c.Check(v, Equals, 2) }
func (ovs *overlordSuite) TestNewWithGoodState(c *C) { fakeState := []byte(fmt.Sprintf(`{"data":{"patch-level":%d,"some":"data"},"changes":null,"tasks":null,"last-change-id":0,"last-task-id":0}`, patch.Level)) err := ioutil.WriteFile(dirs.SnapStateFile, fakeState, 0600) c.Assert(err, IsNil) o, err := overlord.New() c.Assert(err, IsNil) state := o.State() c.Assert(err, IsNil) state.Lock() defer state.Unlock() d, err := state.MarshalJSON() c.Assert(err, IsNil) var got, expected map[string]interface{} err = json.Unmarshal(d, &got) c.Assert(err, IsNil) err = json.Unmarshal(fakeState, &expected) c.Assert(err, IsNil) c.Check(got, DeepEquals, expected) }
func (s *authContextSetupSuite) SetUpTest(c *C) { tempdir := c.MkDir() dirs.SetRootDir(tempdir) err := os.MkdirAll(filepath.Dir(dirs.SnapStateFile), 0755) c.Assert(err, IsNil) captureAuthContext := func(_ *store.Config, ac auth.AuthContext) *store.Store { s.ac = ac return nil } r := overlord.MockStoreNew(captureAuthContext) defer r() s.storeSigning = assertstest.NewStoreStack("can0nical", rootPrivKey, storePrivKey) s.restoreTrusted = sysdb.InjectTrusted(s.storeSigning.Trusted) s.brandSigning = assertstest.NewSigningDB("my-brand", brandPrivKey) brandAcct := assertstest.NewAccount(s.storeSigning, "my-brand", map[string]interface{}{ "account-id": "my-brand", "verification": "certified", }, "") s.storeSigning.Add(brandAcct) brandAccKey := assertstest.NewAccountKey(s.storeSigning, brandAcct, nil, brandPrivKey.PublicKey(), "") s.storeSigning.Add(brandAccKey) model, err := s.brandSigning.Sign(asserts.ModelType, map[string]interface{}{ "series": "16", "authority-id": "my-brand", "brand-id": "my-brand", "model": "my-model", "architecture": "amd64", "store": "my-brand-store-id", "gadget": "pc", "kernel": "pc-kernel", "timestamp": time.Now().Format(time.RFC3339), }, nil, "") c.Assert(err, IsNil) s.model = model.(*asserts.Model) encDevKey, err := asserts.EncodePublicKey(deviceKey.PublicKey()) c.Assert(err, IsNil) serial, err := s.brandSigning.Sign(asserts.SerialType, map[string]interface{}{ "authority-id": "my-brand", "brand-id": "my-brand", "model": "my-model", "serial": "7878", "device-key": string(encDevKey), "device-key-sha3-384": deviceKey.PublicKey().ID(), "timestamp": time.Now().Format(time.RFC3339), }, nil, "") c.Assert(err, IsNil) s.serial = serial.(*asserts.Serial) o, err := overlord.New() c.Assert(err, IsNil) s.o = o st := o.State() st.Lock() defer st.Unlock() prereqs := []asserts.Assertion{s.storeSigning.StoreAccountKey(""), brandAcct, brandAccKey} for _, a := range prereqs { err = assertstate.Add(st, a) c.Assert(err, IsNil) } }
func populateStateFromSeed() error { if osutil.FileExists(dirs.SnapStateFile) { return fmt.Errorf("cannot create state: state %q already exists", dirs.SnapStateFile) } ovld, err := overlord.New() if err != nil { return err } st := ovld.State() // ack all initial assertions if err := importAssertionsFromSeed(st); err != nil { return err } seed, err := snap.ReadSeedYaml(filepath.Join(dirs.SnapSeedDir, "seed.yaml")) if err != nil { return err } tsAll := []*state.TaskSet{} for i, sn := range seed.Snaps { st.Lock() flags := snapstate.Flags(0) if sn.DevMode { flags |= snapstate.DevMode } path := filepath.Join(dirs.SnapSeedDir, "snaps", sn.File) var sideInfo snap.SideInfo if sn.Unasserted { sideInfo.RealName = sn.Name } else { si, err := snapasserts.DeriveSideInfo(path, assertstate.DB(st)) if err == asserts.ErrNotFound { st.Unlock() return fmt.Errorf("cannot find signatures with metadata for snap %q (%q)", sn.Name, path) } if err != nil { st.Unlock() return err } sideInfo = *si sideInfo.Private = sn.Private } ts, err := snapstate.InstallPath(st, &sideInfo, path, sn.Channel, flags) if i > 0 { ts.WaitAll(tsAll[i-1]) } st.Unlock() if err != nil { return err } tsAll = append(tsAll, ts) } if len(tsAll) == 0 { return nil } st.Lock() msg := fmt.Sprintf("First boot seeding") chg := st.NewChange("seed", msg) for _, ts := range tsAll { chg.AddAll(ts) } st.Unlock() // do it and wait for ready ovld.Loop() st.EnsureBefore(0) <-chg.Ready() st.Lock() status := chg.Status() err = chg.Err() st.Unlock() if status != state.DoneStatus { ovld.Stop() return fmt.Errorf("cannot run seed change: %s", err) } return ovld.Stop() }
func (ovs *overlordSuite) TestRequestRestartNoHandler(c *C) { o, err := overlord.New() c.Assert(err, IsNil) o.State().RequestRestart(state.RestartDaemon) }