Esempio n. 1
0
func addPackageDesktopFiles(s *snap.Info) error {
	if err := os.MkdirAll(dirs.SnapDesktopFilesDir, 0755); err != nil {
		return err
	}

	baseDir := s.MountDir()

	desktopFiles, err := filepath.Glob(filepath.Join(baseDir, "meta", "gui", "*.desktop"))
	if err != nil {
		return fmt.Errorf("cannot get desktop files for %v: %s", baseDir, err)
	}

	for _, df := range desktopFiles {
		content, err := ioutil.ReadFile(df)
		if err != nil {
			return err
		}

		realBaseDir := stripGlobalRootDir(baseDir)
		content = sanitizeDesktopFile(s, realBaseDir, content)

		installedDesktopFileName := filepath.Join(dirs.SnapDesktopFilesDir, fmt.Sprintf("%s_%s", s.Name(), filepath.Base(df)))
		if err := osutil.AtomicWriteFile(installedDesktopFileName, []byte(content), 0755, 0); err != nil {
			return err
		}
	}

	return nil
}
Esempio n. 2
0
func enableFirstEther() error {
	gadget, _ := getGadget()
	if gadget != nil && gadget.Legacy.Gadget.SkipIfupProvisioning {
		return nil
	}

	var eths []string
	for _, glob := range globs {
		eths, _ = filepath.Glob(glob)
		if len(eths) != 0 {
			break
		}
	}
	if len(eths) == 0 {
		return nil
	}
	eth := filepath.Base(eths[0])
	ethfile := filepath.Join(ethdir, eth)
	data := fmt.Sprintf("allow-hotplug %[1]s\niface %[1]s inet dhcp\n", eth)

	if err := osutil.AtomicWriteFile(ethfile, []byte(data), 0644, 0); err != nil {
		return err
	}

	ifup := exec.Command(ifup, eth)
	ifup.Stdout = os.Stdout
	ifup.Stderr = os.Stderr
	if err := ifup.Run(); err != nil {
		return err
	}

	return nil
}
Esempio n. 3
0
func addPackageBinaries(s *snap.Info) error {
	if err := os.MkdirAll(dirs.SnapBinariesDir, 0755); err != nil {
		return err
	}

	baseDir := s.MountDir()

	for _, app := range s.Apps {
		if app.Daemon != "" {
			continue
		}

		// this will remove the global base dir when generating the
		// service file, this ensures that /snap/foo/1.0/bin/start
		// is in the service file when the SetRoot() option
		// is used
		realBaseDir := stripGlobalRootDir(baseDir)
		content, err := generateSnapBinaryWrapper(app, realBaseDir)
		if err != nil {
			return err
		}

		if err := osutil.AtomicWriteFile(app.WrapperPath(), []byte(content), 0755, 0); err != nil {
			return err
		}
	}

	return nil
}
Esempio n. 4
0
// writeAuthData saves authentication details for later reuse through ReadAuthData
func writeAuthData(user User) error {
	targetFile := storeAuthDataFilename()
	if err := os.MkdirAll(filepath.Dir(targetFile), 0700); err != nil {
		return err
	}
	outStr, err := json.Marshal(user)
	if err != nil {
		return nil
	}

	return osutil.AtomicWriteFile(targetFile, []byte(outStr), 0600, 0)
}
Esempio n. 5
0
func stampFirstBoot() error {
	// filepath.Dir instead of firstbootDir directly to ease testing
	stampDir := filepath.Dir(stampFile)

	if _, err := os.Stat(stampDir); os.IsNotExist(err) {
		if err := os.MkdirAll(stampDir, 0755); err != nil {
			return err
		}
	}

	return osutil.AtomicWriteFile(stampFile, []byte{}, 0644, 0)
}
Esempio n. 6
0
func atomicWriteEntry(data []byte, secret bool, top string, subpath ...string) error {
	fpath := filepath.Join(top, filepath.Join(subpath...))
	dir := filepath.Dir(fpath)
	err := os.MkdirAll(dir, 0775)
	if err != nil {
		return err
	}
	fperm := 0664
	if secret {
		fperm = 0600
	}
	return osutil.AtomicWriteFile(fpath, data, os.FileMode(fperm), 0)
}
Esempio n. 7
0
// writeApparmorAdditionalFile generate a $partID.json.additional file.
//
// This file grants additional access on top of the existing apparmor json
// rules. This is required for the Gadget hardware assign code because by
// default apparmor will not allow access to /dev. We grant access here
// and the ubuntu-core-launcher is then used to generate a confinement
// based on the devices cgroup.
func writeApparmorAdditionalFile(s *snap.Info) error {
	if err := os.MkdirAll(dirs.SnapAppArmorDir, 0755); err != nil {
		return err
	}

	for _, h := range s.Legacy.Gadget.Hardware.Assign {
		jsonAdditionalPath := filepath.Join(dirs.SnapAppArmorDir, fmt.Sprintf("%s.json.additional", h.PartID))
		if err := osutil.AtomicWriteFile(jsonAdditionalPath, []byte(apparmorAdditionalContent), 0644, 0); err != nil {
			return err
		}
	}

	return nil
}
Esempio n. 8
0
func setPassthrough(rootDir string, pc []passthroughConfig) error {
	for _, c := range pc {
		path := filepath.Join(rootDir, c.Name)
		if c.Content == "" {
			os.Remove(path)
			continue
		}
		if err := osutil.AtomicWriteFile(path, []byte(c.Content), 0644, osutil.AtomicWriteFollow); err != nil {
			return err
		}
	}

	return nil
}
Esempio n. 9
0
func (s *systemd) WriteMountUnitFile(name, what, where string) (string, error) {
	c := fmt.Sprintf(`[Unit]
Description=Squashfs mount unit for %s

[Mount]
What=%s
Where=%s

[Install]
WantedBy=multi-user.target
`, name, what, where)

	mu := MountUnitPath(where, "mount")
	return filepath.Base(mu), osutil.AtomicWriteFile(mu, []byte(c), 0644, 0)
}
Esempio n. 10
0
func setModules(modules []string) error {
	oldModules, err := getModules()
	if err != nil {
		return err
	}

	for i := range modules {
		m := strings.TrimSpace(modules[i])
		if len(m) == 0 {
			continue
		}

		if m[0] == '-' {
			m = m[1:]
			idx := sort.SearchStrings(oldModules, m)
			if idx == len(oldModules) || oldModules[idx] != m {
				// not found
				continue
			}
			oldModules = append(oldModules[:idx], oldModules[idx+1:]...)
		} else {
			idx := sort.SearchStrings(oldModules, m)
			if idx < len(oldModules) && oldModules[idx] == m {
				// already got it
				continue
			}
			oldModules = append(oldModules, "")
			copy(oldModules[idx+1:], oldModules[idx:])
			oldModules[idx] = m
		}
	}

	var buf bytes.Buffer

	// bytes' Write* methods always return nil error
	buf.WriteString(modulesHeader)

	for i := range oldModules {
		buf.WriteString(oldModules[i])
		buf.WriteByte('\n')
	}

	return osutil.AtomicWriteFile(modulesPath, buf.Bytes(), 0644, osutil.AtomicWriteFollow)
}
Esempio n. 11
0
// SaveManifest saves the manifest at the designated location for the snap containing information not in the snap.yaml.
func SaveManifest(rsnap *snap.Info) error {
	if rsnap.Revision == 0 {
		return fmt.Errorf("internal error: should not be storring manifests for sideloaded snaps")
	}

	// XXX: we store OfficialName though it may not be the blessed one later
	content, err := yaml.Marshal(&rsnap.SideInfo)
	if err != nil {
		return err
	}

	if err := os.MkdirAll(dirs.SnapMetaDir, 0755); err != nil {
		return err
	}

	p := manifestPath(rsnap.Name(), rsnap.Revision)
	// don't worry about previous contents
	return osutil.AtomicWriteFile(p, content, 0644, 0)
}
Esempio n. 12
0
func writeGadgetHardwareUdevRules(s *snap.Info) error {
	os.MkdirAll(dirs.SnapUdevRulesDir, 0755)

	// cleanup
	if err := cleanupGadgetHardwareUdevRules(s); err != nil {
		return err
	}
	// write new files
	for _, h := range s.Legacy.Gadget.Hardware.Assign {
		rulesContent, err := generateUdevRuleContent(&h)
		if err != nil {
			return err
		}
		outfile := filepath.Join(dirs.SnapUdevRulesDir, fmt.Sprintf("80-snappy_%s_%s.rules", s.Name(), h.PartID))
		if err := osutil.AtomicWriteFile(outfile, []byte(rulesContent), 0644, 0); err != nil {
			return err
		}
	}

	return nil
}
Esempio n. 13
0
func addPackageServices(s *snap.Info, inter interacter) error {
	baseDir := s.MountDir()

	for _, app := range s.Apps {
		if app.Daemon == "" {
			continue
		}

		// this will remove the global base dir when generating the
		// service file, this ensures that /snap/foo/1.0/bin/start
		// is in the service file when the SetRoot() option
		// is used
		realBaseDir := stripGlobalRootDir(baseDir)
		// Generate service file
		content, err := generateSnapServicesFile(app, realBaseDir)
		if err != nil {
			return err
		}
		svcFilePath := app.ServiceFile()
		os.MkdirAll(filepath.Dir(svcFilePath), 0755)
		if err := osutil.AtomicWriteFile(svcFilePath, []byte(content), 0644, 0); err != nil {
			return err
		}
		// Generate systemd socket file if needed
		if app.Socket {
			content, err := generateSnapSocketFile(app, realBaseDir)
			if err != nil {
				return err
			}
			svcSocketFilePath := app.ServiceSocketFile()
			os.MkdirAll(filepath.Dir(svcSocketFilePath), 0755)
			if err := osutil.AtomicWriteFile(svcSocketFilePath, []byte(content), 0644, 0); err != nil {
				return err
			}
		}
		// daemon-reload and enable plus start
		serviceName := filepath.Base(app.ServiceFile())
		sysd := systemd.New(dirs.GlobalRootDir, inter)

		if err := sysd.DaemonReload(); err != nil {
			return err
		}

		// enable the service
		if err := sysd.Enable(serviceName); err != nil {
			return err
		}

		if err := sysd.Start(serviceName); err != nil {
			return err
		}

		if app.Socket {
			socketName := filepath.Base(app.ServiceSocketFile())
			// enable the socket
			if err := sysd.Enable(socketName); err != nil {
				return err
			}

			if err := sysd.Start(socketName); err != nil {
				return err
			}
		}
	}

	return nil
}
Esempio n. 14
0
func (osb *overlordStateBackend) Checkpoint(data []byte) error {
	return osutil.AtomicWriteFile(osb.path, data, 0600, 0)
}
Esempio n. 15
0
	tz, err := ioutil.ReadFile(tzFile())
	if err != nil {
		return "", err
	}

	return strings.TrimSpace(string(tz)), nil
}

// setTimezone sets the specified timezone for the system, an error is returned
// if it can't.
var setTimezone = func(timezone string) error {
	if err := osutil.CopyFile(filepath.Join(tzZoneInfoPath, timezone), tzZoneInfoTarget, osutil.CopyFlagOverwrite); err != nil {
		return err
	}

	return osutil.AtomicWriteFile(tzFile(), []byte(timezone), 0644, osutil.AtomicWriteFollow)
}

func getPassthrough(rootDir string) (pc []passthroughConfig, err error) {
	filepath.Walk(rootDir, func(path string, info os.FileInfo, err error) error {
		if info.IsDir() {
			return nil
		}
		content, err := ioutil.ReadFile(path)
		if err != nil {
			return err
		}
		pc = append(pc, passthroughConfig{
			Name:    path[len(rootDir):],
			Content: string(content),
		})