func (_ *File) RenderCloudInit(t *cloudinit.CloudInitTarget, a, e, changes *File) error { dirMode := os.FileMode(0755) fileMode, err := fi.ParseFileMode(fi.StringValue(e.Mode), 0644) if err != nil { return fmt.Errorf("invalid file mode for %q: %q", e.Path, e.Mode) } if e.Type == FileType_Symlink { t.AddCommand(cloudinit.Always, "ln", "-s", fi.StringValue(e.Symlink), e.Path) } else if e.Type == FileType_Directory { parent := filepath.Dir(strings.TrimSuffix(e.Path, "/")) t.AddCommand(cloudinit.Once, "mkdir", "-p", "-m", fi.FileModeToString(dirMode), parent) t.AddCommand(cloudinit.Once, "mkdir", "-m", fi.FileModeToString(dirMode), e.Path) } else if e.Type == FileType_File { err = t.WriteFile(e.Path, e.Contents, fileMode, dirMode) if err != nil { return err } } else { return fmt.Errorf("File type=%q not valid/supported", e.Type) } if e.Owner != nil || e.Group != nil { t.Chown(e.Path, fi.StringValue(e.Owner), fi.StringValue(e.Group)) } if e.OnChangeExecute != nil { t.AddCommand(cloudinit.Always, e.OnChangeExecute...) } return nil }
func (t *CloudInitTarget) WriteFile(destPath string, contents fi.Resource, fileMode os.FileMode, dirMode os.FileMode) error { var p *fi.Source if hs, ok := contents.(fi.HasSource); ok { p = hs.GetSource() } if p != nil { t.AddMkdirpCommand(path.Dir(destPath), dirMode) t.fetch(p, destPath) } else { // TODO: No way to specify parent dir permissions? f := &CloudConfigFile{ Encoding: "b64", Owner: "root:root", Permissions: fi.FileModeToString(fileMode), Path: destPath, } d, err := fi.ResourceAsBytes(contents) if err != nil { return err } // Not a strict limit, just a sanity check if len(d) > 256*1024 { return fmt.Errorf("resource is very large (failed sanity-check): %v", contents) } f.Content = base64.StdEncoding.EncodeToString(d) t.Config.WriteFiles = append(t.Config.WriteFiles, f) } return nil }
func findFile(p string) (*File, error) { stat, err := os.Lstat(p) if err != nil { if os.IsNotExist(err) { return nil, nil } } actual := &File{} actual.Path = p actual.Mode = fi.String(fi.FileModeToString(stat.Mode() & os.ModePerm)) uid := int(stat.Sys().(*syscall.Stat_t).Uid) owner, err := fi.LookupUserById(uid) if err != nil { return nil, err } if owner != nil { actual.Owner = fi.String(owner.Name) } else { actual.Owner = fi.String(strconv.Itoa(uid)) } gid := int(stat.Sys().(*syscall.Stat_t).Gid) group, err := fi.LookupGroupById(gid) if err != nil { return nil, err } if group != nil { actual.Group = fi.String(group.Name) } else { actual.Group = fi.String(strconv.Itoa(gid)) } if (stat.Mode() & os.ModeSymlink) != 0 { target, err := os.Readlink(p) if err != nil { return nil, fmt.Errorf("error reading symlink target: %v", err) } actual.Type = FileType_Symlink actual.Symlink = fi.String(target) } else if (stat.Mode() & os.ModeDir) != 0 { actual.Type = FileType_Directory } else { actual.Type = FileType_File actual.Contents = fi.NewFileResource(p) } return actual, nil }
func (t *CloudInitTarget) AddMkdirpCommand(p string, dirMode os.FileMode) { t.AddCommand(Once, "mkdir", "-p", "-m", fi.FileModeToString(dirMode), p) }