github.com/cloud-foundations/dominator@v0.0.0-20221004181915-6e4fee580046/cmd/installer/lib.go (about)

     1  // +build linux
     2  
     3  package main
     4  
     5  import (
     6  	"fmt"
     7  	"io"
     8  	"os"
     9  	"os/exec"
    10  	"path/filepath"
    11  	"strings"
    12  	"syscall"
    13  
    14  	"github.com/Cloud-Foundations/Dominator/lib/log"
    15  )
    16  
    17  type writeCloser struct{}
    18  
    19  func create(filename string) (io.WriteCloser, error) {
    20  	if *dryRun {
    21  		return &writeCloser{}, nil
    22  	}
    23  	return os.Create(filename)
    24  }
    25  
    26  func findExecutable(rootDir, file string) error {
    27  	if d, err := os.Stat(filepath.Join(rootDir, file)); err != nil {
    28  		return err
    29  	} else {
    30  		if m := d.Mode(); !m.IsDir() && m&0111 != 0 {
    31  			return nil
    32  		}
    33  		return os.ErrPermission
    34  	}
    35  }
    36  
    37  func lookPath(rootDir, file string) (string, error) {
    38  	if strings.Contains(file, "/") {
    39  		if err := findExecutable(rootDir, file); err != nil {
    40  			return "", err
    41  		}
    42  		return file, nil
    43  	}
    44  	path := os.Getenv("PATH")
    45  	for _, dir := range filepath.SplitList(path) {
    46  		if dir == "" {
    47  			dir = "." // Unix shell semantics: path element "" means "."
    48  		}
    49  		path := filepath.Join(dir, file)
    50  		if err := findExecutable(rootDir, path); err == nil {
    51  			return path, nil
    52  		}
    53  	}
    54  	return "", fmt.Errorf("(chroot=%s) %s not found in PATH", rootDir, file)
    55  }
    56  
    57  func run(name, chroot string, logger log.DebugLogger, args ...string) error {
    58  	if *dryRun {
    59  		logger.Debugf(0, "dry run: skipping: %s %s\n",
    60  			name, strings.Join(args, " "))
    61  		return nil
    62  	}
    63  	path, err := lookPath(chroot, name)
    64  	if err != nil {
    65  		return err
    66  	}
    67  	cmd := exec.Command(path, args...)
    68  	if chroot != "" {
    69  		cmd.Dir = "/"
    70  		cmd.SysProcAttr = &syscall.SysProcAttr{Chroot: chroot}
    71  		logger.Debugf(0, "running(chroot=%s): %s %s\n",
    72  			chroot, name, strings.Join(args, " "))
    73  	} else {
    74  		logger.Debugf(0, "running: %s %s\n", name, strings.Join(args, " "))
    75  	}
    76  	if output, err := cmd.CombinedOutput(); err != nil {
    77  		return fmt.Errorf("error running: %s: %s", name, output)
    78  	} else {
    79  		return nil
    80  	}
    81  }
    82  
    83  func (wc *writeCloser) Close() error {
    84  	return nil
    85  }
    86  
    87  func (wc *writeCloser) Write(p []byte) (int, error) {
    88  	return len(p), nil
    89  }