func (s *backendSuite) TestInstallingSnapCreatesModulesConf(c *C) { // NOTE: Hand out a permanent snippet so that .conf file is generated. s.Iface.PermanentSlotSnippetCallback = func(slot *interfaces.Slot, securitySystem interfaces.SecuritySystem) ([]byte, error) { if securitySystem == interfaces.SecurityKMod { return []byte("module1 \n module2\nmodule1\n#\n"), nil } return nil, nil } path := filepath.Join(dirs.SnapKModModulesDir, "snap.samba.conf") c.Assert(osutil.FileExists(path), Equals, false) for _, devMode := range []bool{true, false} { s.modprobeCmd.ForgetCalls() snapInfo := s.InstallSnap(c, devMode, backendtest.SambaYamlV1, 0) c.Assert(osutil.FileExists(path), Equals, true) modfile, err := ioutil.ReadFile(path) c.Assert(err, IsNil) c.Assert(string(modfile), Equals, "# This file is automatically generated.\nmodule1\nmodule2\n") c.Assert(s.modprobeCmd.Calls(), DeepEquals, [][]string{ {"modprobe", "--syslog", "module1"}, {"modprobe", "--syslog", "module2"}, }) s.RemoveSnap(c, snapInfo) } }
func (s *linkSuite) TestLinkDoUndoCurrentSymlink(c *C) { const yaml = `name: hello version: 1.0 ` info := snaptest.MockSnap(c, yaml, &snap.SideInfo{Revision: snap.R(11)}) err := s.be.LinkSnap(info) c.Assert(err, IsNil) mountDir := info.MountDir() dataDir := info.DataDir() currentActiveSymlink := filepath.Join(mountDir, "..", "current") currentActiveDir, err := filepath.EvalSymlinks(currentActiveSymlink) c.Assert(err, IsNil) c.Assert(currentActiveDir, Equals, mountDir) currentDataSymlink := filepath.Join(dataDir, "..", "current") currentDataDir, err := filepath.EvalSymlinks(currentDataSymlink) c.Assert(err, IsNil) c.Assert(currentDataDir, Equals, dataDir) // undo will remove the symlinks err = s.be.UnlinkSnap(info, &s.nullProgress) c.Assert(err, IsNil) c.Check(osutil.FileExists(currentActiveSymlink), Equals, false) c.Check(osutil.FileExists(currentDataSymlink), Equals, false) }
// ExecInCoreSnap makes sure you're executing the binary that ships in // the core snap. func ExecInCoreSnap() { if !release.OnClassic { // you're already the real deal, natch return } if os.Getenv(key) != "1" { return } exe, err := os.Readlink("/proc/self/exe") if err != nil { return } full := filepath.Join(newCore, exe) if !osutil.FileExists(full) { if rev, err := os.Readlink(oldCore); err != nil { return } else if revno, err := strconv.Atoi(rev); err != nil || revno < minOldRevno { return } full = filepath.Join(oldCore, exe) if !osutil.FileExists(full) { return } } logger.Debugf("restarting into %q", full) env := append(os.Environ(), key+"=0") panic(syscall.Exec(full, os.Args, env)) }
func (s *setupSuite) TestSetupUndoIdempotent(c *C) { // make sure that a retry wouldn't stumble on partial work // use a kernel because that does and need to do strictly more // this cannot check systemd own behavior though around mounts! bootloader := boottest.NewMockBootloader("mock", c.MkDir()) partition.ForceBootloader(bootloader) // we don't get real mounting os.Setenv("SNAPPY_SQUASHFS_UNPACK_FOR_TESTS", "1") defer os.Unsetenv("SNAPPY_SQUASHFS_UNPACK_FOR_TESTS") testFiles := [][]string{ {"kernel.img", "kernel"}, {"initrd.img", "initrd"}, {"modules/4.4.0-14-generic/foo.ko", "a module"}, {"firmware/bar.bin", "some firmware"}, {"meta/kernel.yaml", "version: 4.2"}, } snapPath := snaptest.MakeTestSnapWithFiles(c, `name: kernel version: 1.0 type: kernel `, testFiles) si := snap.SideInfo{ RealName: "kernel", Revision: snap.R(140), } err := s.be.SetupSnap(snapPath, &si, &s.nullProgress) c.Assert(err, IsNil) minInfo := snap.MinimalPlaceInfo("kernel", snap.R(140)) err = s.be.UndoSetupSnap(minInfo, "kernel", &s.nullProgress) c.Assert(err, IsNil) // retry run err = s.be.UndoSetupSnap(minInfo, "kernel", &s.nullProgress) c.Assert(err, IsNil) // sanity checks l, _ := filepath.Glob(filepath.Join(dirs.SnapServicesDir, "*.mount")) c.Assert(l, HasLen, 0) c.Assert(osutil.FileExists(minInfo.MountDir()), Equals, false) c.Assert(osutil.FileExists(minInfo.MountFile()), Equals, false) l, _ = filepath.Glob(filepath.Join(bootloader.Dir(), "*")) c.Assert(l, HasLen, 0) }
func loadState(backend state.Backend) (*state.State, error) { if !osutil.FileExists(dirs.SnapStateFile) { // fail fast, mostly interesting for tests, this dir is setup // by the snapd package stateDir := filepath.Dir(dirs.SnapStateFile) if !osutil.IsDirectory(stateDir) { return nil, fmt.Errorf("fatal: directory %q must be present", stateDir) } s := state.New(backend) patch.Init(s) return s, nil } r, err := os.Open(dirs.SnapStateFile) if err != nil { return nil, fmt.Errorf("cannot read the state file: %s", err) } defer r.Close() s, err := state.ReadState(backend, r) if err != nil { return nil, err } // one-shot migrations err = patch.Apply(s) if err != nil { return nil, err } return s, nil }
func (s *SnapSuite) TestSnapRunCreateDataDirs(c *check.C) { info, err := snap.InfoFromSnapYaml(mockYaml) c.Assert(err, check.IsNil) info.SideInfo.Revision = snap.R(42) fakeHome := c.MkDir() restorer := snaprun.MockUserCurrent(func() (*user.User, error) { return &user.User{HomeDir: fakeHome}, nil }) defer restorer() err = snaprun.CreateUserDataDirs(info) c.Assert(err, check.IsNil) c.Check(osutil.FileExists(filepath.Join(fakeHome, "/snap/snapname/42")), check.Equals, true) c.Check(osutil.FileExists(filepath.Join(fakeHome, "/snap/snapname/common")), check.Equals, true) }
func (cs *clientSuite) TestClientLogin(c *check.C) { cs.rsp = `{"type": "sync", "result": {"username": "******", "macaroon": "the-root-macaroon", "discharges": ["discharge-macaroon"]}}` outfile := filepath.Join(c.MkDir(), "json") os.Setenv(client.TestAuthFileEnvKey, outfile) defer os.Unsetenv(client.TestAuthFileEnvKey) c.Assert(cs.cli.LoggedIn(), check.Equals, false) user, err := cs.cli.Login("username", "pass", "") c.Check(err, check.IsNil) c.Check(user, check.DeepEquals, &client.User{ Macaroon: "the-root-macaroon", Discharges: []string{"discharge-macaroon"}}) c.Assert(cs.cli.LoggedIn(), check.Equals, true) c.Check(osutil.FileExists(outfile), check.Equals, true) content, err := ioutil.ReadFile(outfile) c.Check(err, check.IsNil) c.Check(string(content), check.Equals, `{"macaroon":"the-root-macaroon","discharges":["discharge-macaroon"]}`) }
func removeMountUnit(baseDir string, meter progress.Meter) error { sysd := systemd.New(dirs.GlobalRootDir, meter) unit := systemd.MountUnitPath(dirs.StripRootDir(baseDir), "mount") if osutil.FileExists(unit) { // use umount -l (lazy) to ensure that even busy mount points // can be unmounted. // note that the long option --lazy is not supported on trusty. if output, err := exec.Command("umount", "-l", baseDir).CombinedOutput(); err != nil { return osutil.OutputErr(output, err) } if err := sysd.Stop(filepath.Base(unit), time.Duration(1*time.Second)); err != nil { return err } if err := sysd.Disable(filepath.Base(unit)); err != nil { return err } if err := os.Remove(unit); err != nil { return err } // daemon-reload to ensure that systemd actually really // forgets about this mount unit if err := sysd.DaemonReload(); err != nil { return err } } return nil }
// Open opens a given snap file with the right backend func Open(path string) (Container, error) { // see if it's a snapdir first if osutil.FileExists(filepath.Join(path, "meta", "snap.yaml")) { return snapdir.New(path), nil } // open the file and check magic f, err := os.Open(path) if err != nil { return nil, fmt.Errorf("cannot open snap: %v", err) } defer f.Close() header := make([]byte, 20) if _, err := f.ReadAt(header, 0); err != nil { return nil, fmt.Errorf("cannot read snap: %v", err) } for _, h := range formatHandlers { if bytes.HasPrefix(header, h.magic) { return h.open(path) } } return nil, fmt.Errorf("cannot open snap: unknown header: %q", header) }
func (s *kernelOSSuite) TestExtractKernelAssetsNoUnpacksKernelForGrub(c *C) { // pretend to be a grub system mockGrub := boottest.NewMockBootloader("grub", c.MkDir()) partition.ForceBootloader(mockGrub) files := [][]string{ {"kernel.img", "I'm a kernel"}, {"initrd.img", "...and I'm an initrd"}, {"meta/kernel.yaml", "version: 4.2"}, } si := &snap.SideInfo{ RealName: "ubuntu-kernel", Revision: snap.R(42), } fn := snaptest.MakeTestSnapWithFiles(c, packageKernel, files) snapf, err := snap.Open(fn) c.Assert(err, IsNil) info, err := snap.ReadInfoFromSnapFile(snapf, si) c.Assert(err, IsNil) err = boot.ExtractKernelAssets(info, snapf) c.Assert(err, IsNil) // kernel is *not* here kernimg := filepath.Join(mockGrub.Dir(), "ubuntu-kernel_42.snap", "kernel.img") c.Assert(osutil.FileExists(kernimg), Equals, false) }
func (x *cmdShell) Execute(args []string) error { if len(args) > 0 { return ErrExtraArgs } shellType := x.Positional.ShellType // FIXME: make this generic so that all snaps can provide a // shell if shellType == "classic" { if !osutil.FileExists("/snap/classic/current") { return fmt.Errorf(i18n.G(`Classic dimension disabled on this system. Use "sudo snap install --devmode classic && sudo classic.create" to enable it.`)) } // we need to re-exec if we do not run as root if os.Getuid() != 0 { if err := reexecWithSudo(); err != nil { return err } } fmt.Fprintln(Stdout, i18n.G(`Entering classic dimension`)) fmt.Fprintln(Stdout, i18n.G(` The home directory is shared between snappy and the classic dimension. Run "exit" to leave the classic shell. `)) args := []string{"/snap/bin/classic.shell"} return syscall.Exec(args[0], args, os.Environ()) } return fmt.Errorf(i18n.G("unsupported shell %v"), shellType) }
// RemoveSnapServices disables and removes service units for the applications from the snap which are services. func RemoveSnapServices(s *snap.Info, inter interacter) error { sysd := systemd.New(dirs.GlobalRootDir, inter) nservices := 0 for _, app := range s.Apps { if app.Daemon == "" || !osutil.FileExists(app.ServiceFile()) { continue } nservices++ serviceName := filepath.Base(app.ServiceFile()) if err := sysd.Disable(serviceName); err != nil { return err } if err := os.Remove(app.ServiceFile()); err != nil && !os.IsNotExist(err) { logger.Noticef("Failed to remove service file for %q: %v", serviceName, err) } if err := os.Remove(app.ServiceSocketFile()); err != nil && !os.IsNotExist(err) { logger.Noticef("Failed to remove socket file for %q: %v", serviceName, err) } } // only reload if we actually had services if nservices > 0 { if err := sysd.DaemonReload(); err != nil { return err } } return nil }
// StopSnapServices stops service units for the applications from the snap which are services. func StopSnapServices(s *snap.Info, inter interacter) error { sysd := systemd.New(dirs.GlobalRootDir, inter) for _, app := range s.Apps { // Handle the case where service file doesn't exist and don't try to stop it as it will fail. // This can happen with snap try when snap.yaml is modified on the fly and a daemon line is added. if app.Daemon == "" || !osutil.FileExists(app.ServiceFile()) { continue } serviceName := filepath.Base(app.ServiceFile()) tout := serviceStopTimeout(app) if err := sysd.Stop(serviceName, tout); err != nil { if !systemd.IsTimeout(err) { return err } inter.Notify(fmt.Sprintf("%s refused to stop, killing.", serviceName)) // ignore errors for kill; nothing we'd do differently at this point sysd.Kill(serviceName, "TERM") time.Sleep(killWait) sysd.Kill(serviceName, "KILL") } } return nil }
// InDeveloperMode returns true if the image was build with --developer-mode func InDeveloperMode() bool { // FIXME: this is a bit terrible, we really need a single // bootloader dir like /boot or /boot/loader // instead of having to query the partition code bootloader, err := findBootloader() if err != nil { // can only happy on systems like ubuntu classic // that are not full snappy systems return false } file := filepath.Join(bootloader.Dir(), InstallYamlFile) if !osutil.FileExists(file) { // no idea return false } InstallYaml, err := parseInstallYaml(file) if err != nil { // no idea return false } return InstallYaml.InstallOptions.DeveloperMode }
// newGrub create a new Grub bootloader object func newGrub() Bootloader { g := &grub{} if !osutil.FileExists(g.ConfigFile()) { return nil } return g }
// newUboot create a new Uboot bootloader object func newUboot() Bootloader { u := &uboot{} if !osutil.FileExists(u.envFile()) { return nil } return u }
func (s *SnapSuite) TestAutoImportFromSpoolHappy(c *C) { restore := release.MockOnClassic(false) defer restore() fakeAssertData := []byte("my-assertion") n := 0 total := 2 s.RedirectClientToTestServer(func(w http.ResponseWriter, r *http.Request) { switch n { case 0: c.Check(r.Method, Equals, "POST") c.Check(r.URL.Path, Equals, "/v2/assertions") postData, err := ioutil.ReadAll(r.Body) c.Assert(err, IsNil) c.Check(postData, DeepEquals, fakeAssertData) fmt.Fprintln(w, `{"type": "sync", "result": {"ready": true, "status": "Done"}}`) n++ case 1: c.Check(r.Method, Equals, "POST") c.Check(r.URL.Path, Equals, "/v2/create-user") postData, err := ioutil.ReadAll(r.Body) c.Assert(err, IsNil) c.Check(string(postData), Equals, `{"sudoer":true,"known":true}`) fmt.Fprintln(w, `{"type": "sync", "result": [{"username": "******"}]}`) n++ default: c.Fatalf("unexpected request: %v (expected %d got %d)", r, total, n) } }) dirs.SetRootDir(c.MkDir()) defer dirs.SetRootDir("") fakeAssertsFn := filepath.Join(dirs.SnapAssertsSpoolDir, "1234343") err := os.MkdirAll(filepath.Dir(fakeAssertsFn), 0755) c.Assert(err, IsNil) err = ioutil.WriteFile(fakeAssertsFn, fakeAssertData, 0644) c.Assert(err, IsNil) l, err := logger.NewConsoleLog(s.stderr, 0) c.Assert(err, IsNil) logger.SetLogger(l) rest, err := snap.Parser().ParseArgs([]string{"auto-import"}) c.Assert(err, IsNil) c.Assert(rest, DeepEquals, []string{}) c.Check(s.Stdout(), Equals, `created user "foo"`+"\n") // matches because we may get a: // "WARNING: cannot create syslog logger\n" // in the output c.Check(s.Stderr(), Matches, fmt.Sprintf("(?ms).*imported %s\n", fakeAssertsFn)) c.Check(n, Equals, total) c.Check(osutil.FileExists(fakeAssertsFn), Equals, false) }
func (s *imageSuite) TestInstallCloudConfigNoConfig(c *C) { targetDir := c.MkDir() emptyGadgetDir := c.MkDir() dirs.SetRootDir(targetDir) err := image.InstallCloudConfig(emptyGadgetDir) c.Assert(err, IsNil) c.Check(osutil.FileExists(filepath.Join(targetDir, "etc/cloud/cloud-init.disabled")), Equals, true) }
func (ms *mgrsSuite) TestHappyRevert(c *C) { st := ms.o.State() st.Lock() defer st.Unlock() x1Yaml := `name: foo version: 1.0 apps: x1: command: bin/bar ` x1binary := filepath.Join(dirs.SnapBinariesDir, "foo.x1") x2Yaml := `name: foo version: 2.0 apps: x2: command: bin/bar ` x2binary := filepath.Join(dirs.SnapBinariesDir, "foo.x2") ms.installLocalTestSnap(c, x1Yaml) ms.installLocalTestSnap(c, x2Yaml) // ensure we are on x2 _, err := os.Lstat(x2binary) c.Assert(err, IsNil) _, err = os.Lstat(x1binary) c.Assert(err, ErrorMatches, ".*no such file.*") // now do the revert ts, err := snapstate.Revert(st, "foo", snapstate.Flags{}) c.Assert(err, IsNil) chg := st.NewChange("revert-snap", "...") chg.AddAll(ts) st.Unlock() err = ms.o.Settle() st.Lock() c.Assert(err, IsNil) c.Assert(chg.Status(), Equals, state.DoneStatus, Commentf("revert-snap change failed with: %v", chg.Err())) // ensure that we use x1 now _, err = os.Lstat(x1binary) c.Assert(err, IsNil) _, err = os.Lstat(x2binary) c.Assert(err, ErrorMatches, ".*no such file.*") // ensure that x1,x2 is still there, revert just moves the "current" // pointer for _, fn := range []string{"foo_x2.snap", "foo_x1.snap"} { p := filepath.Join(dirs.SnapBlobDir, fn) c.Assert(osutil.FileExists(p), Equals, true) } }
func (s *backendSuite) TestRemovingSnapRemovesModulesConf(c *C) { // NOTE: Hand out a permanent snippet so that .conf file is generated. s.Iface.PermanentSlotSnippetCallback = func(slot *interfaces.Slot, securitySystem interfaces.SecuritySystem) ([]byte, error) { if securitySystem == interfaces.SecurityKMod { return []byte("module1\nmodule2"), nil } return nil, nil } path := filepath.Join(dirs.SnapKModModulesDir, "snap.samba.conf") c.Assert(osutil.FileExists(path), Equals, false) for _, devMode := range []bool{true, false} { snapInfo := s.InstallSnap(c, devMode, backendtest.SambaYamlV1, 0) c.Assert(osutil.FileExists(path), Equals, true) s.RemoveSnap(c, snapInfo) c.Assert(osutil.FileExists(path), Equals, false) } }
func init() { ReleaseInfo = readOSRelease() // Assume that we are running on Classic OnClassic = true // On Ubuntu, dpkg is not present in an all-snap image so the presence of // dpkg status file can be used as an indicator for a classic vs all-snap // system. if ReleaseInfo.ID == "ubuntu" { OnClassic = osutil.FileExists("/var/lib/dpkg/status") } }
func (s *desktopSuite) TestAddPackageDesktopFiles(c *C) { expectedDesktopFilePath := filepath.Join(dirs.SnapDesktopFilesDir, "foo_foobar.desktop") c.Assert(osutil.FileExists(expectedDesktopFilePath), Equals, false) info := snaptest.MockSnap(c, desktopAppYaml, &snap.SideInfo{Revision: snap.R(11)}) // generate .desktop file in the package baseDir baseDir := info.MountDir() err := os.MkdirAll(filepath.Join(baseDir, "meta", "gui"), 0755) c.Assert(err, IsNil) err = ioutil.WriteFile(filepath.Join(baseDir, "meta", "gui", "foobar.desktop"), mockDesktopFile, 0644) c.Assert(err, IsNil) err = wrappers.AddSnapDesktopFiles(info) c.Assert(err, IsNil) c.Assert(osutil.FileExists(expectedDesktopFilePath), Equals, true) c.Assert(s.mockUpdateDesktopDatabase.Calls(), DeepEquals, [][]string{ {"update-desktop-database", dirs.SnapDesktopFilesDir}, }) }
func (s *backendSuite) TestRemove(c *C) { appCanaryToGo := filepath.Join(dirs.SnapMountPolicyDir, "snap.hello-world.hello-world.fstab") err := ioutil.WriteFile(appCanaryToGo, []byte("ni! ni! ni!"), 0644) c.Assert(err, IsNil) hookCanaryToGo := filepath.Join(dirs.SnapMountPolicyDir, "snap.hello-world.hook.apply-config.fstab") err = ioutil.WriteFile(hookCanaryToGo, []byte("ni! ni! ni!"), 0644) c.Assert(err, IsNil) canaryToStay := filepath.Join(dirs.SnapMountPolicyDir, "snap.i-stay.really.fstab") err = ioutil.WriteFile(canaryToStay, []byte("stay!"), 0644) c.Assert(err, IsNil) err = s.Backend.Remove("hello-world") c.Assert(err, IsNil) c.Assert(osutil.FileExists(appCanaryToGo), Equals, false) c.Assert(osutil.FileExists(hookCanaryToGo), Equals, false) content, err := ioutil.ReadFile(canaryToStay) c.Assert(err, IsNil) c.Assert(string(content), Equals, "stay!") }
func (s *PartitionTestSuite) TestInstallBootloaderConfig(c *C) { for _, t := range []struct{ gadgetFile, systemFile string }{ {"grub.conf", "/boot/grub/grub.cfg"}, {"uboot.conf", "/boot/uboot/uboot.env"}, } { mockGadgetDir := c.MkDir() err := ioutil.WriteFile(filepath.Join(mockGadgetDir, t.gadgetFile), nil, 0644) err = InstallBootConfig(mockGadgetDir) c.Assert(err, IsNil) fn := filepath.Join(dirs.GlobalRootDir, t.systemFile) c.Assert(osutil.FileExists(fn), Equals, true) } }
func (s *linkSuite) TestLinkUndoIdempotent(c *C) { // make sure that a retry wouldn't stumble on partial work const yaml = `name: hello version: 1.0 apps: bin: command: bin svc: command: svc daemon: simple ` info := snaptest.MockSnap(c, yaml, &snap.SideInfo{Revision: snap.R(11)}) err := s.be.LinkSnap(info) c.Assert(err, IsNil) err = s.be.UnlinkSnap(info, &s.nullProgress) c.Assert(err, IsNil) err = s.be.UnlinkSnap(info, &s.nullProgress) c.Assert(err, IsNil) // no wrappers l, err := filepath.Glob(filepath.Join(dirs.SnapBinariesDir, "*")) c.Assert(err, IsNil) c.Assert(l, HasLen, 0) l, err = filepath.Glob(filepath.Join(dirs.SnapServicesDir, "*.service")) c.Assert(err, IsNil) c.Assert(l, HasLen, 0) // no symlinks currentActiveSymlink := filepath.Join(info.MountDir(), "..", "current") currentDataSymlink := filepath.Join(info.DataDir(), "..", "current") c.Check(osutil.FileExists(currentActiveSymlink), Equals, false) c.Check(osutil.FileExists(currentDataSymlink), Equals, false) }
func (b Backend) DiscardSnapNamespace(snapName string) error { mntFile := mountNsPath(snapName) // If there's a .mnt file that was created by snap-confine we should ask // snap-confine to discard it appropriately. if osutil.FileExists(mntFile) { snapDiscardNs := filepath.Join(dirs.LibExecDir, "snap-discard-ns") cmd := exec.Command(snapDiscardNs, snapName) output, err := cmd.CombinedOutput() if err != nil { return fmt.Errorf("cannot discard preserved namespaces of snap %q: %s", snapName, osutil.OutputErr(output, err)) } } return nil }
func autoImportCandidates() ([]string, error) { var cands []string // see https://www.kernel.org/doc/Documentation/filesystems/proc.txt, // sec. 3.5 f, err := os.Open(mountInfoPath) if err != nil { return nil, err } defer f.Close() scanner := bufio.NewScanner(f) for scanner.Scan() { l := strings.Fields(scanner.Text()) // Per proc.txt:3.5, /proc/<pid>/mountinfo looks like // // 36 35 98:0 /mnt1 /mnt2 rw,noatime master:1 - ext3 /dev/root rw,errors=continue // (1)(2)(3) (4) (5) (6) (7) (8) (9) (10) (11) // // and (7) has zero or more elements, find the "-" separator. i := 6 for i < len(l) && l[i] != "-" { i++ } if i+2 >= len(l) { continue } mountSrc := l[i+2] // skip everything that is not a device (cgroups, debugfs etc) if !strings.HasPrefix(mountSrc, "/dev/") { continue } // skip all loop devices (snaps) if strings.HasPrefix(mountSrc, "/dev/loop") { continue } mountPoint := l[4] cand := filepath.Join(mountPoint, autoImportsName) if osutil.FileExists(cand) { cands = append(cands, cand) } } return cands, scanner.Err() }
func (s *mountunitSuite) TestRemoveMountUnit(c *C) { info := &snap.Info{ SideInfo: snap.SideInfo{ RealName: "foo", Revision: snap.R(13), }, Version: "1.1", Architectures: []string{"all"}, } err := backend.AddMountUnit(info, &s.nullProgress) c.Assert(err, IsNil) // ensure we have the files p := filepath.Join(dirs.SnapServicesDir, "snap-foo-13.mount") c.Assert(osutil.FileExists(p), Equals, true) // now call remove and ensure they are gone err = backend.RemoveMountUnit(info.MountDir(), &s.nullProgress) c.Assert(err, IsNil) p = filepath.Join(dirs.SnapServicesDir, "snaps-foo-13.mount") c.Assert(osutil.FileExists(p), Equals, false) }
func (ms *mgrsSuite) TestHappyRemove(c *C) { st := ms.o.State() st.Lock() defer st.Unlock() snapYamlContent := `name: foo apps: bar: command: bin/bar ` snapInfo := ms.installLocalTestSnap(c, snapYamlContent+"version: 1.0") ts, err := snapstate.Remove(st, "foo", snap.R(0)) c.Assert(err, IsNil) chg := st.NewChange("remove-snap", "...") chg.AddAll(ts) st.Unlock() err = ms.o.Settle() st.Lock() c.Assert(err, IsNil) c.Assert(chg.Status(), Equals, state.DoneStatus, Commentf("remove-snap change failed with: %v", chg.Err())) // ensure that the binary wrapper file got removed binaryWrapper := filepath.Join(dirs.SnapBinariesDir, "foo.bar") c.Assert(osutil.FileExists(binaryWrapper), Equals, false) // data dirs c.Assert(osutil.FileExists(snapInfo.DataDir()), Equals, false) c.Assert(osutil.FileExists(snapInfo.CommonDataDir()), Equals, false) // snap file and its mount c.Assert(osutil.FileExists(filepath.Join(dirs.SnapBlobDir, "foo_x1.snap")), Equals, false) mup := systemd.MountUnitPath("/snap/foo/x1") c.Assert(osutil.FileExists(mup), Equals, false) }
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") }