func (ms *mgrsSuite) TestHappyRefreshControl(c *C) { // test install through store and update, plus some mechanics // of update // TODO: ok to split if it gets too messy to maintain ms.prereqSnapAssertions(c) snapYamlContent := `name: foo version: @VERSION@ ` ver := "1.0" revno := "42" snapPath, _ := ms.makeStoreTestSnap(c, strings.Replace(snapYamlContent, "@VERSION@", ver, -1), revno) ms.serveSnap(snapPath, revno) mockServer := ms.mockStore(c) defer mockServer.Close() st := ms.o.State() st.Lock() defer st.Unlock() ts, err := snapstate.Install(st, "foo", "stable", snap.R(0), 0, 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())) info, err := snapstate.CurrentInfo(st, "foo") c.Assert(err, IsNil) c.Check(info.Revision, Equals, snap.R(42)) // Refresh // Setup refresh control headers := map[string]interface{}{ "series": "16", "snap-id": "bar-id", "snap-name": "bar", "publisher-id": "devdevdev", "refresh-control": []interface{}{fooSnapID}, "timestamp": time.Now().Format(time.RFC3339), } snapDeclBar, err := ms.storeSigning.Sign(asserts.SnapDeclarationType, headers, nil, "") c.Assert(err, IsNil) err = ms.storeSigning.Add(snapDeclBar) c.Assert(err, IsNil) err = assertstate.Add(st, snapDeclBar) c.Assert(err, IsNil) snapstate.Set(st, "bar", &snapstate.SnapState{ Active: true, Sequence: []*snap.SideInfo{ {RealName: "bar", SnapID: "bar-id", Revision: snap.R(1)}, }, Current: snap.R(1), SnapType: "app", }) develSigning := assertstest.NewSigningDB("devdevdev", develPrivKey) develAccKey := assertstest.NewAccountKey(ms.storeSigning, ms.devAcct, nil, develPrivKey.PublicKey(), "") err = ms.storeSigning.Add(develAccKey) c.Assert(err, IsNil) ver = "2.0" revno = "50" snapPath, _ = ms.makeStoreTestSnap(c, strings.Replace(snapYamlContent, "@VERSION@", ver, -1), revno) ms.serveSnap(snapPath, revno) updated, tss, err := snapstate.UpdateMany(st, []string{"foo"}, 0) c.Check(updated, IsNil) c.Check(tss, IsNil) // no validation we, get an error c.Check(err, ErrorMatches, `cannot refresh "foo" to revision 50: no validation by "bar"`) // setup validation headers = map[string]interface{}{ "series": "16", "snap-id": "bar-id", "approved-snap-id": fooSnapID, "approved-snap-revision": "50", "timestamp": time.Now().Format(time.RFC3339), } barValidation, err := develSigning.Sign(asserts.ValidationType, headers, nil, "") c.Assert(err, IsNil) err = ms.storeSigning.Add(barValidation) c.Assert(err, IsNil) // ... and try again updated, tss, err = snapstate.UpdateMany(st, []string{"foo"}, 0) c.Assert(err, IsNil) c.Assert(updated, DeepEquals, []string{"foo"}) c.Assert(tss, HasLen, 1) chg = st.NewChange("upgrade-snaps", "...") chg.AddAll(tss[0]) 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("upgrade-snap change failed with: %v", chg.Err())) info, err = snapstate.CurrentInfo(st, "foo") c.Assert(err, IsNil) c.Check(info.Revision, Equals, snap.R(50)) }
func (ms *mgrsSuite) TestHappyRemoteInstallAndUpdateAutoAliases(c *C) { ms.prereqSnapAssertions(c, map[string]interface{}{ "snap-name": "foo", "auto-aliases": []interface{}{"app1"}, }) fooYaml := `name: foo version: @VERSION@ apps: app1: command: bin/app1 aliases: [app1] app2: command: bin/app2 aliases: [app2] ` fooPath, _ := ms.makeStoreTestSnap(c, strings.Replace(fooYaml, "@VERSION@", "1.0", -1), "10") ms.serveSnap(fooPath, "10") mockServer := ms.mockStore(c) defer mockServer.Close() st := ms.o.State() st.Lock() defer st.Unlock() ts, err := snapstate.Install(st, "foo", "stable", snap.R(0), 0, 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())) info, err := snapstate.CurrentInfo(st, "foo") c.Assert(err, IsNil) c.Check(info.Revision, Equals, snap.R(10)) c.Check(info.Version, Equals, "1.0") var allAliases map[string]map[string]string err = st.Get("aliases", &allAliases) c.Check(err, IsNil) c.Check(allAliases, DeepEquals, map[string]map[string]string{ "foo": { "app1": "auto", }, }) app1Alias := filepath.Join(dirs.SnapBinariesDir, "app1") dest, err := os.Readlink(app1Alias) c.Assert(err, IsNil) c.Check(dest, Equals, "foo.app1") ms.prereqSnapAssertions(c, map[string]interface{}{ "snap-name": "foo", "auto-aliases": []interface{}{"app2"}, "revision": "1", }) // new foo version/revision fooPath, _ = ms.makeStoreTestSnap(c, strings.Replace(fooYaml, "@VERSION@", "1.5", -1), "15") ms.serveSnap(fooPath, "15") // refresh all updated, tss, err := snapstate.UpdateMany(st, nil, 0) c.Assert(err, IsNil) c.Assert(updated, DeepEquals, []string{"foo"}) c.Assert(tss, HasLen, 1) chg = st.NewChange("upgrade-snaps", "...") chg.AddAll(tss[0]) st.Unlock() err = ms.o.Settle() st.Lock() c.Assert(err, IsNil) c.Assert(chg.Status(), Equals, state.DoneStatus, Commentf("upgrade-snap change failed with: %v", chg.Err())) info, err = snapstate.CurrentInfo(st, "foo") c.Assert(err, IsNil) c.Check(info.Revision, Equals, snap.R(15)) c.Check(info.Version, Equals, "1.5") allAliases = nil err = st.Get("aliases", &allAliases) c.Check(err, IsNil) c.Check(allAliases, DeepEquals, map[string]map[string]string{ "foo": { "app2": "auto", }, }) c.Check(osutil.IsSymlink(app1Alias), Equals, false) app2Alias := filepath.Join(dirs.SnapBinariesDir, "app2") dest, err = os.Readlink(app2Alias) c.Assert(err, IsNil) c.Check(dest, Equals, "foo.app2") }
func (ms *mgrsSuite) TestHappyRemoteInstallAndUpgradeSvc(c *C) { // test install through store and update, plus some mechanics // of update // TODO: ok to split if it gets too messy to maintain ms.prereqSnapAssertions(c) snapYamlContent := `name: foo version: @VERSION@ apps: bar: command: bin/bar svc: command: svc daemon: forking ` ver := "1.0" revno := "42" snapPath, digest := ms.makeStoreTestSnap(c, strings.Replace(snapYamlContent, "@VERSION@", ver, -1), revno) ms.serveSnap(snapPath, revno) mockServer := ms.mockStore(c) defer mockServer.Close() st := ms.o.State() st.Lock() defer st.Unlock() ts, err := snapstate.Install(st, "foo", "stable", snap.R(0), 0, 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())) info, err := snapstate.CurrentInfo(st, "foo") c.Assert(err, IsNil) c.Check(info.Revision, Equals, snap.R(42)) c.Check(info.SnapID, Equals, fooSnapID) c.Check(info.DeveloperID, Equals, "devdevdev") c.Check(info.Version, Equals, "1.0") c.Check(info.Summary(), Equals, "Foo") c.Check(info.Description(), Equals, "this is a description") c.Check(info.Developer, Equals, "bar") c.Assert(osutil.FileExists(info.MountFile()), Equals, true) snapRev42, err := assertstate.DB(st).Find(asserts.SnapRevisionType, map[string]string{ "snap-sha3-384": digest, }) c.Assert(err, IsNil) c.Check(snapRev42.(*asserts.SnapRevision).SnapID(), Equals, fooSnapID) c.Check(snapRev42.(*asserts.SnapRevision).SnapRevision(), Equals, 42) // check service was setup properly svcFile := filepath.Join(dirs.SnapServicesDir, "snap.foo.svc.service") c.Assert(osutil.FileExists(svcFile), Equals, true) stat, err := os.Stat(svcFile) c.Assert(err, IsNil) // should _not_ be executable c.Assert(stat.Mode().String(), Equals, "-rw-r--r--") // Refresh ver = "2.0" revno = "50" snapPath, digest = ms.makeStoreTestSnap(c, strings.Replace(snapYamlContent, "@VERSION@", ver, -1), revno) ms.serveSnap(snapPath, revno) ts, err = snapstate.Update(st, "foo", "stable", snap.R(0), 0, snapstate.Flags{}) c.Assert(err, IsNil) chg = st.NewChange("upgrade-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("upgrade-snap change failed with: %v", chg.Err())) info, err = snapstate.CurrentInfo(st, "foo") c.Assert(err, IsNil) c.Check(info.Revision, Equals, snap.R(50)) c.Check(info.SnapID, Equals, fooSnapID) c.Check(info.DeveloperID, Equals, "devdevdev") c.Check(info.Version, Equals, "2.0") snapRev50, err := assertstate.DB(st).Find(asserts.SnapRevisionType, map[string]string{ "snap-sha3-384": digest, }) c.Assert(err, IsNil) c.Check(snapRev50.(*asserts.SnapRevision).SnapID(), Equals, fooSnapID) c.Check(snapRev50.(*asserts.SnapRevision).SnapRevision(), Equals, 50) // check updated wrapper symlinkTarget, err := os.Readlink(info.Apps["bar"].WrapperPath()) c.Assert(err, IsNil) c.Assert(symlinkTarget, Equals, "/usr/bin/snap") // check updated service file content, err := ioutil.ReadFile(svcFile) c.Assert(err, IsNil) c.Assert(strings.Contains(string(content), "/var/snap/foo/"+revno), Equals, true) }
func (ms *mgrsSuite) TestHappyRemoteInstallAutoAliases(c *C) { ms.prereqSnapAssertions(c, map[string]interface{}{ "snap-name": "foo", "auto-aliases": []interface{}{"app1", "app2"}, }) snapYamlContent := `name: foo version: @VERSION@ apps: app1: command: bin/app1 aliases: [app1] app2: command: bin/app2 aliases: [app2] ` ver := "1.0" revno := "42" snapPath, _ := ms.makeStoreTestSnap(c, strings.Replace(snapYamlContent, "@VERSION@", ver, -1), revno) ms.serveSnap(snapPath, revno) mockServer := ms.mockStore(c) defer mockServer.Close() st := ms.o.State() st.Lock() defer st.Unlock() ts, err := snapstate.Install(st, "foo", "stable", snap.R(0), 0, 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())) var allAliases map[string]map[string]string err = st.Get("aliases", &allAliases) c.Assert(err, IsNil) c.Check(allAliases, DeepEquals, map[string]map[string]string{ "foo": { "app1": "auto", "app2": "auto", }, }) // check disk app1Alias := filepath.Join(dirs.SnapBinariesDir, "app1") dest, err := os.Readlink(app1Alias) c.Assert(err, IsNil) c.Check(dest, Equals, "foo.app1") app2Alias := filepath.Join(dirs.SnapBinariesDir, "app2") dest, err = os.Readlink(app2Alias) c.Assert(err, IsNil) c.Check(dest, Equals, "foo.app2") }