// AddSnapServices adds service units for the applications from the snap which are services. func AddSnapServices(s *snap.Info, inter interacter) error { for _, app := range s.Apps { if app.Daemon == "" { continue } // Generate service file content, err := generateSnapServiceFile(app) 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) 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 } } } return nil }
// AddSnapDesktopFiles puts in place the desktop files for the applications from the snap. func AddSnapDesktopFiles(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 } installedDesktopFileName := filepath.Join(dirs.SnapDesktopFilesDir, fmt.Sprintf("%s_%s", s.Name(), filepath.Base(df))) content = sanitizeDesktopFile(s, installedDesktopFileName, content) if err := osutil.AtomicWriteFile(installedDesktopFileName, []byte(content), 0755, 0); err != nil { return err } } // updates mime info etc if err := updateDesktopDatabase(desktopFiles); err != nil { return err } return nil }
func (s *systemd) WriteMountUnitFile(name, what, where, fstype string) (string, error) { extra := "" if osutil.IsDirectory(what) { extra = "Options=bind\n" fstype = "none" } if fstype == "squashfs" && useFuse() { fstype = "fuse.squashfuse" } c := fmt.Sprintf(`[Unit] Description=Mount unit for %s [Mount] What=%s Where=%s Type=%s %s [Install] WantedBy=multi-user.target `, name, what, where, fstype, extra) mu := MountUnitPath(where) return filepath.Base(mu), osutil.AtomicWriteFile(mu, []byte(c), 0644, 0) }
func (seed *Seed) Write(seedFn string) error { data, err := yaml.Marshal(&seed) if err != nil { return err } if err := osutil.AtomicWriteFile(seedFn, data, 0644, 0); err != nil { return err } return nil }
func StampFirstBoot() error { // filepath.Dir instead of firstbootDir directly to ease testing stampDir := filepath.Dir(dirs.SnapFirstBootStamp) if _, err := os.Stat(stampDir); os.IsNotExist(err) { if err := os.MkdirAll(stampDir, 0755); err != nil { return err } } return osutil.AtomicWriteFile(dirs.SnapFirstBootStamp, []byte{}, 0644, 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) }
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 }
// InitialNetworkConfig writes and applies a netplan config that // enables dhcp on all wired interfaces. In the long run this should // be run as part of the config-changed hook and read the snap's // config to determine the netplan config to write. func InitialNetworkConfig() error { // If the config is already present, don't overwrite it. See // https://bugs.launchpad.net/snappy/+bug/1623119. if _, err := os.Stat(netplanConfigFile); err == nil { return nil } if err := osutil.AtomicWriteFile(netplanConfigFile, []byte(netplanConfigData), 0644, 0); err != nil { return err } enable := exec.Command(enableConfig[0], enableConfig[1:]...) enable.Stdout = os.Stdout enable.Stderr = os.Stderr return enable.Run() }
func installCloudConfig(gadgetDir string) error { var err error cloudDir := filepath.Join(dirs.GlobalRootDir, "/etc/cloud") if err := os.MkdirAll(cloudDir, 0755); err != nil { return err } cloudConfig := filepath.Join(gadgetDir, "cloud.conf") if osutil.FileExists(cloudConfig) { dst := filepath.Join(cloudDir, "cloud.cfg") err = osutil.CopyFile(cloudConfig, dst, osutil.CopyFlagOverwrite) } else { dst := filepath.Join(cloudDir, "cloud-init.disabled") err = osutil.AtomicWriteFile(dst, nil, 0644, 0) } return err }
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) }
func (osb *overlordStateBackend) Checkpoint(data []byte) error { return osutil.AtomicWriteFile(osb.path, data, 0600, 0) }
func (s *BaseSnapSuite) Login(c *C) { err := osutil.AtomicWriteFile(s.AuthFile, []byte(TestAuthFileContents), 0600, 0) c.Assert(err, IsNil) }
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), })