AppRunner: Reports detailed status
Status includes: commit hash, running commands and logs
Change-Id: I5f28f69710b30508bb3296a22fc97b9ad7553844
diff --git a/apps/app-runner/Makefile b/apps/app-runner/Makefile
index 86ec333..187ca18 100644
--- a/apps/app-runner/Makefile
+++ b/apps/app-runner/Makefile
@@ -16,6 +16,11 @@
clean:
rm -f app-runner
+build: export CGO_ENABLED=0
+build: export GO111MODULE=on
+build: clean
+ /usr/local/go/bin/go build -o app-runner *.go
+
build_arm64: export CGO_ENABLED=0
build_arm64: export GO111MODULE=on
build_arm64: export GOOS=linux
diff --git a/apps/app-runner/main.go b/apps/app-runner/main.go
index 9c57225..b9acaa6 100644
--- a/apps/app-runner/main.go
+++ b/apps/app-runner/main.go
@@ -35,7 +35,7 @@
Env []string `json:"env"`
}
-func CloneRepositoryBranch(addr, branch, rootDir string, signer ssh.Signer, path string) error {
+func CloneRepositoryBranch(addr, branch, rootDir string, signer ssh.Signer, path string) (string, error) {
ref := fmt.Sprintf("refs/heads/%s", branch)
opts := &git.CloneOptions{
URL: addr,
@@ -61,29 +61,13 @@
}
c, err := git.Clone(memory.NewStorage(), osfs.New(path, osfs.WithBoundOS()), opts)
if err != nil {
- return err
+ return "", err
}
- wt, err := c.Worktree()
+ head, err := c.Head()
if err != nil {
- return err
+ return "", err
}
- if wt == nil {
- panic(wt)
- }
- // TODO(gio): This should probably be removed.
- // sb, err := wt.Submodules()
- // if err != nil {
- // return err
- // }
- // if err := sb.Init(); err != nil {
- // return err
- // }
- // if err := sb.Update(&git.SubmoduleUpdateOptions{
- // Depth: 1,
- // }); err != nil {
- // return err
- // }
- return err
+ return head.Hash().String(), nil
}
func main() {
@@ -92,6 +76,10 @@
if !ok {
panic("no SELF_IP")
}
+ id, ok := os.LookupEnv("SELF_ID")
+ if !ok {
+ panic("no SELF_ID")
+ }
var signer ssh.Signer
// TODO(gio): revisit this logic
if *sshKey != "" && !(strings.HasPrefix(*repoAddr, "http://") || strings.HasPrefix(*repoAddr, "https://")) {
@@ -104,7 +92,7 @@
panic(err)
}
}
- if err := CloneRepositoryBranch(*repoAddr, *branch, *rootDir, signer, *appDir); err != nil {
+ if err := os.Mkdir(*appDir, os.ModePerm); err != nil {
panic(err)
}
r, err := os.Open(*runCfg)
@@ -116,7 +104,7 @@
if err := json.NewDecoder(r).Decode(&cmds); err != nil {
panic(err)
}
- s := NewServer(*port, *appId, *service, *repoAddr, *branch, *rootDir, signer, *appDir, cmds, self, *managerAddr)
+ s := NewServer(*port, *appId, *service, id, *repoAddr, *branch, *rootDir, signer, *appDir, cmds, self, *managerAddr)
if err := s.Start(); err != nil {
log.Fatal(err)
}
diff --git a/apps/app-runner/server.go b/apps/app-runner/server.go
index 83bcac4..1661731 100644
--- a/apps/app-runner/server.go
+++ b/apps/app-runner/server.go
@@ -17,11 +17,25 @@
"golang.org/x/crypto/ssh"
)
+type CommandState string
+
+type CommandStatus struct {
+ Command string `json:"command"`
+ State CommandState `json:"state"`
+}
+
+type Status struct {
+ RepoOK bool `json:"repoOK"`
+ Commit string `json:"commit"`
+ Commands []CommandStatus `json:"commands"`
+}
+
type Server struct {
l sync.Locker
port int
appId string
service string
+ id string
ready bool
cmd *exec.Cmd
repoAddr string
@@ -34,15 +48,17 @@
managerAddr string
logs *Log
currDir string
+ status *Status
}
-func NewServer(port int, appId, service, repoAddr, branch, rootDir string, signer ssh.Signer, appDir string, runCommands []Command, self string, manager string) *Server {
+func NewServer(port int, appId, service, id, repoAddr, branch, rootDir string, signer ssh.Signer, appDir string, runCommands []Command, self string, manager string) *Server {
return &Server{
l: &sync.Mutex{},
port: port,
ready: false,
appId: appId,
service: service,
+ id: id,
repoAddr: repoAddr,
branch: branch,
rootDir: rootDir,
@@ -53,6 +69,7 @@
managerAddr: manager,
logs: &Log{},
currDir: "",
+ status: nil,
}
}
@@ -102,23 +119,45 @@
if err != nil {
return err
}
- if err := CloneRepositoryBranch(s.repoAddr, s.branch, s.rootDir, s.signer, newDir); err != nil {
+ commit, err := CloneRepositoryBranch(s.repoAddr, s.branch, s.rootDir, s.signer, newDir)
+ if err != nil {
+ s.status = &Status{
+ RepoOK: false,
+ }
return err
}
- logM := io.MultiWriter(os.Stdout, s.logs)
- for i, c := range s.runCommands {
+ s.status = &Status{
+ RepoOK: true,
+ Commit: commit,
+ Commands: []CommandStatus{},
+ }
+ commands := []string{}
+ for _, c := range s.runCommands {
args := []string{c.Bin}
args = append(args, c.Args...)
+ cmd := strings.Join(args, " ")
+ commands = append(commands, cmd)
+ s.status.Commands = append(s.status.Commands, CommandStatus{
+ Command: cmd,
+ State: "waiting",
+ })
+ }
+ logM := io.MultiWriter(os.Stdout, s.logs)
+ for i, c := range commands {
+ if i > 0 {
+ s.status.Commands[i-1].State = "success"
+ }
cmd := &exec.Cmd{
Dir: filepath.Join(newDir, s.rootDir),
Path: "/bin/sh",
- Args: []string{"/bin/sh", "-c", strings.Join(args, " ")},
- Env: append(os.Environ(), c.Env...),
+ Args: []string{"/bin/sh", "-c", c},
+ Env: append(os.Environ(), s.runCommands[i].Env...),
Stdout: logM,
Stderr: logM,
}
cmd.SysProcAttr = &syscall.SysProcAttr{Setpgid: true}
- fmt.Printf("Running: %s %s\n", c.Bin, c.Args)
+ fmt.Printf("Running: %s\n", c)
+ s.status.Commands[i].State = "running"
if i < len(s.runCommands)-1 {
if err := cmd.Run(); err != nil {
return err
@@ -129,8 +168,10 @@
if err := s.kill(); err != nil {
return err
}
- if err := os.RemoveAll(s.currDir); err != nil {
- return err
+ if s.currDir != "" {
+ if err := os.RemoveAll(s.currDir); err != nil {
+ return err
+ }
}
}
if err := cmd.Start(); err != nil {
@@ -144,9 +185,11 @@
}
type pingReq struct {
- Service string `json:"service"`
- Address string `json:"address"`
- Logs string `json:"logs"`
+ Id string `json:"id"`
+ Service string `json:"service"`
+ Address string `json:"address"`
+ Status *Status `json:"status,omitempty"`
+ Logs string `json:"logs"`
}
func (s *Server) pingManager() {
@@ -157,8 +200,10 @@
}()
}()
buf, err := json.Marshal(pingReq{
+ Id: s.id,
Service: s.service,
Address: fmt.Sprintf("http://%s:%d", s.self, s.port),
+ Status: s.status,
Logs: s.logs.Contents(),
})
if err != nil {
diff --git a/charts/app-runner/Chart.yaml b/charts/app-runner/Chart.yaml
index 0edd283..d72f597 100644
--- a/charts/app-runner/Chart.yaml
+++ b/charts/app-runner/Chart.yaml
@@ -2,5 +2,5 @@
name: app-runner
description: A Helm chart for PCloud App Runner
type: application
-version: 0.0.4
-appVersion: "0.0.4"
+version: 0.0.5
+appVersion: "0.0.5"
diff --git a/charts/app-runner/templates/install.yaml b/charts/app-runner/templates/install.yaml
index 8a1a8c7..52b8495 100644
--- a/charts/app-runner/templates/install.yaml
+++ b/charts/app-runner/templates/install.yaml
@@ -98,6 +98,10 @@
{{ toYaml .Values.appPorts | nindent 8 }}
{{- end }}
env:
+ - name: SELF_ID
+ valueFrom:
+ fieldRef:
+ fieldPath: metadata.name
- name: SELF_IP
valueFrom:
fieldRef: