Permalink
Browse files

Merge pull request #2605 from pedronis/orthog-alias-refresh

overlord,overlord/snapstate: have UpdateMany retire/enable auto-aliases even without new revision
  • Loading branch information...
2 parents 8923092 + fa67181 commit e7a61bddee9b0b16c25b782d7e9d939041952e88 @mvo5 mvo5 committed on GitHub Jan 12, 2017
Showing with 529 additions and 54 deletions.
  1. +157 −0 overlord/managers_test.go
  2. +55 −52 overlord/snapstate/backend_test.go
  3. +168 −0 overlord/snapstate/snapmgr_test.go
  4. +149 −2 overlord/snapstate/snapstate.go
@@ -32,6 +32,7 @@ import (
"net/url"
"os"
"path/filepath"
+ "sort"
"strings"
"time"
@@ -1321,6 +1322,162 @@ apps:
c.Check(dest, Equals, "foo.app2")
}
+func (ms *mgrsSuite) TestHappyOrthogonalRefreshAutoAliases(c *C) {
+ ms.prereqSnapAssertions(c, map[string]interface{}{
+ "snap-name": "foo",
+ "auto-aliases": []interface{}{"app1"},
+ }, map[string]interface{}{
+ "snap-name": "bar",
+ })
+
+ fooYaml := `name: foo
+version: @VERSION@
+apps:
+ app1:
+ command: bin/app1
+ aliases: [app1]
+ app2:
+ command: bin/app2
+ aliases: [app2]
+`
+
+ barYaml := `name: bar
+version: @VERSION@
+apps:
+ app1:
+ command: bin/app1
+ aliases: [app1]
+ app3:
+ command: bin/app3
+ aliases: [app3]
+`
+
+ fooPath, _ := ms.makeStoreTestSnap(c, strings.Replace(fooYaml, "@VERSION@", "1.0", -1), "10")
+ ms.serveSnap(fooPath, "10")
+
+ barPath, _ := ms.makeStoreTestSnap(c, strings.Replace(barYaml, "@VERSION@", "2.0", -1), "20")
+ ms.serveSnap(barPath, "20")
+
+ 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()))
+
+ c.Assert(chg.Status(), Equals, state.DoneStatus, Commentf("install-snap change failed with: %v", chg.Err()))
+
+ ts, err = snapstate.Install(st, "bar", "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")
+
+ info, err = snapstate.CurrentInfo(st, "bar")
+ c.Assert(err, IsNil)
+ c.Check(info.Revision, Equals, snap.R(20))
+ c.Check(info.Version, Equals, "2.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",
+ },
+ })
+
+ ms.prereqSnapAssertions(c, map[string]interface{}{
+ "snap-name": "foo",
+ "auto-aliases": []interface{}{"app2"},
+ "revision": "1",
+ }, map[string]interface{}{
+ "snap-name": "bar",
+ "auto-aliases": []interface{}{"app1", "app3"},
+ "revision": "1",
+ })
+
+ // new foo version/revision
+ fooPath, _ = ms.makeStoreTestSnap(c, strings.Replace(fooYaml, "@VERSION@", "1.5", -1), "15")
+ ms.serveSnap(fooPath, "15")
+
+ // refresh all
+ err = assertstate.RefreshSnapDeclarations(st, 0)
+ c.Assert(err, IsNil)
+
+ updated, tss, err := snapstate.UpdateMany(st, nil, 0)
+ c.Assert(err, IsNil)
+ sort.Strings(updated)
+ c.Assert(updated, DeepEquals, []string{"bar", "foo"})
+ c.Assert(tss, HasLen, 3)
+ chg = st.NewChange("upgrade-snaps", "...")
+ chg.AddAll(tss[0])
+ chg.AddAll(tss[1])
+ chg.AddAll(tss[2])
+
+ 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",
+ },
+ "bar": {
+ "app1": "auto",
+ "app3": "auto",
+ },
+ })
+
+ app2Alias := filepath.Join(dirs.SnapBinariesDir, "app2")
+ dest, err := os.Readlink(app2Alias)
+ c.Assert(err, IsNil)
+ c.Check(dest, Equals, "foo.app2")
+
+ app1Alias := filepath.Join(dirs.SnapBinariesDir, "app1")
+ dest, err = os.Readlink(app1Alias)
+ c.Assert(err, IsNil)
+ c.Check(dest, Equals, "bar.app1")
+ app3Alias := filepath.Join(dirs.SnapBinariesDir, "app3")
+ dest, err = os.Readlink(app3Alias)
+ c.Assert(err, IsNil)
+ c.Check(dest, Equals, "bar.app3")
+}
+
type authContextSetupSuite struct {
o *overlord.Overlord
ac auth.AuthContext
@@ -148,71 +148,74 @@ func (f *fakeStore) ListRefresh(cands []*store.RefreshCandidate, _ *auth.UserSta
if len(cands) == 0 {
return nil, nil
}
- if len(cands) != 1 {
- panic("ListRefresh unexpectedly called with more than one candidate")
+ if len(cands) > 2 {
+ panic("ListRefresh unexpectedly called with more than two candidates")
}
- cand := cands[0]
- snapID := cand.SnapID
+ var res []*snap.Info
+ for _, cand := range cands {
+ snapID := cand.SnapID
- if snapID == "" {
- return nil, nil
- }
+ if snapID == "" || snapID == "other-snap-id" {
+ continue
+ }
- if snapID == "fakestore-please-error-on-refresh" {
- return nil, fmt.Errorf("failing as requested")
- }
+ if snapID == "fakestore-please-error-on-refresh" {
+ return nil, fmt.Errorf("failing as requested")
+ }
- var name string
- if snapID == "some-snap-id" {
- name = "some-snap"
- } else {
- panic(fmt.Sprintf("ListRefresh: unknown snap-id: %s", snapID))
- }
+ var name string
+ if snapID == "some-snap-id" {
+ name = "some-snap"
+ } else {
+ panic(fmt.Sprintf("ListRefresh: unknown snap-id: %s", snapID))
+ }
- revno := snap.R(11)
- confinement := snap.StrictConfinement
- switch cand.Channel {
- case "channel-for-7":
- revno = snap.R(7)
- case "channel-for-classic":
- confinement = snap.ClassicConfinement
- case "channel-for-devmode":
- confinement = snap.DevModeConfinement
- }
+ revno := snap.R(11)
+ confinement := snap.StrictConfinement
+ switch cand.Channel {
+ case "channel-for-7":
+ revno = snap.R(7)
+ case "channel-for-classic":
+ confinement = snap.ClassicConfinement
+ case "channel-for-devmode":
+ confinement = snap.DevModeConfinement
+ }
- info := &snap.Info{
- SideInfo: snap.SideInfo{
- RealName: name,
- Channel: cand.Channel,
- SnapID: cand.SnapID,
- Revision: revno,
- },
- Version: name,
- DownloadInfo: snap.DownloadInfo{
- DownloadURL: "https://some-server.com/some/path.snap",
- },
- Confinement: confinement,
- }
+ info := &snap.Info{
+ SideInfo: snap.SideInfo{
+ RealName: name,
+ Channel: cand.Channel,
+ SnapID: cand.SnapID,
+ Revision: revno,
+ },
+ Version: name,
+ DownloadInfo: snap.DownloadInfo{
+ DownloadURL: "https://some-server.com/some/path.snap",
+ },
+ Confinement: confinement,
+ }
- var hit snap.Revision
- if cand.Revision != revno {
- hit = revno
- }
- for _, blocked := range cand.Block {
- if blocked == revno {
- hit = snap.Revision{}
- break
+ var hit snap.Revision
+ if cand.Revision != revno {
+ hit = revno
+ }
+ for _, blocked := range cand.Block {
+ if blocked == revno {
+ hit = snap.Revision{}
+ break
+ }
}
- }
- f.fakeBackend.ops = append(f.fakeBackend.ops, fakeOp{op: "storesvc-list-refresh", cand: *cand, revno: hit})
+ f.fakeBackend.ops = append(f.fakeBackend.ops, fakeOp{op: "storesvc-list-refresh", cand: *cand, revno: hit})
- if hit.Unset() {
- return nil, nil
+ if !hit.Unset() {
+
+ res = append(res, info)
+ }
}
- return []*snap.Info{info}, nil
+ return res, nil
}
func (f *fakeStore) SuggestedCurrency() string {
Oops, something went wrong.

0 comments on commit e7a61bd

Please sign in to comment.