Dodo APP: infrastructure to deploy app by pusing to Git repo
Change-Id: I4034c6893255581b014ddb207c844261cb34202b
diff --git a/apps/app-runner/main.go b/apps/app-runner/main.go
new file mode 100644
index 0000000..fb17415
--- /dev/null
+++ b/apps/app-runner/main.go
@@ -0,0 +1,80 @@
+package main
+
+import (
+ "encoding/json"
+ "flag"
+ "fmt"
+ "net"
+ "os"
+
+ "golang.org/x/crypto/ssh"
+
+ "github.com/go-git/go-billy/v5/osfs"
+ "github.com/go-git/go-git/v5"
+ gitssh "github.com/go-git/go-git/v5/plumbing/transport/ssh"
+ "github.com/go-git/go-git/v5/storage/memory"
+)
+
+var port = flag.Int("port", 3000, "Port to listen on")
+var repoAddr = flag.String("repo-addr", "", "Git repository address")
+var sshKey = flag.String("ssh-key", "", "Private SSH key to access Git repository")
+var appDir = flag.String("app-dir", "", "Path to store application repository locally")
+var runCfg = flag.String("run-cfg", "", "Run configuration")
+var manager = flag.String("manager", "", "Address of the manager")
+
+type Command struct {
+ Bin string `json:"bin"`
+ Args []string `json:"args"`
+}
+
+func CloneRepository(addr string, signer ssh.Signer, path string) error {
+ _, err := git.Clone(memory.NewStorage(), osfs.New(path, osfs.WithBoundOS()), &git.CloneOptions{
+ URL: addr,
+ Auth: &gitssh.PublicKeys{
+ User: "git",
+ Signer: signer,
+ HostKeyCallbackHelper: gitssh.HostKeyCallbackHelper{
+ HostKeyCallback: func(hostname string, remote net.Addr, key ssh.PublicKey) error {
+ // TODO(giolekva): verify server public key
+ fmt.Printf("--- %+v\n", ssh.MarshalAuthorizedKey(key))
+ return nil
+ },
+ },
+ },
+ RemoteName: "origin",
+ ReferenceName: "refs/heads/master",
+ Depth: 1,
+ InsecureSkipTLS: true,
+ })
+ return err
+}
+
+func main() {
+ flag.Parse()
+ self, ok := os.LookupEnv("SELF_IP")
+ if !ok {
+ panic("no SELF_IP")
+ }
+ key, err := os.ReadFile(*sshKey)
+ if err != nil {
+ panic(err)
+ }
+ signer, err := ssh.ParsePrivateKey(key)
+ if err != nil {
+ panic(err)
+ }
+ if err := CloneRepository(*repoAddr, signer, *appDir); err != nil {
+ panic(err)
+ }
+ r, err := os.Open(*runCfg)
+ if err != nil {
+ panic(err)
+ }
+ defer r.Close()
+ var cmds []Command
+ if err := json.NewDecoder(r).Decode(&cmds); err != nil {
+ panic(err)
+ }
+ s := NewServer(*port, *repoAddr, signer, *appDir, cmds, self, *manager)
+ s.Start()
+}