func (ms *mgrsSuite) installLocalTestSnap(c *C, snapYamlContent string) *snap.Info { st := ms.o.State() snapPath := makeTestSnap(c, snapYamlContent) snapf, err := snap.Open(snapPath) c.Assert(err, IsNil) info, err := snap.ReadInfoFromSnapFile(snapf, nil) c.Assert(err, IsNil) // store current state snapName := info.Name() var snapst snapstate.SnapState snapstate.Get(st, snapName, &snapst) ts, err := snapstate.InstallPath(st, &snap.SideInfo{RealName: snapName}, snapPath, "", snapstate.Flags{DevMode: true}) c.Assert(err, IsNil) chg := st.NewChange("install-snap", "...") chg.AddAll(ts) st.Unlock() err = ms.o.Settle() st.Lock() c.Assert(err, IsNil) c.Assert(chg.Err(), IsNil) c.Assert(chg.Status(), Equals, state.DoneStatus, Commentf("install-snap change failed with: %v", chg.Err())) return info }
func (ms *mgrsSuite) TestHappyLocalInstall(c *C) { snapYamlContent := `name: foo apps: bar: command: bin/bar ` snapPath := makeTestSnap(c, snapYamlContent+"version: 1.0") st := ms.o.State() st.Lock() defer st.Unlock() ts, err := snapstate.InstallPath(st, &snap.SideInfo{RealName: "foo"}, snapPath, "", snapstate.Flags{DevMode: true}) c.Assert(err, IsNil) chg := st.NewChange("install-snap", "...") chg.AddAll(ts) st.Unlock() err = ms.o.Settle() st.Lock() c.Assert(err, IsNil) c.Assert(chg.Status(), Equals, state.DoneStatus, Commentf("install-snap change failed with: %v", chg.Err())) snap, err := snapstate.CurrentInfo(st, "foo") c.Assert(err, IsNil) // ensure that the binary wrapper file got generated with the right // name binaryWrapper := filepath.Join(dirs.SnapBinariesDir, "foo.bar") c.Assert(osutil.IsSymlink(binaryWrapper), Equals, true) // data dirs c.Assert(osutil.IsDirectory(snap.DataDir()), Equals, true) c.Assert(osutil.IsDirectory(snap.CommonDataDir()), Equals, true) // snap file and its mounting // after install the snap file is in the right dir c.Assert(osutil.FileExists(filepath.Join(dirs.SnapBlobDir, "foo_x1.snap")), Equals, true) // ensure the right unit is created mup := systemd.MountUnitPath("/snap/foo/x1") content, err := ioutil.ReadFile(mup) c.Assert(err, IsNil) c.Assert(string(content), Matches, "(?ms).*^Where=/snap/foo/x1") c.Assert(string(content), Matches, "(?ms).*^What=/var/lib/snapd/snaps/foo_x1.snap") }
func (ms *mgrsSuite) TestCheckInterfaces(c *C) { snapDecl := ms.prereqSnapAssertions(c) snapYamlContent := `name: foo apps: bar: command: bin/bar slots: network: ` snapPath := makeTestSnap(c, snapYamlContent+"version: 1.5") si := &snap.SideInfo{ RealName: "foo", SnapID: fooSnapID, Revision: snap.R(55), DeveloperID: "devdevdevID", Developer: "devdevdev", } st := ms.o.State() st.Lock() defer st.Unlock() // have the snap-declaration in the system db err := assertstate.Add(st, ms.storeSigning.StoreAccountKey("")) c.Assert(err, IsNil) err = assertstate.Add(st, ms.devAcct) c.Assert(err, IsNil) err = assertstate.Add(st, snapDecl) c.Assert(err, IsNil) ts, err := snapstate.InstallPath(st, si, snapPath, "", snapstate.Flags{DevMode: true}) c.Assert(err, IsNil) chg := st.NewChange("install-snap", "...") chg.AddAll(ts) st.Unlock() err = ms.o.Settle() st.Lock() c.Assert(err, IsNil) c.Assert(chg.Err(), ErrorMatches, `(?s).*installation not allowed by "network" slot rule of interface "network".*`) c.Check(chg.Status(), Equals, state.ErrorStatus) }
func (ms *mgrsSuite) TestInstallKernelSnapUpdatesBootloader(c *C) { bootloader := boottest.NewMockBootloader("mock", c.MkDir()) partition.ForceBootloader(bootloader) defer partition.ForceBootloader(nil) restore := release.MockOnClassic(false) defer restore() const packageKernel = ` name: krnl version: 4.0-1 type: kernel` files := [][]string{ {"kernel.img", "I'm a kernel"}, {"initrd.img", "...and I'm an initrd"}, {"meta/kernel.yaml", "version: 4.2"}, } snapPath := snaptest.MakeTestSnapWithFiles(c, packageKernel, files) st := ms.o.State() st.Lock() defer st.Unlock() ts, err := snapstate.InstallPath(st, &snap.SideInfo{RealName: "krnl"}, snapPath, "", 0) c.Assert(err, IsNil) chg := st.NewChange("install-snap", "...") chg.AddAll(ts) st.Unlock() err = ms.o.Settle() st.Lock() c.Assert(err, IsNil) c.Assert(chg.Status(), Equals, state.DoneStatus, Commentf("install-snap change failed with: %v", chg.Err())) c.Assert(bootloader.BootVars, DeepEquals, map[string]string{ "snap_try_kernel": "krnl_x1.snap", "snap_mode": "try", }) }
func (ms *mgrsSuite) TestInstallCoreSnapUpdatesBootloader(c *C) { bootloader := boottest.NewMockBootloader("mock", c.MkDir()) partition.ForceBootloader(bootloader) defer partition.ForceBootloader(nil) restore := release.MockOnClassic(false) defer restore() const packageOS = ` name: core version: 16.04-1 type: os ` snapPath := makeTestSnap(c, packageOS) st := ms.o.State() st.Lock() defer st.Unlock() ts, err := snapstate.InstallPath(st, &snap.SideInfo{RealName: "core"}, snapPath, "", 0) c.Assert(err, IsNil) chg := st.NewChange("install-snap", "...") chg.AddAll(ts) st.Unlock() err = ms.o.Settle() st.Lock() c.Assert(err, IsNil) c.Assert(chg.Status(), Equals, state.DoneStatus, Commentf("install-snap change failed with: %v", chg.Err())) c.Assert(bootloader.BootVars, DeepEquals, map[string]string{ "snap_try_core": "core_x1.snap", "snap_mode": "try", }) }
func (ms *mgrsSuite) TestInstallKernelSnapUpdatesBootloader(c *C) { bootloader := boottest.NewMockBootloader("mock", c.MkDir()) partition.ForceBootloader(bootloader) defer partition.ForceBootloader(nil) restore := release.MockOnClassic(false) defer restore() brandAcct := assertstest.NewAccount(ms.storeSigning, "my-brand", map[string]interface{}{ "account-id": "my-brand", "verification": "certified", }, "") brandAccKey := assertstest.NewAccountKey(ms.storeSigning, brandAcct, nil, brandPrivKey.PublicKey(), "") brandSigning := assertstest.NewSigningDB("my-brand", brandPrivKey) model, err := 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": "gadget", "kernel": "krnl", "timestamp": time.Now().Format(time.RFC3339), }, nil, "") c.Assert(err, IsNil) const packageKernel = ` name: krnl version: 4.0-1 type: kernel` files := [][]string{ {"kernel.img", "I'm a kernel"}, {"initrd.img", "...and I'm an initrd"}, {"meta/kernel.yaml", "version: 4.2"}, } snapPath := snaptest.MakeTestSnapWithFiles(c, packageKernel, files) st := ms.o.State() st.Lock() defer st.Unlock() // setup model assertion err = assertstate.Add(st, ms.storeSigning.StoreAccountKey("")) c.Assert(err, IsNil) err = assertstate.Add(st, brandAcct) c.Assert(err, IsNil) err = assertstate.Add(st, brandAccKey) c.Assert(err, IsNil) auth.SetDevice(st, &auth.DeviceState{ Brand: "my-brand", Model: "my-model", }) err = assertstate.Add(st, model) c.Assert(err, IsNil) ts, err := snapstate.InstallPath(st, &snap.SideInfo{RealName: "krnl"}, snapPath, "", snapstate.Flags{}) c.Assert(err, IsNil) chg := st.NewChange("install-snap", "...") chg.AddAll(ts) st.Unlock() err = ms.o.Settle() st.Lock() c.Assert(err, IsNil) c.Assert(chg.Status(), Equals, state.DoneStatus, Commentf("install-snap change failed with: %v", chg.Err())) c.Assert(bootloader.BootVars, DeepEquals, map[string]string{ "snap_try_kernel": "krnl_x1.snap", "snap_mode": "try", }) }
func (ms *mgrsSuite) TestHappyLocalInstallWithStoreMetadata(c *C) { snapDecl := ms.prereqSnapAssertions(c) snapYamlContent := `name: foo apps: bar: command: bin/bar ` snapPath := makeTestSnap(c, snapYamlContent+"version: 1.5") si := &snap.SideInfo{ RealName: "foo", SnapID: fooSnapID, Revision: snap.R(55), DeveloperID: "devdevdevID", Developer: "devdevdev", } st := ms.o.State() st.Lock() defer st.Unlock() // have the snap-declaration in the system db err := assertstate.Add(st, ms.storeSigning.StoreAccountKey("")) c.Assert(err, IsNil) err = assertstate.Add(st, ms.devAcct) c.Assert(err, IsNil) err = assertstate.Add(st, snapDecl) c.Assert(err, IsNil) ts, err := snapstate.InstallPath(st, si, snapPath, "", snapstate.Flags{DevMode: true}) c.Assert(err, IsNil) chg := st.NewChange("install-snap", "...") chg.AddAll(ts) st.Unlock() err = ms.o.Settle() st.Lock() c.Assert(err, IsNil) c.Assert(chg.Status(), Equals, state.DoneStatus, Commentf("install-snap change failed with: %v", chg.Err())) info, err := snapstate.CurrentInfo(st, "foo") c.Assert(err, IsNil) c.Check(info.Revision, Equals, snap.R(55)) c.Check(info.SnapID, Equals, fooSnapID) c.Check(info.DeveloperID, Equals, "devdevdevID") c.Check(info.Developer, Equals, "devdevdev") c.Check(info.Version, Equals, "1.5") // ensure that the binary wrapper file got generated with the right // name binaryWrapper := filepath.Join(dirs.SnapBinariesDir, "foo.bar") c.Assert(osutil.IsSymlink(binaryWrapper), Equals, true) // data dirs c.Assert(osutil.IsDirectory(info.DataDir()), Equals, true) c.Assert(osutil.IsDirectory(info.CommonDataDir()), Equals, true) // snap file and its mounting // after install the snap file is in the right dir c.Assert(osutil.FileExists(filepath.Join(dirs.SnapBlobDir, "foo_55.snap")), Equals, true) // ensure the right unit is created mup := systemd.MountUnitPath("/snap/foo/55") content, err := ioutil.ReadFile(mup) c.Assert(err, IsNil) c.Assert(string(content), Matches, "(?ms).*^Where=/snap/foo/55") c.Assert(string(content), Matches, "(?ms).*^What=/var/lib/snapd/snaps/foo_55.snap") }
func populateStateFromSeedImpl(st *state.State) ([]*state.TaskSet, error) { // check that the state is empty var seeded bool err := st.Get("seeded", &seeded) if err != nil && err != state.ErrNoState { return nil, err } if seeded { return nil, fmt.Errorf("cannot populate state: already seeded") } // ack all initial assertions if err := importAssertionsFromSeed(st); err != nil { return nil, err } seed, err := snap.ReadSeedYaml(filepath.Join(dirs.SnapSeedDir, "seed.yaml")) if err != nil { return nil, err } tsAll := []*state.TaskSet{} for i, sn := range seed.Snaps { var flags snapstate.Flags if sn.DevMode { flags.DevMode = true } 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 { return nil, fmt.Errorf("cannot find signatures with metadata for snap %q (%q)", sn.Name, path) } if err != nil { return nil, 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]) } if err != nil { return nil, err } tsAll = append(tsAll, ts) } if len(tsAll) == 0 { return nil, nil } ts := tsAll[len(tsAll)-1] markSeeded := st.NewTask("mark-seeded", i18n.G("Mark system seeded")) markSeeded.WaitAll(ts) tsAll = append(tsAll, state.NewTaskSet(markSeeded)) return tsAll, nil }
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() }