Exemple #1
0
// returns string property prop
func (proc *SProcess) GetProperty(prop string) string {
	var (
		file *os.File
		err  error
	)

	// file exists
	if proc.files[prop] != nil {
		file = proc.files[prop]
		file.Seek(0, 0)

		// doesn't exist; create
	} else {
		file, err = os.Create("/system/process/" + strconv.Itoa(proc.pid) + "/" + prop)
		file.Chmod(0755)
	}

	// read up to 1024 bytes
	b := make([]byte, 1024)
	_, err = file.Read(b)

	// an error occured, and it was not an EOF
	if err != nil && err != io.EOF {
		return "(undefined)"
	}

	// file was more than 1M
	if err != io.EOF {
		return "(maxed out)"
	}

	return string(b)
}
Exemple #2
0
// try hard to create a file with MODE at PATH. creates any missing
// directories in PATH and will try to move un-writable files out of
// the way if necessary.
func Create(path string, mode os.FileMode) (*os.File, error) {
	var err error
	err = os.MkdirAll(filepath.Dir(path), 0744)
	if err != nil {
		return nil, err
	}
	var wr *os.File
	for tries := 0; tries < 2; tries++ {
		wr, err = os.OpenFile(path, os.O_CREATE|os.O_WRONLY, mode)
		// sometimes, can't overwrite a file, but can move it out of the way
		if err != nil {
			trash := path + ".trash"
			os.Remove(trash)
			rename := os.Rename(path, trash)
			if rename == nil {
				continue
			} else {
				break
			}
		} else {
			break
		}
	}
	if err == nil && wr != nil {
		wr.Chmod(mode)
	}
	return wr, err

}
Exemple #3
0
func copyPathToPath(fromPath, toPath string) (err error) {
	srcFileInfo, err := os.Stat(fromPath)
	if err != nil {
		return
	}

	if srcFileInfo.IsDir() {
		err = os.MkdirAll(toPath, srcFileInfo.Mode())
		if err != nil {
			return
		}
	} else {
		var dst *os.File
		dst, err = fileutils.Create(toPath)
		if err != nil {
			return
		}
		defer dst.Close()

		dst.Chmod(srcFileInfo.Mode())

		err = fileutils.CopyPathToWriter(fromPath, dst)
	}
	return err
}
Exemple #4
0
func (st *Store) DestructiveSavePath(path string) (hash string, err error) {
	start := time.Now()
	var f *os.File
	f, err = os.Open(path)
	if err != nil {
		return "", err
	}
	before, _ := f.Stat()
	defer f.Close()

	h := st.Options.Hash.New()

	var content []byte
	var size int
	if before.Size() < st.Options.MemMaxSize {
		content, err = ioutil.ReadAll(f)
		if err != nil {
			return "", err
		}

		size, _ = h.Write(content)
	} else {
		sz, _ := io.Copy(h, f)
		size = int(sz)
	}

	s := string(h.Sum(nil))
	if st.HasHash(s) {
		os.Remove(path)
		return s, nil
	}

	st.mutex.Lock()
	st.have[s] = true
	if content != nil && st.inMemoryCache != nil {
		st.inMemoryCache.Add(s, content)
	}
	st.mutex.Unlock()

	p := st.Path(s)
	err = os.Rename(path, p)
	if err != nil {
		log.Fatal("Rename failed", err)
	}
	f.Chmod(0444)
	after, _ := f.Stat()
	if !after.ModTime().Equal(before.ModTime()) || after.Size() != before.Size() {
		log.Fatal("File changed during save", before, after)
	}

	dt := time.Now().Sub(start)

	st.AddTiming("DestructiveSave", size, dt)

	log.Printf("Saving %s as %x destructively", path, s)
	return s, nil
}
Exemple #5
0
func TextEditor(inPath string, inContent []byte) ([]byte, error) {
	var f *os.File
	var err error
	var path string

	// Detect the text editor to use
	editor := os.Getenv("VISUAL")
	if editor == "" {
		editor = os.Getenv("EDITOR")
		if editor == "" {
			editor = "vi"
		}
	}

	if inPath == "" {
		// If provided input, create a new file
		f, err = ioutil.TempFile("", "lxd_editor_")
		if err != nil {
			return []byte{}, err
		}

		if err = f.Chmod(0600); err != nil {
			f.Close()
			os.Remove(f.Name())
			return []byte{}, err
		}

		f.Write(inContent)
		f.Close()

		path = f.Name()
		defer os.Remove(path)
	} else {
		path = inPath
	}

	cmdParts := strings.Fields(editor)
	cmd := exec.Command(cmdParts[0], append(cmdParts[1:], path)...)
	cmd.Stdin = os.Stdin
	cmd.Stdout = os.Stdout
	cmd.Stderr = os.Stderr
	err = cmd.Run()
	if err != nil {
		return []byte{}, err
	}

	content, err := ioutil.ReadFile(path)
	if err != nil {
		return []byte{}, err
	}

	return content, nil
}
Exemple #6
0
func (appfiles ApplicationFiles) CopyFiles(appFiles []models.AppFileFields, fromDir, toDir string) error {
	for _, file := range appFiles {
		err := func() error {
			fromPath := filepath.Join(fromDir, file.Path)
			srcFileInfo, err := os.Stat(fromPath)
			if err != nil {
				return err
			}

			toPath := filepath.Join(toDir, file.Path)

			if srcFileInfo.IsDir() {
				err = os.MkdirAll(toPath, srcFileInfo.Mode())
				if err != nil {
					return err
				}
				return nil
			}

			var dst *os.File
			dst, err = fileutils.Create(toPath)
			if err != nil {
				return err
			}
			defer dst.Close()

			dst.Chmod(srcFileInfo.Mode())

			src, err := os.Open(fromPath)
			if err != nil {
				return err
			}
			defer src.Close()

			_, err = io.Copy(dst, src)
			if err != nil {
				return err
			}

			return nil
		}()

		if err != nil {
			return err
		}
	}

	return nil
}
Exemple #7
0
func (u *Unarchiver) writeFile(blockSource chan block, workInProgress *sync.WaitGroup) {
	var file *os.File = nil
	var bufferedFile *bufio.Writer
	for block := range blockSource {
		if block.blockType == blockTypeStartOfFile {
			u.Logger.Verbose(block.filePath)

			if u.DryRun {
				continue
			}

			tmp, err := os.Create(block.filePath)
			if err != nil {
				u.Logger.Warning("File create error:", err.Error())
				file = nil
				continue
			}
			file = tmp
			bufferedFile = bufio.NewWriter(file)

			if !u.IgnoreOwners {
				err = file.Chown(block.uid, block.gid)
				if err != nil {
					u.Logger.Warning("Unable to chown file to", block.uid, "/", block.gid, ":", err.Error())
				}
			}
			if !u.IgnorePerms {
				err = file.Chmod(block.mode)
				if err != nil {
					u.Logger.Warning("Unable to chmod file to", block.mode, ":", err.Error())
				}
			}
		} else if file == nil {
			// do nothing; file couldn't be opened for write
		} else if block.blockType == blockTypeEndOfFile {
			bufferedFile.Flush()
			file.Close()
			file = nil
		} else {
			_, err := bufferedFile.Write(block.buffer[:block.numBytes])
			if err != nil {
				u.Logger.Warning("File write error:", err.Error())
			}
		}
	}
	workInProgress.Done()
}
Exemple #8
0
func CopyPathToPath(fromPath, toPath string) (err error) {
	srcFileInfo, err := os.Stat(fromPath)
	if err != nil {
		return err
	}

	if srcFileInfo.IsDir() {
		err = os.MkdirAll(toPath, srcFileInfo.Mode())
		if err != nil {
			return err
		}

		files, err := ioutil.ReadDir(fromPath)
		if err != nil {
			return err
		}

		for _, file := range files {
			err = CopyPathToPath(path.Join(fromPath, file.Name()), path.Join(toPath, file.Name()))
			if err != nil {
				return err
			}
		}
	} else {
		var dst *os.File
		dst, err = Create(toPath)
		if err != nil {
			return err
		}
		defer dst.Close()

		dst.Chmod(srcFileInfo.Mode())

		src, err := os.Open(fromPath)
		if err != nil {
			return err
		}
		defer src.Close()

		_, err = io.Copy(dst, src)
		if err != nil {
			return err
		}
	}
	return err
}
Exemple #9
0
func (u *Unzip) Expand() error {
	file_handler := func(meta *ZipMeta) error {

		if meta.artifacts == nil {
			meta.artifacts = list.New()
		}
		Zipfile := meta.current_file.file
		meta.artifacts.PushBack(meta.current_file)

		var (
			err  error
			file *os.File
			rc   io.ReadCloser
		)
		if rc, err = Zipfile.Open(); err != nil {
			return err
		}

		if file, err = os.Create(Zipfile.Name); err != nil {
			return err
		}

		if _, err = io.Copy(file, rc); err != nil {
			return err
		}

		if err = file.Chmod(Zipfile.Mode().Perm()); err != nil {
			//log.Println(err) // Windows WTF?
		}
		file.Close()
		rc.Close()
		return nil
	}

	folder_handler := func(meta *ZipMeta) error {
		return os.MkdirAll(meta.last_folder, 0755)
	}
	meta := ZipMeta{file_handler, folder_handler, make(map[string]bool), "", nil, nil}
	if err := meta.walk(u.Zipfile); err != nil {
		return err
	} else {
		u.Artifacts = meta.artifacts
	}
	return nil
}
Exemple #10
0
func main() {
	var err error
	var path string
	var mode *os.FileMode

	if len(os.Args) > 1 {
		path = os.Args[1]
	} else {
		fmt.Fprintf(os.Stderr, "usage: putfile path [mode]\n")
		os.Exit(1)
	}

	if len(os.Args) > 2 {
		var m uint64
		m, err = strconv.ParseUint(os.Args[2], 8, 32)
		if err != nil {
			fmt.Fprintf(os.Stderr, "bad file mode=`%s`\n", os.Args[2])
			os.Exit(1)
		}
		var m2 os.FileMode
		m2 = os.FileMode(m)
		mode = &m2
	}

	var f *os.File
	f, err = os.Create(path)
	if err != nil {
		fmt.Fprintln(os.Stderr, err)
		os.Exit(1)
	}
	defer f.Close()
	if mode != nil {
		err = f.Chmod(*mode)
		if err != nil {
			fmt.Fprintln(os.Stderr, err)
			os.Exit(1)
		}
	}

	_, err = io.Copy(f, os.Stdin)
	if err != nil {
		fmt.Fprintln(os.Stderr, err)
		os.Exit(1)
	}
}
Exemple #11
0
func UnzipMem(arc []byte, size int64) error {
	var (
		err  error
		file *os.File
		rc   io.ReadCloser
		r    *zip.Reader
	)
	ra := bytes.NewReader(arc)

	if r, err = zip.NewReader(ra, size); err != nil {
		log.Fatal(err)
		return err
	}

	for _, f := range r.File {
		fmt.Println(f.Name)
		if f.Mode().IsDir() { // if file is a directory
			if err = os.MkdirAll(f.Name, f.Mode().Perm()); err != nil {
				return err
			}
			continue
		}

		if rc, err = f.Open(); err != nil {
			return err
		}

		if file, err = os.Create(f.Name); err != nil {
			return err
		}

		if _, err = io.Copy(file, rc); err != nil {
			return err
		}

		if err = file.Chmod(f.Mode().Perm()); err != nil {
			return err
		}

		file.Close()
		rc.Close()
	}
	return nil
}
Exemple #12
0
func UnzipFile(name string) error {
	var (
		err  error
		file *os.File
		rc   io.ReadCloser
		r    *zip.ReadCloser
	)
	if r, err = zip.OpenReader(name); err != nil {
		log.Fatal(err)
		return err
	}
	defer r.Close()

	for _, f := range r.File {
		fmt.Println(f.Name)
		if f.Mode().IsDir() { // if file is a directory
			if err = os.MkdirAll(f.Name, f.Mode().Perm()); err != nil {
				return err
			}
			continue
		}

		if rc, err = f.Open(); err != nil {
			return err
		}

		if file, err = os.Create(f.Name); err != nil {
			return err
		}

		if _, err = io.Copy(file, rc); err != nil {
			return err
		}

		if err = file.Chmod(f.Mode().Perm()); err != nil {
			return err
		}

		file.Close()
		rc.Close()
	}
	return nil
}
Exemple #13
0
// assign a property
func (proc *SProcess) SetProperty(prop string, value string) {
	var file *os.File

	// file exists; empty
	if proc.files[prop] != nil {
		file = proc.files[prop]
		file.Truncate(0)

		// doesn't exist; create
	} else {
		file, _ = os.Create("/system/process/" + strconv.Itoa(proc.pid) + "/" + prop)
		file.Chmod(0755)
	}

	proc.files[prop] = file

	// write
	file.Seek(0, 0)
	file.WriteString(value)
}
func getBenchClientPath() (path string, err error) {
	benchClientOnce.Do(func() {
		var tempFile *os.File
		tempFile, err = ioutil.TempFile("", "benchclient")
		if err != nil {
			return
		}
		if err = tempFile.Chmod(0755); err != nil {
			return
		}

		benchClientPath = tempFile.Name()
		cmd := exec.Command("go", "build", "-o", tempFile.Name(), ".")
		cmd.Dir = "./benchclient"
		cmd.Stdout = os.Stdout
		cmd.Stderr = os.Stderr
		err = cmd.Run()
	})

	return benchClientPath, err
}
Exemple #15
0
/*
	Brute copy from [source] to [target].
*/
func copyFile(source, target string) error {

	var sourceFile, targetFile *os.File
	var err error

	sourceFile, err = os.Open(source)
	if err != nil {
		return err
	}
	defer sourceFile.Close()

	targetFile, err = os.Create(target)
	if err != nil {
		return err
	}
	targetFile.Chmod(0755)
	defer targetFile.Close()

	_, err = io.Copy(targetFile, sourceFile)
	return err
}
Exemple #16
0
//通过OS写文件
func OsWriteFile(path string, content []byte, perm os.FileMode, append bool) error {
	var f *os.File
	var err error
	if append {
		f, err = os.OpenFile(path, os.O_WRONLY|os.O_APPEND|os.O_CREATE, perm)
	} else {
		f, err = os.OpenFile(path, os.O_WRONLY|os.O_TRUNC|os.O_CREATE, perm)
	}
	defer f.Close()
	if err != nil {
		return err
	} else {
		_, err := f.Write(content)
		if err != nil {
			return err
		} else {
			f.Sync()
			f.Chmod(perm)
			return nil
		}
	}
}
Exemple #17
0
func templateApply(c *lxdContainer, trigger string) error {
	fname := shared.VarPath("lxc", c.name, "metadata.yaml")

	if _, err := os.Stat(fname); err != nil {
		return nil
	}

	content, err := ioutil.ReadFile(fname)
	if err != nil {
		return err
	}

	metadata := new(imageMetadata)
	err = yaml.Unmarshal(content, &metadata)

	if err != nil {
		return fmt.Errorf("Could not parse %s: %v", fname, err)
	}

	for path, template := range metadata.Templates {
		var w *os.File

		found := false
		for _, tplTrigger := range template.When {
			if tplTrigger == trigger {
				found = true
				break
			}
		}

		if !found {
			continue
		}

		fpath := shared.VarPath("lxc", c.name, "rootfs", strings.TrimLeft(path, "/"))

		if _, err := os.Stat(fpath); err == nil {
			w, err = os.Create(fpath)
			if err != nil {
				return err
			}
		} else {
			w, err = os.Create(fpath)
			if err != nil {
				return err
			}

			uid, gid := c.idmapset.ShiftIntoNs(0, 0)
			w.Chown(uid, gid)
			w.Chmod(0644)
		}

		tpl, err := pongo2.FromFile(shared.VarPath("lxc", c.name, "templates", template.Template))
		if err != nil {
			return err
		}

		container_meta := make(map[string]string)
		container_meta["name"] = c.name
		container_meta["architecture"], _ = shared.ArchitectureName(c.architecture)

		if c.ephemeral {
			container_meta["ephemeral"] = "true"
		} else {
			container_meta["ephemeral"] = "false"
		}

		if c.isPrivileged() {
			container_meta["privileged"] = "true"
		} else {
			container_meta["privileged"] = "false"
		}

		tpl.ExecuteWriter(pongo2.Context{"trigger": trigger,
			"path":       path,
			"container":  container_meta,
			"config":     c.config,
			"devices":    c.devices,
			"properties": template.Properties}, w)
	}

	return nil
}
Exemple #18
0
			Expect(err).To(HaveOccurred())
			testFileIsEmpty()
		})

		It("downloads the data at the url", func() {
			requester.GetProductDownloadUrlReturns(server.URL(), nil)
			err := api.Download(&resource.ProductFile{}, file.Name())

			Expect(err).ToNot(HaveOccurred())
			res, err := ioutil.ReadFile(file.Name())
			Expect(res).To(Equal([]byte("aaa")))
		})

		It("returns an error if it can't write to the file", func() {
			requester.GetProductDownloadUrlReturns(server.URL(), nil)
			err := file.Chmod(0444)

			Expect(err).ToNot(HaveOccurred())
			err = api.Download(&resource.ProductFile{}, file.Name())
			Expect(err).To(HaveOccurred())
		})
	})

	Context("GetVersionsForProduct", func() {
		It("Returns an error if the product is empty", func() {
			versions, err := api.GetVersionsForProduct("")
			Expect(err).To(HaveOccurred())
			Expect(versions).To(BeEmpty())
		})

		It("returns an error if it can't get the product from the server", func() {
Exemple #19
0
						"Schemas": getSchemas(),
					}
					cacheString, _ := json.Marshal(cache)
					file.WriteString(fmt.Sprintf("%s", cacheString))

					gohanClientCLI.opts.cachePath = file.Name()
					schemas, err := gohanClientCLI.getCachedSchemas()
					Expect(err).ToNot(HaveOccurred())
					Expect(schemas).To(HaveLen(2))
					Expect(schemas[0].ID).To(Equal("castle"))
					Expect(schemas[1].ID).To(Equal("tower"))
				})

				It("Should bypass cache - error reading file", func() {
					server.AppendHandlers(ghttp.RespondWithJSONEncoded(200, getSchemasResponse()))
					file.Chmod(os.ModeDir)
					gohanClientCLI.opts.cachePath = file.Name()
					schemas, err := gohanClientCLI.getCachedSchemas()
					Expect(err).ToNot(HaveOccurred())
					Expect(schemas).To(HaveLen(2))
					Expect(schemas[0].ID).To(Equal("castle"))
					Expect(schemas[1].ID).To(Equal("tower"))
				})

				It("Should bypass cache - error unmarshalling cache", func() {
					server.AppendHandlers(ghttp.RespondWithJSONEncoded(200, getSchemasResponse()))
					gohanClientCLI.opts.cachePath = file.Name()
					schemas, err := gohanClientCLI.getCachedSchemas()
					Expect(err).ToNot(HaveOccurred())
					Expect(schemas).To(HaveLen(2))
					Expect(schemas[0].ID).To(Equal("castle"))
Exemple #20
0
func GenerateKey(keyFileBase string) (err error) {
	if len(keyFileBase) == 0 {
		return errors.New("key file basename must not be emtpy")
	}
	if isExistingDirectory(keyFileBase) {
		return errors.New("key file basename must not be a directory")
	}

	var f *os.File
	var e *openpgp.Entity
	name, comment, email := entityData()
	e, err = openpgp.NewEntity(name, comment, email, nil)
	if err != nil {
		return err
	}
	for _, id := range e.Identities {
		id.SelfSignature.PreferredSymmetric = []uint8{
			uint8(packet.CipherAES128),
			uint8(packet.CipherAES256),
			uint8(packet.CipherAES192),
			uint8(packet.CipherCAST5),
		}
		id.SelfSignature.PreferredHash = []uint8{
			hashToHashId(crypto.RIPEMD160),
			hashToHashId(crypto.SHA256),
			hashToHashId(crypto.SHA384),
			hashToHashId(crypto.SHA512),
			hashToHashId(crypto.SHA224),
			hashToHashId(crypto.MD5),
		}
		id.SelfSignature.PreferredCompression = []uint8{
			uint8(packet.CompressionNone),
		}
		err := id.SelfSignature.SignUserId(id.UserId.Id, e.PrimaryKey, e.PrivateKey, nil)
		if err != nil {
			return err
		}
	}

	f, err = os.Create(keyFileBase + ".key.asc")
	if err != nil {
		return err
	}
	defer f.Close()
	if err = f.Chmod(0600); err != nil {
		return err
	}
	w, err := armor.Encode(f, openpgp.PrivateKeyType, nil)
	if err != nil {
		return err
	}
	e.SerializePrivate(w, nil)
	w.Close()
	f.Write([]byte{'\n'})

	f, err = os.Create(keyFileBase + ".pub.asc")
	if err != nil {
		return err
	}
	defer f.Close()
	w, err = armor.Encode(f, openpgp.PublicKeyType, nil)
	if err != nil {
		return err
	}
	e.Serialize(w)
	w.Close()
	f.Write([]byte{'\n'})

	return nil
}
Exemple #21
0
Fichier : file.go Projet : vahe/lxd
func (c *fileCmd) pull(config *lxd.Config, args []string) error {
	if len(args) < 2 {
		return errArgs
	}

	target := args[len(args)-1]
	targetIsDir := false
	sb, err := os.Stat(target)
	if err != nil && !os.IsNotExist(err) {
		return err
	}

	/*
	 * If the path exists, just use it. If it doesn't exist, it might be a
	 * directory in one of three cases:
	 *   1. Someone explicitly put "/" at the end
	 *   2. Someone provided more than one source. In this case the target
	 *      should be a directory so we can save all the files into it.
	 *   3. We are dealing with recursive copy
	 */
	if err == nil {
		targetIsDir = sb.IsDir()
		if !targetIsDir && len(args)-1 > 1 {
			return fmt.Errorf(i18n.G("More than one file to download, but target is not a directory"))
		}
	} else if strings.HasSuffix(target, string(os.PathSeparator)) || len(args)-1 > 1 || c.recursive {
		if err := os.MkdirAll(target, 0755); err != nil {
			return err
		}
		targetIsDir = true
	}

	for _, f := range args[:len(args)-1] {
		pathSpec := strings.SplitN(f, "/", 2)
		if len(pathSpec) != 2 {
			return fmt.Errorf(i18n.G("Invalid source %s"), f)
		}

		remote, container := config.ParseRemoteAndContainer(pathSpec[0])
		d, err := lxd.NewClient(config, remote)
		if err != nil {
			return err
		}

		if c.recursive {
			if err := d.RecursivePullFile(container, pathSpec[1], target); err != nil {
				return err
			}

			continue
		}

		_, _, mode, type_, buf, _, err := d.PullFile(container, pathSpec[1])
		if err != nil {
			return err
		}

		if type_ == "directory" {
			return fmt.Errorf(i18n.G("can't pull a directory without --recursive"))
		}

		var targetPath string
		if targetIsDir {
			targetPath = path.Join(target, path.Base(pathSpec[1]))
		} else {
			targetPath = target
		}

		var f *os.File
		if targetPath == "-" {
			f = os.Stdout
		} else {
			f, err = os.Create(targetPath)
			if err != nil {
				return err
			}
			defer f.Close()

			err = f.Chmod(os.FileMode(mode))
			if err != nil {
				return err
			}
		}

		_, err = io.Copy(f, buf)
		if err != nil {
			return err
		}
	}

	return nil
}
Exemple #22
0
func TextEditor(inPath string, inContent []byte) ([]byte, error) {
	var f *os.File
	var err error
	var path string

	// Detect the text editor to use
	editor := os.Getenv("VISUAL")
	if editor == "" {
		editor = os.Getenv("EDITOR")
		if editor == "" {
			for _, p := range []string{"editor", "vi", "emacs", "nano"} {
				_, err := exec.LookPath(p)
				if err == nil {
					editor = p
					break
				}
			}
			if editor == "" {
				return []byte{}, fmt.Errorf("No text editor found, please set the EDITOR environment variable.")
			}
		}
	}

	if inPath == "" {
		// If provided input, create a new file
		f, err = ioutil.TempFile("", "lxd_editor_")
		if err != nil {
			return []byte{}, err
		}

		if err = f.Chmod(0600); err != nil {
			f.Close()
			os.Remove(f.Name())
			return []byte{}, err
		}

		f.Write(inContent)
		f.Close()

		path = f.Name()
		defer os.Remove(path)
	} else {
		path = inPath
	}

	cmdParts := strings.Fields(editor)
	cmd := exec.Command(cmdParts[0], append(cmdParts[1:], path)...)
	cmd.Stdin = os.Stdin
	cmd.Stdout = os.Stdout
	cmd.Stderr = os.Stderr
	err = cmd.Run()
	if err != nil {
		return []byte{}, err
	}

	content, err := ioutil.ReadFile(path)
	if err != nil {
		return []byte{}, err
	}

	return content, nil
}
Exemple #23
0
func (c *containerLXD) TemplateApply(trigger string) error {
	fname := path.Join(c.PathGet(""), "metadata.yaml")

	if !shared.PathExists(fname) {
		return nil
	}

	content, err := ioutil.ReadFile(fname)
	if err != nil {
		return err
	}

	metadata := new(imageMetadata)
	err = yaml.Unmarshal(content, &metadata)

	if err != nil {
		return fmt.Errorf("Could not parse %s: %v", fname, err)
	}

	for filepath, template := range metadata.Templates {
		var w *os.File

		found := false
		for _, tplTrigger := range template.When {
			if tplTrigger == trigger {
				found = true
				break
			}
		}

		if !found {
			continue
		}

		fullpath := shared.VarPath("containers", c.name, "rootfs", strings.TrimLeft(filepath, "/"))

		if shared.PathExists(fullpath) {
			w, err = os.Create(fullpath)
			if err != nil {
				return err
			}
		} else {
			uid := 0
			gid := 0
			if !c.IsPrivileged() {
				uid, gid = c.idmapset.ShiftIntoNs(0, 0)
			}
			shared.MkdirAllOwner(path.Dir(fullpath), 0755, uid, gid)

			w, err = os.Create(fullpath)
			if err != nil {
				return err
			}

			if !c.IsPrivileged() {
				w.Chown(uid, gid)
			}
			w.Chmod(0644)
		}

		tplString, err := ioutil.ReadFile(shared.VarPath("containers", c.name, "templates", template.Template))
		if err != nil {
			return err
		}

		tpl, err := pongo2.FromString("{% autoescape off %}" + string(tplString) + "{% endautoescape %}")
		if err != nil {
			return err
		}

		containerMeta := make(map[string]string)
		containerMeta["name"] = c.name
		containerMeta["architecture"], _ = shared.ArchitectureName(c.architecture)

		if c.ephemeral {
			containerMeta["ephemeral"] = "true"
		} else {
			containerMeta["ephemeral"] = "false"
		}

		if c.IsPrivileged() {
			containerMeta["privileged"] = "true"
		} else {
			containerMeta["privileged"] = "false"
		}

		configGet := func(confKey, confDefault *pongo2.Value) *pongo2.Value {
			val, ok := c.config[confKey.String()]
			if !ok {
				return confDefault
			}

			return pongo2.AsValue(strings.TrimRight(val, "\r\n"))
		}

		tpl.ExecuteWriter(pongo2.Context{"trigger": trigger,
			"path":       filepath,
			"container":  containerMeta,
			"config":     c.config,
			"devices":    c.devices,
			"properties": template.Properties,
			"config_get": configGet}, w)
	}

	return nil
}
// FIXME: I do 99% of the same thing as ssh/generate_authorized_keys
func generateAuthorizedKeys(repoId RepoIdentifier, u *user.User, forceCreate, printToStdOut bool) error {
	var err error
	var sshKeys []string
	var destFile *os.File
	var srcFile *os.File
	var w *bufio.Writer

	sshKeys, err = filepath.Glob(path.Join(repoId.SshAccessBasePath(), "*"))
	if err != nil {
		return err
	}

	if !printToStdOut {
		os.MkdirAll(repoId.HomePath(), 0700)
		os.Mkdir(path.Join(repoId.HomePath(), ".ssh"), 0700)
		authKeysPath := repoId.AuthKeysPathFor()
		if _, err = os.Stat(authKeysPath); err != nil {
			if !os.IsNotExist(err) {
				return err
			}
		} else {
			if forceCreate {
				os.Remove(authKeysPath)
			} else {
				return nil
			}
		}

		if destFile, err = os.Create(authKeysPath); err != nil {
			return err
		}
		defer destFile.Close()
		destFile.Chmod(0400)
		w = bufio.NewWriter(destFile)
	} else {
		w = bufio.NewWriter(os.Stdout)
	}

	for _, keyFile := range sshKeys {
		s, err := os.Stat(keyFile)
		if err != nil {
			continue
		}
		if s.IsDir() {
			continue
		}

		srcFile, err = os.Open(keyFile)
		defer srcFile.Close()

		readwriteRepo := strings.HasSuffix(keyFile, ".write")
		if readwriteRepo {
			w.WriteString("command=\"/usr/bin/switchns --git\",no-agent-forwarding,no-X11-forwarding,no-port-forwarding ")
		} else {
			w.WriteString("command=\"/usr/bin/switchns --git-ro\",no-agent-forwarding,no-X11-forwarding,no-port-forwarding ")
		}

		io.Copy(w, srcFile)
		w.WriteString("\n")
	}
	w.Flush()

	if !printToStdOut {
		uid, _ := strconv.Atoi(u.Uid)
		gid, _ := strconv.Atoi(u.Gid)

		for _, path := range []string{
			repoId.HomePath(),
			filepath.Join(repoId.HomePath(), ".ssh"),
			filepath.Join(repoId.HomePath(), ".ssh", "authorized_keys"),
		} {
			if err := os.Chown(path, uid, gid); err != nil {
				return err
			}
		}

		if err := selinux.RestoreCon(repoId.BaseHomePath(), true); err != nil {
			return err
		}
	}
	return nil
}
// NewKVMCoreOSFactory returns a new HostedProgramFactory that can create
// qemu-kvm/coreos virtual machines to run hosted programs.
func NewKVMCoreOSFactory(coreOSImage string, hashKvm bool) (factory HostedProgramFactory, err error) {

	// TODO(kwalsh) consoladate factory temp files into a single temp dir
	tempdir, err := ioutil.TempDir("", "cloudproxy_linux_host")
	if err != nil {
		return nil, err
	}
	defer func() {
		if err != nil {
			os.RemoveAll(tempdir)
		}
	}()
	if err = os.Chmod(tempdir, 0755); err != nil {
		return
	}

	var hash []byte
	if hashKvm {
		// Copy and hash the coreos image. This is expensive. Also, it doesn't
		// account for kvm images that have a backing image, so it isn't really
		// complete anyway. Hence, the coping and hashing is optional.
		temppath := path.Join(tempdir, "coreos.img")
		var tf *os.File
		tf, err = os.OpenFile(temppath, os.O_CREATE|os.O_RDWR, 0700)
		defer tf.Close()
		if err != nil {
			return
		}
		if err = tf.Chmod(0755); err != nil {
			return
		}

		var inf *os.File
		inf, err = os.Open(coreOSImage)
		defer inf.Close()
		if err != nil {
			return
		}

		// Read from the input file and write to the temp file.
		hasher := sha256.New()
		if _, err = io.Copy(hasher, io.TeeReader(inf, tf)); err != nil {
			return
		}
		hash = hasher.Sum(nil)
		coreOSImage = temppath
	} else {
		hash = []byte{0}
	}

	// Create a key to use to connect to the instance and set up LinuxHost
	// there.
	priv, err := rsa.GenerateKey(rand.Reader, 2048)
	if err != nil {
		return nil, err
	}
	sshpk, err := ssh.NewPublicKey(&priv.PublicKey)
	if err != nil {
		return nil, err
	}
	pkstr := "ssh-rsa " + base64.StdEncoding.EncodeToString(sshpk.Marshal()) + " linux_host"

	sshpriv, err := ssh.NewSignerFromKey(priv)
	if err != nil {
		return nil, err
	}

	return &KVMCoreOSFactory{
		CoreOSImage: coreOSImage,
		TempDir:     tempdir,
		CoreOSHash:  hash[:],
		PublicKey:   pkstr,
		PrivateKey:  sshpriv,
	}, nil
}