Merge lp:~sergiusens/snappy/originsOrNamespaceWhatever into lp:~snappy-dev/snappy/15.04-deprecated

Proposed by Sergio Schvezov
Status: Merged
Approved by: Ricardo Salveti
Approved revision: 454
Merged at revision: 457
Proposed branch: lp:~sergiusens/snappy/originsOrNamespaceWhatever
Merge into: lp:~snappy-dev/snappy/15.04-deprecated
Diff against target: 278 lines (+127/-4)
5 files modified
snappy/dirs.go (+4/-0)
snappy/errors.go (+12/-0)
snappy/parts.go (+30/-0)
snappy/snapp.go (+44/-4)
snappy/snapp_test.go (+37/-0)
To merge this branch: bzr merge lp:~sergiusens/snappy/originsOrNamespaceWhatever
Reviewer Review Type Date Requested Status
Ricardo Salveti (community) Approve
Review via email: mp+263960@code.launchpad.net

Commit message

Save store manifest on install and use that information to present the namespace/origin.

Description of the change

This wasn't a straightforward backport.

To post a comment you must log in.
454. By Sergio Schvezov

Read the type from the store

Revision history for this message
Ricardo Salveti (rsalveti) wrote :

Looks good.

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file 'snappy/dirs.go'
--- snappy/dirs.go 2015-04-20 16:51:29 +0000
+++ snappy/dirs.go 2015-07-06 19:42:05 +0000
@@ -30,6 +30,7 @@
30 snapAppArmorDir string30 snapAppArmorDir string
31 snapSeccompDir string31 snapSeccompDir string
32 snapUdevRulesDir string32 snapUdevRulesDir string
33 snapMetaDir string
3334
34 snapBinariesDir string35 snapBinariesDir string
35 snapServicesDir string36 snapServicesDir string
@@ -39,6 +40,8 @@
39 cloudMetaDataFile string40 cloudMetaDataFile string
40)41)
4142
43var snappyDir = filepath.Join("var", "lib", "snappy")
44
42// SetRootDir allows settings a new global root directory, this is useful45// SetRootDir allows settings a new global root directory, this is useful
43// for e.g. chroot operations46// for e.g. chroot operations
44func SetRootDir(rootdir string) {47func SetRootDir(rootdir string) {
@@ -50,6 +53,7 @@
50 snapDataHomeGlob = filepath.Join(rootdir, "/home/*/apps/")53 snapDataHomeGlob = filepath.Join(rootdir, "/home/*/apps/")
51 snapAppArmorDir = filepath.Join(rootdir, "/var/lib/apparmor/clicks")54 snapAppArmorDir = filepath.Join(rootdir, "/var/lib/apparmor/clicks")
52 snapSeccompDir = filepath.Join(rootdir, "/var/lib/snappy/seccomp/profiles")55 snapSeccompDir = filepath.Join(rootdir, "/var/lib/snappy/seccomp/profiles")
56 snapMetaDir = filepath.Join(rootdir, snappyDir, "meta")
5357
54 snapBinariesDir = filepath.Join(snapAppsDir, "bin")58 snapBinariesDir = filepath.Join(snapAppsDir, "bin")
55 snapServicesDir = filepath.Join(rootdir, "/etc/systemd/system")59 snapServicesDir = filepath.Join(rootdir, "/etc/systemd/system")
5660
=== modified file 'snappy/errors.go'
--- snappy/errors.go 2015-06-04 15:00:44 +0000
+++ snappy/errors.go 2015-07-06 19:42:05 +0000
@@ -269,3 +269,15 @@
269func (e ErrApparmorGenerate) Error() string {269func (e ErrApparmorGenerate) Error() string {
270 return fmt.Sprintf("apparmor generate fails with %v: '%v'", e.exitCode, string(e.output))270 return fmt.Sprintf("apparmor generate fails with %v: '%v'", e.exitCode, string(e.output))
271}271}
272
273// ErrInvalidYaml is returned if a yaml file can not be parsed
274type ErrInvalidYaml struct {
275 file string
276 err error
277 yaml []byte
278}
279
280func (e *ErrInvalidYaml) Error() string {
281 // %#v of string(yaml) so the yaml is presented as a human-readable string, but in a single greppable line
282 return fmt.Sprintf("can not parse %s: %v (from: %#v)", e.file, e.err, string(e.yaml))
283}
272284
=== modified file 'snappy/parts.go'
--- snappy/parts.go 2015-04-30 16:56:15 +0000
+++ snappy/parts.go 2015-07-06 19:42:05 +0000
@@ -18,9 +18,11 @@
18package snappy18package snappy
1919
20import (20import (
21 "encoding/json"
21 "fmt"22 "fmt"
22 "net"23 "net"
23 "net/url"24 "net/url"
25 "path/filepath"
24 "strings"26 "strings"
25 "time"27 "time"
2628
@@ -30,6 +32,29 @@
30// SnapType represents the kind of snap (app, core, frameworks, oem)32// SnapType represents the kind of snap (app, core, frameworks, oem)
31type SnapType string33type SnapType string
3234
35// MarshalJSON returns *m as the JSON encoding of m.
36func (m SnapType) MarshalJSON() ([]byte, error) {
37 return json.Marshal(string(m))
38}
39
40// UnmarshalJSON sets *m to a copy of data.
41func (m *SnapType) UnmarshalJSON(data []byte) error {
42 var str string
43 if err := json.Unmarshal(data, &str); err != nil {
44 return err
45 }
46
47 // this is a workaround as the store sends "application" but snappy uses
48 // "app" for TypeApp
49 if str == "application" {
50 *m = SnapTypeApp
51 } else {
52 *m = SnapType(str)
53 }
54
55 return nil
56}
57
33// SystemConfig is a config map holding configs for multiple packages58// SystemConfig is a config map holding configs for multiple packages
34type SystemConfig map[string]interface{}59type SystemConfig map[string]interface{}
3560
@@ -339,3 +364,8 @@
339func PackageNameActive(name string) bool {364func PackageNameActive(name string) bool {
340 return ActiveSnapByName(name) != nil365 return ActiveSnapByName(name) != nil
341}366}
367
368// manifestPath returns the would be path for the store manifest meta data
369func manifestPath(s Part) string {
370 return filepath.Join(snapMetaDir, fmt.Sprintf("%s_%s.manifest", Dirname(s), s.Version()))
371}
342372
=== modified file 'snappy/snapp.go'
--- snappy/snapp.go 2015-07-06 15:35:48 +0000
+++ snappy/snapp.go 2015-07-06 19:42:05 +0000
@@ -163,6 +163,7 @@
163// SnapPart represents a generic snap type163// SnapPart represents a generic snap type
164type SnapPart struct {164type SnapPart struct {
165 m *packageYaml165 m *packageYaml
166 remoteM *remoteSnap
166 namespace string167 namespace string
167 hash string168 hash string
168 isActive bool169 isActive bool
@@ -214,13 +215,13 @@
214 IconURL string `json:"icon_url"`215 IconURL string `json:"icon_url"`
215 LastUpdated string `json:"last_updated,omitempty"`216 LastUpdated string `json:"last_updated,omitempty"`
216 Name string `json:"package_name"`217 Name string `json:"package_name"`
217 Namespace string `json:"origin"`218 Namespace string `json:"origin" yaml:"origin"`
218 Prices map[string]float64 `json:"prices,omitempty"`219 Prices map[string]float64 `json:"prices,omitempty"`
219 Publisher string `json:"publisher,omitempty"`220 Publisher string `json:"publisher,omitempty"`
220 RatingsAverage float64 `json:"ratings_average,omitempty"`221 RatingsAverage float64 `json:"ratings_average,omitempty"`
221 SupportURL string `json:"support_url"`222 SupportURL string `json:"support_url"`
222 Title string `json:"title"`223 Title string `json:"title"`
223 Type string `json:"content,omitempty"`224 Type SnapType `json:"content"`
224 Version string `json:"version"`225 Version string `json:"version"`
225}226}
226227
@@ -478,6 +479,20 @@
478 }479 }
479 part.hash = h.ArchiveSha512480 part.hash = h.ArchiveSha512
480481
482 remoteManifestPath := manifestPath(part)
483 if helpers.FileExists(remoteManifestPath) {
484 content, err := ioutil.ReadFile(remoteManifestPath)
485 if err != nil {
486 return nil, err
487 }
488
489 var r remoteSnap
490 if err := yaml.Unmarshal(content, &r); err != nil {
491 return nil, &ErrInvalidYaml{file: remoteManifestPath, err: err, yaml: content}
492 }
493 part.remoteM = &r
494 }
495
481 return part, nil496 return part, nil
482}497}
483498
@@ -509,6 +524,10 @@
509524
510// Namespace returns the namespace525// Namespace returns the namespace
511func (s *SnapPart) Namespace() string {526func (s *SnapPart) Namespace() string {
527 if r := s.remoteM; r != nil {
528 return r.Namespace
529 }
530
512 return s.namespace531 return s.namespace
513}532}
514533
@@ -552,6 +571,10 @@
552571
553// DownloadSize returns the dowload size572// DownloadSize returns the dowload size
554func (s *SnapPart) DownloadSize() int64 {573func (s *SnapPart) DownloadSize() int64 {
574 if r := s.remoteM; r != nil {
575 return r.DownloadSize
576 }
577
555 return -1578 return -1
556}579}
557580
@@ -852,8 +875,7 @@
852875
853// Type returns the type of the SnapPart (app, oem, ...)876// Type returns the type of the SnapPart (app, oem, ...)
854func (s *RemoteSnapPart) Type() SnapType {877func (s *RemoteSnapPart) Type() SnapType {
855 // FIXME: the store does not publish this info878 return s.pkg.Type
856 return SnapTypeApp
857}879}
858880
859// Name returns the name881// Name returns the name
@@ -981,6 +1003,20 @@
981 return w.Name(), w.Sync()1003 return w.Name(), w.Sync()
982}1004}
9831005
1006func (s *RemoteSnapPart) saveStoreManifest() error {
1007 content, err := yaml.Marshal(s.pkg)
1008 if err != nil {
1009 return err
1010 }
1011
1012 if err := os.MkdirAll(snapMetaDir, 0755); err != nil {
1013 return err
1014 }
1015
1016 // don't worry about previous contents
1017 return ioutil.WriteFile(manifestPath(s), content, 0644)
1018}
1019
984// Install installs the snap1020// Install installs the snap
985func (s *RemoteSnapPart) Install(pbar progress.Meter, flags InstallFlags) (string, error) {1021func (s *RemoteSnapPart) Install(pbar progress.Meter, flags InstallFlags) (string, error) {
986 downloadedSnap, err := s.Download(pbar)1022 downloadedSnap, err := s.Download(pbar)
@@ -989,6 +1025,10 @@
989 }1025 }
990 defer os.Remove(downloadedSnap)1026 defer os.Remove(downloadedSnap)
9911027
1028 if err := s.saveStoreManifest(); err != nil {
1029 return "", err
1030 }
1031
992 return installClick(downloadedSnap, flags, pbar, s.Namespace())1032 return installClick(downloadedSnap, flags, pbar, s.Namespace())
993}1033}
9941034
9951035
=== modified file 'snappy/snapp_test.go'
--- snappy/snapp_test.go 2015-06-04 15:00:44 +0000
+++ snappy/snapp_test.go 2015-07-06 19:42:05 +0000
@@ -656,6 +656,10 @@
656656
657 snap := RemoteSnapPart{}657 snap := RemoteSnapPart{}
658 snap.pkg.AnonDownloadURL = mockServer.URL + "/snap"658 snap.pkg.AnonDownloadURL = mockServer.URL + "/snap"
659 snap.pkg.IconURL = mockServer.URL + "/icon"
660 snap.pkg.Name = "foo"
661 snap.pkg.Namespace = "bar"
662 snap.pkg.Version = "1.0"
659663
660 p := &MockProgressMeter{}664 p := &MockProgressMeter{}
661 name, err := snap.Install(p, 0)665 name, err := snap.Install(p, 0)
@@ -664,6 +668,15 @@
664 st, err := os.Stat(snapPackage)668 st, err := os.Stat(snapPackage)
665 c.Assert(err, IsNil)669 c.Assert(err, IsNil)
666 c.Assert(p.written, Equals, int(st.Size()))670 c.Assert(p.written, Equals, int(st.Size()))
671
672 installed, err := ListInstalled()
673 c.Assert(err, IsNil)
674 c.Assert(installed, HasLen, 1)
675
676 c.Check(installed[0].Namespace(), Equals, "bar")
677
678 _, err = os.Stat(filepath.Join(snapMetaDir, "foo.bar_1.0.manifest"))
679 c.Check(err, IsNil)
667}680}
668681
669func (s *SnapTestSuite) TestRemoteSnapUpgradeService(c *C) {682func (s *SnapTestSuite) TestRemoteSnapUpgradeService(c *C) {
@@ -1026,6 +1039,30 @@
1026 c.Check(yaml.checkForPackageInstalled("otherns"), IsNil)1039 c.Check(yaml.checkForPackageInstalled("otherns"), IsNil)
1027}1040}
10281041
1042func (s *SnapTestSuite) TestUsesStoreMetaData(c *C) {
1043 data := "name: afoo\nversion: 1\nvendor: foo\ntype: framework"
1044 yamlPath, err := makeInstalledMockSnap(s.tempdir, data)
1045 c.Assert(err, IsNil)
1046 c.Assert(makeSnapActive(yamlPath), IsNil)
1047
1048 err = os.MkdirAll(snapMetaDir, 0755)
1049 c.Assert(err, IsNil)
1050
1051 data = "name: afoo\nalias: afoo\ndescription: something nice\ndownloadsize: 10\norigin: someplace"
1052 err = ioutil.WriteFile(filepath.Join(snapMetaDir, "afoo_1.manifest"), []byte(data), 0644)
1053 c.Assert(err, IsNil)
1054
1055 snaps, err := ListInstalled()
1056 c.Assert(err, IsNil)
1057 c.Assert(snaps, HasLen, 1)
1058
1059 c.Check(snaps[0].Name(), Equals, "afoo")
1060 c.Check(snaps[0].Version(), Equals, "1")
1061 c.Check(snaps[0].Type(), Equals, SnapTypeFramework)
1062 c.Check(snaps[0].Namespace(), Equals, "someplace")
1063 c.Check(snaps[0].DownloadSize(), Equals, int64(10))
1064}
1065
1029func (s *SnapTestSuite) TestDetectsNameClash(c *C) {1066func (s *SnapTestSuite) TestDetectsNameClash(c *C) {
1030 data := []byte(`name: afoo1067 data := []byte(`name: afoo
1031version: 1.01068version: 1.0

Subscribers

People subscribed via source and target branches