149 lines
3.3 KiB
Go
149 lines
3.3 KiB
Go
package runner
|
|
|
|
import (
|
|
"code.icod.de/dalu/gomanager/ent"
|
|
"context"
|
|
"fmt"
|
|
"io"
|
|
"os"
|
|
"os/exec"
|
|
"strings"
|
|
)
|
|
|
|
type Runner struct {
|
|
client *ent.Client
|
|
}
|
|
|
|
func NewRunner(client *ent.Client) *Runner {
|
|
r := new(Runner)
|
|
r.client = client
|
|
return r
|
|
}
|
|
|
|
// Run checks all projects sequentially
|
|
func (r *Runner) Run() error {
|
|
ms, e := r.client.Project.Query().All(context.Background())
|
|
if e != nil {
|
|
return fmt.Errorf("error querying projects: %s", e)
|
|
}
|
|
if len(ms) == 0 {
|
|
return nil
|
|
}
|
|
v, e := getCurrentGoVersion()
|
|
if e != nil {
|
|
return fmt.Errorf("error getting current go version: %s", e)
|
|
}
|
|
for _, m := range ms {
|
|
fv, e := getVersionOfFile(fmt.Sprintf("%s/%s", m.RootPath, m.BinaryPath))
|
|
if e != nil {
|
|
return fmt.Errorf("error getting version of file: %s", e)
|
|
}
|
|
if v != fv {
|
|
l, e := goBuildBinary(m.RootPath)
|
|
if e != nil {
|
|
return fmt.Errorf("error in goBuildBinary: %s", e)
|
|
}
|
|
_, e = r.client.Logentry.
|
|
Create().
|
|
SetContent(l).
|
|
Save(context.Background())
|
|
if e != nil {
|
|
return fmt.Errorf("error creating log entry: %s", e)
|
|
}
|
|
if m.MoveToTarget {
|
|
if fl, e := copyFile(
|
|
fmt.Sprintf("%s/%s", m.RootPath, m.BinaryPath),
|
|
fmt.Sprintf("%s/%s", m.RootPath, m.BinaryTargetPath),
|
|
); e != nil {
|
|
return fmt.Errorf("error copying file to target: %s", e)
|
|
} else {
|
|
_, e = r.client.Logentry.
|
|
Create().
|
|
SetContent(fl).
|
|
Save(context.Background())
|
|
if e != nil {
|
|
return fmt.Errorf("error saving log entry: %s", e)
|
|
}
|
|
}
|
|
} else {
|
|
if e := chownBinary(m.User, m.Group, fmt.Sprintf("%s/%s", m.RootPath, m.BinaryPath)); e != nil {
|
|
return fmt.Errorf("error chowning binary: %s", e)
|
|
}
|
|
}
|
|
|
|
}
|
|
}
|
|
return nil
|
|
}
|
|
|
|
// getCurrentGoVersion returns the version of the installed go package or a non-nil error
|
|
func getCurrentGoVersion() (string, error) {
|
|
cmd := exec.Command("go", "version")
|
|
var out strings.Builder
|
|
cmd.Stdout = &out
|
|
if e := cmd.Run(); e != nil {
|
|
return "", e
|
|
}
|
|
split := strings.Split(out.String(), " ")
|
|
version := split[2]
|
|
return version, nil
|
|
}
|
|
|
|
// getVersionOfFile returns the version of a go binary or an non-nil error
|
|
func getVersionOfFile(file string) (string, error) {
|
|
cmd := exec.Command("go", "version", file)
|
|
var out strings.Builder
|
|
cmd.Stdout = &out
|
|
if e := cmd.Run(); e != nil {
|
|
return "", e
|
|
}
|
|
split := strings.Split(out.String(), " ")
|
|
version := split[1]
|
|
return version, nil
|
|
}
|
|
|
|
// goBuildBinary does a go build in the root directory, then "cd"s back to the previous working directory.
|
|
func goBuildBinary(root string) (string, error) {
|
|
cwd, e := os.Getwd()
|
|
if e != nil {
|
|
return "", e
|
|
}
|
|
if e := os.Chdir(root); e != nil {
|
|
return "", e
|
|
}
|
|
|
|
cmd := exec.Command("go", "build")
|
|
var out strings.Builder
|
|
cmd.Stdout = &out
|
|
if e := cmd.Run(); e != nil {
|
|
return "", e
|
|
}
|
|
if e := os.Chdir(cwd); e != nil {
|
|
return "", e
|
|
}
|
|
return out.String(), nil
|
|
}
|
|
|
|
func chownBinary(user, group, file string) error {
|
|
cmd := exec.Command("chown", fmt.Sprintf("%s:%s", user, group), file)
|
|
return cmd.Run()
|
|
}
|
|
|
|
func copyFile(src, dst string) (string, error) {
|
|
srcF, e := os.Open(src)
|
|
if e != nil {
|
|
return "", e
|
|
}
|
|
defer srcF.Close()
|
|
dstF, e := os.Open(dst)
|
|
if e != nil {
|
|
return "", e
|
|
}
|
|
defer dstF.Close()
|
|
if size, e := io.Copy(dstF, srcF); e != nil {
|
|
return "", e
|
|
} else {
|
|
return fmt.Sprintf("copied %d bytes from %s to %s", size, src, dst), nil
|
|
}
|
|
}
|