github.com/niedbalski/juju@v0.0.0-20190215020005-8ff100488e47/acceptancetests/repository/trusty/fill-logs/actions/actions.go (about)

     1  package main
     2  
     3  import (
     4  	"fmt"
     5  	"io"
     6  	"os"
     7  	"os/exec"
     8  	"path/filepath"
     9  	"strconv"
    10  	"strings"
    11  )
    12  
    13  func main() {
    14  	if err := run(os.Args); err != nil {
    15  		fmt.Fprintln(os.Stderr, err)
    16  		os.Exit(1)
    17  	}
    18  }
    19  
    20  func run(args []string) error {
    21  	if len(args) != 2 {
    22  		return fmt.Errorf("expected exactly one argument, the action name")
    23  	}
    24  	switch args[1] {
    25  	case "fill-unit":
    26  		return fillUnit()
    27  	case "fill-machine":
    28  		return fillMachine()
    29  	case "unit-size":
    30  		return unitLogSizes()
    31  	case "machine-size":
    32  		return machineLogSizes()
    33  	default:
    34  		return fmt.Errorf("unknown action: %q", args[1])
    35  	}
    36  }
    37  
    38  func fillUnit() error {
    39  	return fillLog(os.Stdout)
    40  }
    41  
    42  func unitLogSizes() error {
    43  	return writeSizes("/var/log/juju/unit-fill-logs*.log")
    44  }
    45  
    46  func machineLogSizes() error {
    47  	return writeSizes("/var/log/juju/machine-*.log")
    48  }
    49  
    50  func fillMachine() (err error) {
    51  	machine, err := getMachine()
    52  	if err != nil {
    53  		return err
    54  	}
    55  	svcname := fmt.Sprintf("jujud-machine-%d", machine)
    56  	out, err := exec.Command("service", svcname, "stop").CombinedOutput()
    57  	if err != nil {
    58  		return fmt.Errorf("error stopping machine agent %q: %s", svcname, out)
    59  	}
    60  	defer func() {
    61  		out, err2 := exec.Command("service", svcname, "start").CombinedOutput()
    62  		if err2 == nil {
    63  			return
    64  		}
    65  		if err == nil {
    66  			// function error is currently nil, so overwrite with this one.
    67  			err = fmt.Errorf("error starting machine agent %q: %s", svcname, out)
    68  			return
    69  		}
    70  		// function error is non-nil, so can't overwrite, just print.
    71  		fmt.Printf("error starting machine agent %q: %s", svcname, out)
    72  	}()
    73  	logname := fmt.Sprintf("/var/log/juju/machine-%d.log", machine)
    74  	f, err := os.OpenFile(logname, os.O_APPEND|os.O_WRONLY, 0644)
    75  	if err != nil {
    76  		return fmt.Errorf("failed to open machine log file: %v", err)
    77  	}
    78  	defer f.Close()
    79  	return fillLog(f)
    80  }
    81  
    82  func fillLog(w io.Writer) error {
    83  	megs, err := getMegs()
    84  	if err != nil {
    85  		return err
    86  	}
    87  	bytes := megs * 1024 * 1024
    88  	total := 0
    89  
    90  	for total < bytes {
    91  		// technically, the log file will be bigger than asked for, since it
    92  		// prepends a bunch of stuff to each log call, but this guarantees we've
    93  		// put *at least* this much data in the log, which should guarantee a
    94  		// rotation.
    95  		n, err := fmt.Fprintln(w, lorem)
    96  		if err != nil {
    97  			return fmt.Errorf("error writing to log: %s", err)
    98  		}
    99  		total += n
   100  	}
   101  	return nil
   102  }
   103  
   104  func writeSizes(glob string) error {
   105  	paths, err := filepath.Glob(glob)
   106  	if err != nil {
   107  		return fmt.Errorf("error getting logs for %q: %s", glob, err)
   108  	}
   109  
   110  	// go through the list in reverse, since the primary log file is always last,
   111  	// but it's a lot more convenient for parsing if it's first in the output.
   112  	for i, j := len(paths)-1, 0; i >= 0; i-- {
   113  		path := paths[i]
   114  		info, err := os.Stat(path)
   115  		if err != nil {
   116  			return fmt.Errorf("error stating log %q: %s", path, err)
   117  		}
   118  		name := fmt.Sprintf("result-map.log%d.name=%s", j, path)
   119  		size := fmt.Sprintf("result-map.log%d.size=%d", j, info.Size()/1024/1024)
   120  		out, err := exec.Command("action-set", name, size).CombinedOutput()
   121  		if err != nil {
   122  			return fmt.Errorf("error calling action-set: %s", out)
   123  		}
   124  		j++
   125  	}
   126  
   127  	return nil
   128  }
   129  
   130  func getMegs() (int, error) {
   131  	return getInt("megs")
   132  }
   133  
   134  func getMachine() (int, error) {
   135  	return getInt("machine")
   136  }
   137  
   138  func getInt(name string) (int, error) {
   139  	out, err := exec.Command("action-get", name).CombinedOutput()
   140  	if err != nil {
   141  		fmt.Fprintln(os.Stderr, out)
   142  		return 0, fmt.Errorf("error calling action-get: %s", err)
   143  	}
   144  	// for some reason the output always comes with a /n at the end, so just
   145  	// trim it.
   146  	return strconv.Atoi(strings.TrimSpace(string(out)))
   147  }
   148  
   149  const lorem = `Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum. Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum. Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum. Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.`