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.`