Merge lp:~mvo/snappy/snappy-verify into lp:~snappy-dev/snappy/snappy-moved-to-github

Proposed by Michael Vogt on 2015-06-11
Status: Work in progress
Proposed branch: lp:~mvo/snappy/snappy-verify
Merge into: lp:~snappy-dev/snappy/snappy-moved-to-github
Diff against target: 468 lines (+310/-45)
9 files modified
cmd/snappy/cmd_verify.go (+43/-0)
helpers/helpers.go (+4/-0)
snappy/build.go (+3/-37)
snappy/build_test.go (+1/-3)
snappy/hashes.go (+85/-0)
snappy/hashes_test.go (+65/-0)
snappy/snapp.go (+26/-5)
snappy/verify.go (+48/-0)
snappy/verify_test.go (+35/-0)
To merge this branch: bzr merge lp:~mvo/snappy/snappy-verify
Reviewer Review Type Date Requested Status
Leo Arias 2015-06-11 Needs Fixing on 2015-08-24
Federico Gimenez (community) continuous-integration Needs Fixing on 2015-08-19
Snappy Tarmac continuous-integration Pending
Review via email: mp+261718@code.launchpad.net

Description of the Change

Implement "snappy verify" that will ensure that all files are correct on
disk.

To post a comment you must log in.
John Lenton (chipaca) :
Leo Arias (elopio) :
lp:~mvo/snappy/snappy-verify updated on 2015-06-17
509. By Michael Vogt on 2015-06-17

merged lp:snappy

510. By Michael Vogt on 2015-06-17

snappy/parts.go: take the easy route and cast to SnapPart in VerifyInstalled

511. By Michael Vogt on 2015-06-17

snappy/snapp.go: remove RemoteSnapPart.Verify, SystemImagePart.Verify

512. By Michael Vogt on 2015-06-17

cmd/snappy/cmd_verify.go: improve help message (thanks Leo!)

513. By Michael Vogt on 2015-06-17

helpers/helpers.go: fix typo in comment (thanks Leo)

Michael Vogt (mvo) wrote :

Thanks John and Leo for the review! I addressed the comments now. I will do a followup branch (or some) to address the interface problem, its too big but its hard to change unfortunately.

Leo Arias (elopio) wrote :

When I run snappy verify I get this:

Error: panic: interface conversion: snappy.Part is *snappy.SystemImagePart, not *snappy.SnapPart

goroutine 16 [running]:
runtime.panic(0x809060, 0xc2080c4900)
 /usr/lib/go/src/pkg/runtime/panic.c:279 +0xf5
launchpad.net/snappy/snappy.VerifyInstalled(0x7f164e41d8d0, 0xcd9c60, 0x0, 0x0)
 /home/elopio/workspace/canonical/snappy/experimental/build-area/ubuntu-snappy-1.2/obj-x86_64-linux-gnu/src/launchpad.net/snappy/snappy/verify.go:38 +0x249
main.(*cmdVerify).Execute(0xcd9c60, 0xc208000e80, 0x0, 0x1, 0x0, 0x0)
 /home/elopio/workspace/canonical/snappy/experimental/build-area/ubuntu-snappy-1.2/obj-x86_64-linux-gnu/src/launchpad.net/snappy/cmd/snappy/cmd_verify.go:42 +0x51
github.com/jessevdk/go-flags.(*Parser).ParseArgs(0xc20804edc0, 0xc20800e010, 0x1, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0)
 /home/elopio/workspace/canonical/snappy/experimental/build-area/ubuntu-snappy-1.2/obj-x86_64-linux-gnu/src/github.com/jessevdk/go-flags/parser.go:241 +0x7cd
github.com/jessevdk/go-flags.(*Parser).Parse(0xc20804edc0, 0x0, 0x0, 0x0, 0x0, 0x0)
 /home/elopio/workspace/canonical/snappy/experimental/build-area/ubuntu-snappy-1.2/obj-x86_64-linux-gnu/src/github.com/jessevdk/go-flags/parser.go:126 +0xb3
main.main()
 /home/elopio/workspace/canonical/snappy/experimental/build-area/ubuntu-snappy-1.2/obj-x86_64-linux-gnu/src/launchpad.net/snappy/cmd/snappy/main.go:54 +0x32

goroutine 19 [finalizer wait]:
runtime.park(0x422370, 0xcd8f38, 0xcc50e9)
 /usr/lib/go/src/pkg/runtime/proc.c:1369 +0x89
runtime.parkunlock(0xcd8f38, 0xcc50e9)
 /usr/lib/go/src/pkg/runtime/proc.c:1385 +0x3b
runfinq()
 /usr/lib/go/src/pkg/runtime/mgc0.c:2644 +0xcf
runtime.goexit()
 /usr/lib/go/src/pkg/runtime/proc.c:1445

goroutine 20 [syscall]:
os/signal.loop()
 /usr/lib/go/src/pkg/os/signal/signal_unix.go:21 +0x1e
created by os/signal.init·1
 /usr/lib/go/src/pkg/os/signal/signal_unix.go:27 +0x32

goroutine 21 [chan receive]:
launchpad.net/snappy/partition.func·005()
 /home/elopio/workspace/canonical/snappy/experimental/build-area/ubuntu-snappy-1.2/obj-x86_64-linux-gnu/src/launchpad.net/snappy/partition/partition.go:270 +0x4e
created by launchpad.net/snappy/partition.setupSignalHandler
 /home/elopio/workspace/canonical/snappy/experimental/build-area/ubuntu-snappy-1.2/obj-x86_64-linux-gnu/src/launchpad.net/snappy/partition/partition.go:275 +0x174

goroutine 17 [syscall]:
runtime.goexit()
 /usr/lib/go/src/pkg/runtime/proc.c:1445

I don't fully understand the interface conversion error and I could be doing something wrong when setting this up, but in case of doubt, I'll leave a needs fixing.

review: Needs Fixing (exploratory tests)
Sergio Schvezov (sergiusens) wrote :

On Wed, Jun 24, 2015 at 11:54:14PM -0000, Leo Arias wrote:
> Review: Needs Fixing exploratory tests
>
> When I run snappy verify I get this:
>
> Error: panic: interface conversion: snappy.Part is *snappy.SystemImagePart, not *snappy.SnapPart

before converting you need to do something like:

if part, ok := s.(*snappy.SnapPart); ok {{
    // operate on part
}

>
> goroutine 16 [running]:
> runtime.panic(0x809060, 0xc2080c4900)
> /usr/lib/go/src/pkg/runtime/panic.c:279 +0xf5
> launchpad.net/snappy/snappy.VerifyInstalled(0x7f164e41d8d0, 0xcd9c60, 0x0, 0x0)
> /home/elopio/workspace/canonical/snappy/experimental/build-area/ubuntu-snappy-1.2/obj-x86_64-linux-gnu/src/launchpad.net/snappy/snappy/verify.go:38 +0x249
> main.(*cmdVerify).Execute(0xcd9c60, 0xc208000e80, 0x0, 0x1, 0x0, 0x0)
> /home/elopio/workspace/canonical/snappy/experimental/build-area/ubuntu-snappy-1.2/obj-x86_64-linux-gnu/src/launchpad.net/snappy/cmd/snappy/cmd_verify.go:42 +0x51
> github.com/jessevdk/go-flags.(*Parser).ParseArgs(0xc20804edc0, 0xc20800e010, 0x1, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0)
> /home/elopio/workspace/canonical/snappy/experimental/build-area/ubuntu-snappy-1.2/obj-x86_64-linux-gnu/src/github.com/jessevdk/go-flags/parser.go:241 +0x7cd
> github.com/jessevdk/go-flags.(*Parser).Parse(0xc20804edc0, 0x0, 0x0, 0x0, 0x0, 0x0)
> /home/elopio/workspace/canonical/snappy/experimental/build-area/ubuntu-snappy-1.2/obj-x86_64-linux-gnu/src/github.com/jessevdk/go-flags/parser.go:126 +0xb3
> main.main()
> /home/elopio/workspace/canonical/snappy/experimental/build-area/ubuntu-snappy-1.2/obj-x86_64-linux-gnu/src/launchpad.net/snappy/cmd/snappy/main.go:54 +0x32
>
> goroutine 19 [finalizer wait]:
> runtime.park(0x422370, 0xcd8f38, 0xcc50e9)
> /usr/lib/go/src/pkg/runtime/proc.c:1369 +0x89
> runtime.parkunlock(0xcd8f38, 0xcc50e9)
> /usr/lib/go/src/pkg/runtime/proc.c:1385 +0x3b
> runfinq()
> /usr/lib/go/src/pkg/runtime/mgc0.c:2644 +0xcf
> runtime.goexit()
> /usr/lib/go/src/pkg/runtime/proc.c:1445
>
> goroutine 20 [syscall]:
> os/signal.loop()
> /usr/lib/go/src/pkg/os/signal/signal_unix.go:21 +0x1e
> created by os/signal.init·1
> /usr/lib/go/src/pkg/os/signal/signal_unix.go:27 +0x32
>
> goroutine 21 [chan receive]:
> launchpad.net/snappy/partition.func·005()
> /home/elopio/workspace/canonical/snappy/experimental/build-area/ubuntu-snappy-1.2/obj-x86_64-linux-gnu/src/launchpad.net/snappy/partition/partition.go:270 +0x4e
> created by launchpad.net/snappy/partition.setupSignalHandler
> /home/elopio/workspace/canonical/snappy/experimental/build-area/ubuntu-snappy-1.2/obj-x86_64-linux-gnu/src/launchpad.net/snappy/partition/partition.go:275 +0x174
>
> goroutine 17 [syscall]:
> runtime.goexit()
> /usr/lib/go/src/pkg/runtime/proc.c:1445
>
> I don't fully understand the interface conversion error and I could be doing something wrong when setting this up, but in case of doubt, I'll leave a needs fixing.
> --
> https://code.launchpad.net/~mvo/snappy/snappy-verify/+merge/261718
> Your team Snappy Developers is subscribed to branch lp:snappy.

lp:~mvo/snappy/snappy-verify updated on 2015-06-25
514. By Michael Vogt on 2015-06-25

fix crash when trying to verify a SystemImageSnap

Michael Vogt (mvo) wrote :

Thanks Leo and Sergio! Sorry for this issue, I fixed it now and added a proper test.

Leo Arias (elopio) wrote :

I was trying to add a test for the command, and it fails with:
Error: verify for hello-world failed: file mode mismatch for bin: 020000000775 != 020000000755

The MP with the test is here: https://code.launchpad.net/~elopio/snappy/test-verify/+merge/263318

review: Needs Fixing
Federico Gimenez (fgimenez) wrote :

FAILED: Continuous integration, rev:514
No commit message was specified in the merge proposal. Click on the following link and set the commit message (if you want a jenkins rebuild you need to trigger it yourself):
https://code.launchpad.net/~mvo/snappy/snappy-verify/+merge/261718/+edit-commit-message

http://10.55.60.183:8080/job/snappy-rolling-ci/27/
Executed test runs:

Click here to trigger a rebuild:
http://10.55.60.183:8080/job/snappy-rolling-ci/27/rebuild

review: Needs Fixing (continuous-integration)
Leo Arias (elopio) wrote :

this has a conflict with trunk.

review: Needs Fixing

Unmerged revisions

514. By Michael Vogt on 2015-06-25

fix crash when trying to verify a SystemImageSnap

513. By Michael Vogt on 2015-06-17

helpers/helpers.go: fix typo in comment (thanks Leo)

512. By Michael Vogt on 2015-06-17

cmd/snappy/cmd_verify.go: improve help message (thanks Leo!)

511. By Michael Vogt on 2015-06-17

snappy/snapp.go: remove RemoteSnapPart.Verify, SystemImagePart.Verify

510. By Michael Vogt on 2015-06-17

snappy/parts.go: take the easy route and cast to SnapPart in VerifyInstalled

509. By Michael Vogt on 2015-06-17

merged lp:snappy

508. By Michael Vogt on 2015-06-11

improve verify output

507. By Michael Vogt on 2015-06-11

ensure unpack is faithful to the permissiosn in the tar

506. By Michael Vogt on 2015-06-11

improve error message

505. By Michael Vogt on 2015-06-11

implement snappy verify

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== added file 'cmd/snappy/cmd_verify.go'
2--- cmd/snappy/cmd_verify.go 1970-01-01 00:00:00 +0000
3+++ cmd/snappy/cmd_verify.go 2015-06-25 08:56:02 +0000
4@@ -0,0 +1,43 @@
5+// -*- Mode: Go; indent-tabs-mode: t -*-
6+
7+/*
8+ * Copyright (C) 2014-2015 Canonical Ltd
9+ *
10+ * This program is free software: you can redistribute it and/or modify
11+ * it under the terms of the GNU General Public License version 3 as
12+ * published by the Free Software Foundation.
13+ *
14+ * This program is distributed in the hope that it will be useful,
15+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
16+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17+ * GNU General Public License for more details.
18+ *
19+ * You should have received a copy of the GNU General Public License
20+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
21+ *
22+ */
23+
24+package main
25+
26+import (
27+ "launchpad.net/snappy/logger"
28+ "launchpad.net/snappy/progress"
29+ "launchpad.net/snappy/snappy"
30+)
31+
32+type cmdVerify struct {
33+}
34+
35+func init() {
36+ _, err := parser.AddCommand("verify",
37+ "Verify the integrity of all installed snap packages",
38+ "Verify the integrity of all installed snap packages by comparing the permissions, sizes and file hashes of each file",
39+ &cmdVerify{})
40+ if err != nil {
41+ logger.Panicf("Unable to verify: %v", err)
42+ }
43+}
44+
45+func (x *cmdVerify) Execute(args []string) (err error) {
46+ return snappy.VerifyInstalled(progress.MakeProgressBar())
47+}
48
49=== modified file 'helpers/helpers.go'
50--- helpers/helpers.go 2015-06-09 19:11:54 +0000
51+++ helpers/helpers.go 2015-06-25 08:56:02 +0000
52@@ -115,6 +115,10 @@
53
54 // UnpackTar unpacks the given tar file into the target directory
55 func UnpackTar(r io.Reader, targetDir string, fn UnpackTarTransformFunc) error {
56+ // ensure we extract with the original permissions
57+ oldUmask := syscall.Umask(0)
58+ defer syscall.Umask(oldUmask)
59+
60 return TarIterate(r, func(tr *tar.Reader, hdr *tar.Header) (err error) {
61 // run tar transform func
62 name := hdr.Name
63
64=== modified file 'snappy/build.go'
65--- snappy/build.go 2015-06-11 19:30:45 +0000
66+++ snappy/build.go 2015-06-25 08:56:02 +0000
67@@ -186,42 +186,6 @@
68 return strings.Fields(string(output))[0], nil
69 }
70
71-func hashForFile(buildDir, path string, info os.FileInfo) (h *fileHash, err error) {
72- sha512sum := ""
73- // pointer so that omitempty works (we don't want size for
74- // directories or symlinks)
75- var size *int64
76- if info.Mode().IsRegular() {
77- sha512sum, err = helpers.Sha512sum(path)
78- if err != nil {
79- return nil, err
80- }
81- fsize := info.Size()
82- size = &fsize
83- }
84-
85- // major/minor handling
86- device := ""
87- major, minor, err := helpers.MajorMinor(info)
88- if err == nil {
89- device = fmt.Sprintf("%v,%v", major, minor)
90- }
91-
92- if buildDir != "" {
93- path = path[len(buildDir)+1:]
94- }
95-
96- return &fileHash{
97- Name: path,
98- Size: size,
99- Sha512: sha512sum,
100- Device: device,
101- // FIXME: not portable, this output is different on
102- // windows, macos
103- Mode: newYamlFileMode(info.Mode()),
104- }, nil
105-}
106-
107 func writeHashes(buildDir, dataTar string) error {
108
109 debianDir := filepath.Join(buildDir, "DEBIAN")
110@@ -244,10 +208,12 @@
111 return nil
112 }
113
114- hash, err := hashForFile(buildDir, path, info)
115+ hash, err := hashForFile(path)
116 if err != nil {
117 return err
118 }
119+ // adjust the name by removing the builddir
120+ hash.Name = hash.Name[len(buildDir)+1:]
121 hashes.Files = append(hashes.Files, hash)
122
123 return nil
124
125=== modified file 'snappy/build_test.go'
126--- snappy/build_test.go 2015-06-08 16:26:25 +0000
127+++ snappy/build_test.go 2015-06-25 08:56:02 +0000
128@@ -432,9 +432,7 @@
129 c.Skip("no /dev/kmsg")
130 }
131
132- stat, err := os.Stat("/dev/kmsg")
133- c.Assert(err, IsNil)
134- h, err := hashForFile("", "/dev/kmsg", stat)
135+ h, err := hashForFile("/dev/kmsg")
136 c.Assert(err, IsNil)
137 c.Assert(h.Name, Equals, "/dev/kmsg")
138 c.Assert(h.Device, Equals, "1,11")
139
140=== modified file 'snappy/hashes.go'
141--- snappy/hashes.go 2015-05-15 13:33:27 +0000
142+++ snappy/hashes.go 2015-06-25 08:56:02 +0000
143@@ -22,6 +22,8 @@
144 import (
145 "fmt"
146 "os"
147+
148+ "launchpad.net/snappy/helpers"
149 )
150
151 type yamlFileMode struct {
152@@ -111,6 +113,40 @@
153 XAttr map[string]string `yaml:"xattr,omitempty"`
154 }
155
156+func (fh *fileHash) Verify() error {
157+ fh2, err := hashForFile(fh.Name)
158+ if err != nil {
159+ return err
160+ }
161+
162+ // check permissions
163+ if fh2.Mode.mode != fh.Mode.mode {
164+ return fmt.Errorf("file mode mismatch for %v: 0%o != 0%o", fh.Name, fh.Mode.mode, fh2.Mode.mode)
165+ }
166+
167+ // check size (only files have them)
168+ if (fh2.Size == nil && fh.Size != nil) || (fh2.Size != nil && fh.Size == nil) {
169+ return fmt.Errorf("size data mismatch for %v", fh.Name)
170+ }
171+ if fh2.Size != nil && fh.Size != nil {
172+ if *fh2.Size != *fh.Size {
173+ return fmt.Errorf("size mismatch for %v: %v != %v", fh.Name, *fh.Size, *fh2.Size)
174+ }
175+ }
176+
177+ // check hash
178+ if fh2.Sha512 != fh.Sha512 {
179+ return fmt.Errorf("hash mismatch for %v: %v != %v", fh.Name, fh.Sha512, fh2.Sha512)
180+ }
181+
182+ // check device
183+ if fh2.Device != fh.Device {
184+ return fmt.Errorf("device info mismatch for %v: %v != %v", fh.Name, fh.Device, fh2.Device)
185+ }
186+
187+ return nil
188+}
189+
190 // the meta/hashes file
191 type hashesYaml struct {
192 // the archive hash
193@@ -119,3 +155,52 @@
194 // the hashes for the files in the archive
195 Files []*fileHash
196 }
197+
198+func (h *hashesYaml) Verify() error {
199+ for _, fh := range h.Files {
200+ if err := fh.Verify(); err != nil {
201+ return err
202+ }
203+ }
204+
205+ return nil
206+}
207+
208+// get the path for the given file
209+func hashForFile(path string) (h *fileHash, err error) {
210+ sha512sum := ""
211+
212+ info, err := os.Lstat(path)
213+ if err != nil {
214+ return nil, err
215+ }
216+
217+ // pointer so that omitempty works (we don't want size for
218+ // directories or symlinks)
219+ var size *int64
220+ if info.Mode().IsRegular() {
221+ sha512sum, err = helpers.Sha512sum(path)
222+ if err != nil {
223+ return nil, err
224+ }
225+ fsize := info.Size()
226+ size = &fsize
227+ }
228+
229+ // major/minor handling
230+ device := ""
231+ major, minor, err := helpers.MajorMinor(info)
232+ if err == nil {
233+ device = fmt.Sprintf("%v,%v", major, minor)
234+ }
235+
236+ return &fileHash{
237+ Name: path,
238+ Size: size,
239+ Sha512: sha512sum,
240+ Device: device,
241+ // FIXME: not portable, this output is different on
242+ // windows, macos
243+ Mode: newYamlFileMode(info.Mode()),
244+ }, nil
245+}
246
247=== modified file 'snappy/hashes_test.go'
248--- snappy/hashes_test.go 2015-06-02 20:46:07 +0000
249+++ snappy/hashes_test.go 2015-06-25 08:56:02 +0000
250@@ -152,3 +152,68 @@
251 mode: frw-r--r--
252 `)
253 }
254+
255+func makeTestFileWithHash(c *C) (*fileHash, string) {
256+ p := filepath.Join(c.MkDir(), "foo")
257+ err := ioutil.WriteFile(p, []byte("bar\n"), 0644)
258+ c.Assert(err, IsNil)
259+ st, err := os.Stat(p)
260+ c.Assert(err, IsNil)
261+
262+ size := int64(4)
263+ mode := newYamlFileMode(st.Mode())
264+ fh := fileHash{
265+ Name: p,
266+ Size: &size,
267+ Sha512: "cc06808cbbee0510331aa97974132e8dc296aeb795be229d064bae784b0a87a5cf4281d82e8c99271b75db2148f08a026c1a60ed9cabdb8cac6d24242dac4063",
268+ Mode: mode,
269+ }
270+ return &fh, p
271+}
272+
273+func (s *SnapTestSuite) TestFileHashSimple(c *C) {
274+ fh, _ := makeTestFileWithHash(c)
275+ err := fh.Verify()
276+ c.Assert(err, IsNil)
277+}
278+
279+func (s *SnapTestSuite) TestFileHashWrongSize(c *C) {
280+ fh, _ := makeTestFileWithHash(c)
281+
282+ fakeSize := int64(1)
283+ fh.Size = &fakeSize
284+
285+ err := fh.Verify()
286+ c.Assert(err, ErrorMatches, "size mismatch for .*/foo: 1 != 4")
287+}
288+
289+func (s *SnapTestSuite) TestFileHashWrongMode(c *C) {
290+ fh, _ := makeTestFileWithHash(c)
291+ fh.Mode.mode = 0444
292+
293+ err := fh.Verify()
294+ c.Assert(err, ErrorMatches, "file mode mismatch for .*/foo: 0444 != 0644")
295+}
296+
297+func (s *SnapTestSuite) TestFileHashWrongHash(c *C) {
298+ fh, _ := makeTestFileWithHash(c)
299+ fh.Sha512 = "xx"
300+
301+ err := fh.Verify()
302+ c.Assert(err, ErrorMatches, "hash mismatch for .*/foo: xx != cc06808cbbee0510331aa97974132e8dc296aeb795be229d064bae784b0a87a5cf4281d82e8c99271b75db2148f08a026c1a60ed9cabdb8cac6d24242dac4063")
303+}
304+
305+func (s *SnapTestSuite) TestFileHashForDir(c *C) {
306+ name := c.MkDir()
307+ st, err := os.Stat(name)
308+ c.Assert(err, IsNil)
309+
310+ mode := newYamlFileMode(st.Mode())
311+ fh := fileHash{
312+ Name: name,
313+ Mode: mode,
314+ }
315+
316+ err = fh.Verify()
317+ c.Assert(err, IsNil)
318+}
319
320=== modified file 'snappy/snapp.go'
321--- snappy/snapp.go 2015-06-12 03:55:01 +0000
322+++ snappy/snapp.go 2015-06-25 08:56:02 +0000
323@@ -608,9 +608,18 @@
324 part.description = description
325 }
326
327- // read hash, its ok if its not there, some older versions of
328- // snappy did not write this file
329- hashesData, err := ioutil.ReadFile(filepath.Join(part.basedir, "meta", "hashes.yaml"))
330+ // read hash
331+ h, err := part.hashesData()
332+ if err != nil {
333+ return nil, err
334+ }
335+ part.hash = h.ArchiveSha512
336+
337+ return part, nil
338+}
339+
340+func (s *SnapPart) hashesData() (*hashesYaml, error) {
341+ hashesData, err := ioutil.ReadFile(filepath.Join(s.basedir, "meta", "hashes.yaml"))
342 if err != nil {
343 return nil, err
344 }
345@@ -620,9 +629,8 @@
346 if err != nil {
347 return nil, &ErrInvalidYaml{file: "hashes.yaml", err: err, yaml: hashesData}
348 }
349- part.hash = h.ArchiveSha512
350
351- return part, nil
352+ return &h, nil
353 }
354
355 // Type returns the type of the SnapPart (app, oem, ...)
356@@ -1083,6 +1091,19 @@
357 return s.m.Frameworks, nil
358 }
359
360+// Verify checks the integrity
361+func (s *SnapPart) Verify(pb progress.Meter) error {
362+ hashesData, err := s.hashesData()
363+ if err != nil {
364+ return err
365+ }
366+
367+ helpers.ChDir(s.basedir, func() {
368+ err = hashesData.Verify()
369+ })
370+ return err
371+}
372+
373 // DependentNames returns a list of the names of apps installed that
374 // depend on this one
375 //
376
377=== added file 'snappy/verify.go'
378--- snappy/verify.go 1970-01-01 00:00:00 +0000
379+++ snappy/verify.go 2015-06-25 08:56:02 +0000
380@@ -0,0 +1,48 @@
381+// -*- Mode: Go; indent-tabs-mode: t -*-
382+
383+/*
384+ * Copyright (C) 2014-2015 Canonical Ltd
385+ *
386+ * This program is free software: you can redistribute it and/or modify
387+ * it under the terms of the GNU General Public License version 3 as
388+ * published by the Free Software Foundation.
389+ *
390+ * This program is distributed in the hope that it will be useful,
391+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
392+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
393+ * GNU General Public License for more details.
394+ *
395+ * You should have received a copy of the GNU General Public License
396+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
397+ *
398+ */
399+
400+package snappy
401+
402+import (
403+ "fmt"
404+
405+ "launchpad.net/snappy/progress"
406+)
407+
408+// VerifyInstalled verifies all installed snaps
409+func VerifyInstalled(pb progress.Meter) error {
410+ m := NewMetaLocalRepository()
411+ installed, err := m.Installed()
412+ if err != nil {
413+ return err
414+ }
415+
416+ for _, part := range installed {
417+ if _, ok := part.(*SnapPart); !ok {
418+ continue
419+ }
420+ pb.Notify(fmt.Sprintf("Verifying %s", part.Name()))
421+ if err := part.(*SnapPart).Verify(pb); err != nil {
422+ return fmt.Errorf("verify for %v failed: %v", part.Name(), err)
423+ }
424+ }
425+ pb.Notify(fmt.Sprintf("Verified %d successfully", len(installed)))
426+
427+ return nil
428+}
429
430=== added file 'snappy/verify_test.go'
431--- snappy/verify_test.go 1970-01-01 00:00:00 +0000
432+++ snappy/verify_test.go 2015-06-25 08:56:02 +0000
433@@ -0,0 +1,35 @@
434+// -*- Mode: Go; indent-tabs-mode: t -*-
435+
436+/*
437+ * Copyright (C) 2014-2015 Canonical Ltd
438+ *
439+ * This program is free software: you can redistribute it and/or modify
440+ * it under the terms of the GNU General Public License version 3 as
441+ * published by the Free Software Foundation.
442+ *
443+ * This program is distributed in the hope that it will be useful,
444+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
445+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
446+ * GNU General Public License for more details.
447+ *
448+ * You should have received a copy of the GNU General Public License
449+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
450+ *
451+ */
452+
453+package snappy
454+
455+import (
456+ "path/filepath"
457+
458+ . "gopkg.in/check.v1"
459+)
460+
461+func (s *SnapTestSuite) TestSnapVerifyWorksWithSystemImage(c *C) {
462+ systemImageRoot = c.MkDir()
463+
464+ makeFakeSystemImageChannelConfig(c, filepath.Join(systemImageRoot, systemImageChannelConfig), "1")
465+
466+ err := VerifyInstalled(&MockProgressMeter{})
467+ c.Assert(err, IsNil)
468+}

Subscribers

People subscribed via source and target branches