github.com/caos/orbos@v1.5.14-0.20221103111702-e6cd0cea7ad4/internal/operator/orbiter/kinds/providers/gce/gcemachine.go (about) 1 package gce 2 3 import ( 4 "bytes" 5 "errors" 6 "fmt" 7 "io" 8 "os" 9 "os/exec" 10 "strings" 11 12 "github.com/caos/orbos/internal/operator/orbiter/kinds/providers/ssh" 13 "github.com/caos/orbos/mntr" 14 ) 15 16 type gceMachine struct { 17 mntr.Monitor 18 id string 19 zone string 20 context *context 21 } 22 23 func newGCEMachine(context *context, monitor mntr.Monitor, id string, zone string) machine { 24 return &gceMachine{ 25 Monitor: monitor, 26 id: id, 27 zone: zone, 28 context: context, 29 } 30 } 31 32 func resetBuffer(buffer *bytes.Buffer) { 33 if buffer != nil { 34 buffer.Reset() 35 } 36 } 37 38 func (c *gceMachine) Zone() string { 39 return c.zone 40 } 41 42 func (c *gceMachine) Execute(stdin io.Reader, command string) ([]byte, error) { 43 buf, err := c.execute(stdin, command) 44 defer resetBuffer(buf) 45 if err != nil { 46 return nil, err 47 } 48 return buf.Bytes(), nil 49 } 50 51 func (c *gceMachine) execute(stdin io.Reader, command string) (outBuf *bytes.Buffer, err error) { 52 outBuf = new(bytes.Buffer) 53 errBuf := new(bytes.Buffer) 54 defer resetBuffer(errBuf) 55 56 gcloud, err := exec.LookPath("gcloud") 57 if err != nil { 58 return nil, err 59 } 60 61 if err := gcloudSession(c.context.desired.JSONKey.Value, gcloud, func(bin string) error { 62 cmd := exec.Command(gcloud, 63 "compute", 64 "ssh", 65 "--zone", c.zone, 66 fmt.Sprintf("orbiter@%s", c.id), 67 "--tunnel-through-iap", 68 "--project", c.context.projectID, 69 "--command", command, 70 ) 71 cmd.Stdin = stdin 72 cmd.Stdout = outBuf 73 cmd.Stderr = errBuf 74 if runErr := cmd.Run(); runErr != nil { 75 return errors.New(errBuf.String()) 76 } 77 return nil 78 }); err != nil { 79 return nil, err 80 } 81 return outBuf, nil 82 } 83 84 func (c *gceMachine) Shell() error { 85 errBuf := new(bytes.Buffer) 86 defer resetBuffer(errBuf) 87 88 gcloud, err := exec.LookPath("gcloud") 89 if err != nil { 90 return err 91 } 92 93 if err := gcloudSession(c.context.desired.JSONKey.Value, gcloud, func(bin string) error { 94 cmd := exec.Command(gcloud, 95 "compute", 96 "ssh", 97 "--zone", c.zone, 98 fmt.Sprintf("orbiter@%s", c.id), 99 "--tunnel-through-iap", 100 "--project", c.context.projectID, 101 ) 102 cmd.Stderr = os.Stderr 103 cmd.Stdin = os.Stdin 104 cmd.Stdout = os.Stdout 105 return cmd.Run() 106 }); err != nil { 107 return err 108 } 109 return nil 110 } 111 112 func (c *gceMachine) WriteFile(path string, data io.Reader, permissions uint16) error { 113 114 user, err := c.Execute(nil, "whoami") 115 if err != nil { 116 return err 117 } 118 119 mkdir, writeFile := ssh.WriteFileCommands(strings.TrimSpace(string(user)), path, permissions) 120 _, err = c.Execute(nil, mkdir) 121 if err != nil { 122 return err 123 } 124 125 _, err = c.Execute(data, writeFile) 126 return err 127 } 128 129 func (c *gceMachine) ReadFile(path string, data io.Writer) error { 130 buf, err := c.execute(nil, fmt.Sprintf("sudo cat %s", path)) 131 defer resetBuffer(buf) 132 if err != nil { 133 return err 134 } 135 136 _, err = io.Copy(data, buf) 137 return err 138 }