Exemple #1
0
// Update updates the files managed by the resource
func (f *File) Update() error {
	// Purge extra files
	if f.Purge {
		for name := range f.extra {
			dstFile := utils.NewFileUtil(name)
			f.Log("purging %s\n", name)
			if err := dstFile.Remove(); err != nil {
				return err
			}
		}
	}

	// Fix outdated files
	for _, item := range f.outdated {
		dstFile := utils.NewFileUtil(item.dst)

		// Update file content if needed
		if item.flags&flagOutdatedContent != 0 {
			// Create parent directory for file if missing
			dstDir := filepath.Dir(item.dst)
			_, err := os.Stat(dstDir)
			if os.IsNotExist(err) {
				if err := os.MkdirAll(dstDir, 0755); err != nil {
					return err
				}
			}

			srcFile := utils.NewFileUtil(item.src)
			srcMd5, err := srcFile.Md5()
			if err != nil {
				return err
			}

			f.Log("setting content of %s to md5:%s\n", item.dst, srcMd5)
			if err := dstFile.CopyFrom(item.src, true); err != nil {
				return err
			}
		}

		// Update permissions if needed
		if item.flags&flagOutdatedPermissions != 0 {
			f.Log("setting permissions of %s to %#o\n", item.dst, f.Mode)
			if err := dstFile.Chmod(f.Mode); err != nil {
				return err
			}
		}

		// Update ownership if needed
		if item.flags&flagOutdatedOwner != 0 {
			f.Log("setting owner of %s to %s:%s\n", item.dst, f.Owner, f.Group)
			if err := dstFile.SetOwner(f.Owner, f.Group); err != nil {
				return err
			}
		}
	}

	return nil
}
Exemple #2
0
// isOwnerOutdated returns a boolean indicating whether the
// file's owner managed by the resource is outdated compared to the
// ones defined by the resource.
// Each file identified as being out of date will be appended to the
// list of outdated files for the resource, so they can be further
// processed if needed.
func (f *File) isOwnerOutdated() (bool, error) {
	dstRegistry, err := directoryFileRegistry(f.Path, []string{})
	if err != nil {
		return false, err
	}

	isOutdated := false
	for name := range dstRegistry {
		// Skip extra files
		if _, ok := f.extra[dstRegistry[name]]; ok {
			continue
		}

		item := &outdatedFile{
			dst: dstRegistry[name],
		}
		item.flags |= flagOutdatedOwner
		dst := utils.NewFileUtil(dstRegistry[name])
		owner, err := dst.Owner()
		if err != nil {
			return false, err
		}

		if f.Owner != owner.User.Username || f.Group != owner.Group.Name {
			f.outdated = append(f.outdated, item)
			isOutdated = true
		}
	}

	return isOutdated, nil
}
Exemple #3
0
// isPermissionsOutdated returns a boolean indicating whether the
// file's permissions managed by the resource are outdated compared
// to the ones defined by the resource.
// Each file identified as being out of date will be appended to the
// list of outdated files for the resource, so they can be further
// processed if needed.
func (f *File) isPermissionsOutdated() (bool, error) {
	dstRegistry, err := directoryFileRegistry(f.Path, []string{})
	if err != nil {
		return false, err
	}

	isOutdated := false
	for name := range dstRegistry {
		// Skip extra files
		if _, ok := f.extra[dstRegistry[name]]; ok {
			continue
		}

		item := &outdatedFile{
			dst: dstRegistry[name],
		}
		item.flags |= flagOutdatedPermissions

		dst := utils.NewFileUtil(dstRegistry[name])
		mode, err := dst.Mode()
		if err != nil {
			return false, err
		}

		if mode.Perm() != f.Mode {
			f.outdated = append(f.outdated, item)
			isOutdated = true
		}
	}

	return isOutdated, nil
}
Exemple #4
0
// Create creates the file managed by the resource
func (f *File) Create() error {
	f.Log("creating resource\n")

	switch f.FileType {
	case fileTypeRegular:
		if err := f.createRegularFile(); err != nil {
			return err
		}

		dst := utils.NewFileUtil(f.Path)
		if err := dst.Chmod(f.Mode); err != nil {
			return err
		}
		if err := dst.SetOwner(f.Owner, f.Group); err != nil {
			return err
		}
	case fileTypeDirectory:
		if err := f.createDirectory(); err != nil {
			return err
		}

		dstRegistry, err := directoryFileRegistry(f.Path, []string{})
		if err != nil {
			return err
		}

		for _, path := range dstRegistry {
			dst := utils.NewFileUtil(path)
			if err := dst.Chmod(f.Mode); err != nil {
				return err
			}
			if err := dst.SetOwner(f.Owner, f.Group); err != nil {
				return err
			}
		}
	}

	return nil
}
Exemple #5
0
// NewPackage creates a new resource for managing packages.
// This provider tries to determine the most appropriate
// package provider for you, so it is more like a meta-provider.
//
// Example:
//   pkg = package.new("tmux")
//   pkg.state = "installed"
func NewPackage(name string) (Resource, error) {
	// Releases files used by the various GNU/Linux distros
	releases := map[string]Provider{
		"/etc/arch-release":   NewPacman,
		"/etc/centos-release": NewYum,
		"/etc/redhat-release": NewYum,
	}

	// Do our best to determine the proper provider
	for release, provider := range releases {
		dst := utils.NewFileUtil(release)
		if dst.Exists() {
			return provider(name)
		}
	}

	return nil, ErrNoPackageProviderFound
}
Exemple #6
0
// Validate validates the resource
func (f *File) Validate() error {
	if err := f.Base.Validate(); err != nil {
		return err
	}

	// Validate that we have a valid file type
	if f.FileType != fileTypeRegular && f.FileType != fileTypeDirectory {
		return fmt.Errorf("Invalid file type '%s'", f.FileType)
	}

	// If we have a source, ensure that it exists
	if f.Source != "" {
		dst := utils.NewFileUtil(filepath.Join(DefaultConfig.SiteRepo, f.Source))
		if !dst.Exists() {
			return fmt.Errorf("source file '%s' does not exist", f.Source)
		}
	}

	return nil
}
Exemple #7
0
// createRegularFile creates the file and content managed by the resource
func (f *File) createRegularFile() error {
	dst := utils.NewFileUtil(f.Path)

	switch {
	case f.Source != "":
		// We have a source file, use it
		srcPath := filepath.Join(DefaultConfig.SiteRepo, f.Source)
		if err := dst.CopyFrom(srcPath, false); err != nil {
			return err
		}
	case f.Source == "" && dst.Exists():
		// We have no source, do nothing
		break
	case f.Source == "" && !dst.Exists():
		// Create an empty file
		if _, err := os.Create(f.Path); err != nil {
			return err
		}
	}

	return nil
}