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 (_ *File) RenderLocal(t *local.LocalTarget, 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, fi.StringValue(e.Mode)) } if a != nil { if e.IfNotExists { glog.V(2).Infof("file exists and IfNotExists set; skipping %q", e.Path) return nil } } changed := false if e.Type == FileType_Symlink { if changes.Symlink != nil { // This will currently fail if the target already exists. // That's probably a good thing for now ... it is hard to know what to do here! glog.Infof("Creating symlink %q -> %q", e.Path, *changes.Symlink) err := os.Symlink(*changes.Symlink, e.Path) if err != nil { return fmt.Errorf("error creating symlink %q -> %q: %v", e.Path, *changes.Symlink, err) } changed = true } } else if e.Type == FileType_Directory { if a == nil { parent := filepath.Dir(strings.TrimSuffix(e.Path, "/")) err := os.MkdirAll(parent, dirMode) if err != nil { return fmt.Errorf("error creating parent directories %q: %v", parent, err) } err = os.MkdirAll(e.Path, fileMode) if err != nil { return fmt.Errorf("error creating directory %q: %v", e.Path, err) } changed = true } } else if e.Type == FileType_File { if changes.Contents != nil { err = fi.WriteFile(e.Path, e.Contents, fileMode, dirMode) if err != nil { return fmt.Errorf("error copying file %q: %v", e.Path, err) } changed = true } } else { return fmt.Errorf("File type=%q not valid/supported", e.Type) } if changes.Mode != nil { modeChanged, err := fi.EnsureFileMode(e.Path, fileMode) if err != nil { return fmt.Errorf("error changing mode on %q: %v", e.Path, err) } changed = changed || modeChanged } if changes.Owner != nil || changes.Group != nil { ownerChanged, err := fi.EnsureFileOwner(e.Path, fi.StringValue(e.Owner), fi.StringValue(e.Group)) if err != nil { return fmt.Errorf("error changing owner/group on %q: %v", e.Path, err) } changed = changed || ownerChanged } if changed && e.OnChangeExecute != nil { args := e.OnChangeExecute human := strings.Join(args, " ") glog.Infof("Changed; will execute OnChangeExecute command: %q", human) cmd := exec.Command(args[0], args[1:]...) output, err := cmd.CombinedOutput() if err != nil { return fmt.Errorf("error executing command %q: %v\nOutput: %s", human, err, output) } } return nil }