func verifyUnitAction(c *cli.Context) { r := getRegistry() if len(c.Args()) != 1 { fmt.Println("One unit file must be provided.") syscall.Exit(1) } name := path.Base(c.Args()[0]) payload := r.GetPayload(name) if payload == nil { fmt.Println("Job not found.") syscall.Exit(1) } sv, err := sign.NewSignatureVerifierFromSSHAgent() if err != nil { fmt.Println("Fail to create SignatureVerifier:", err) return } s := r.GetSignatureSetOfPayload(name) ok, err := sv.VerifyPayload(payload, s) if !ok || err != nil { fmt.Printf("Check of payload %s failed: %v\n", payload.Name, err) return } fmt.Printf("Succeed to verify job(%s).\n", payload.Name) }
func listMachinesAction(c *cli.Context) { if !c.Bool("no-legend") { fmt.Fprintln(out, "MACHINE\tIP\tMETADATA") } full := c.Bool("full") for _, m := range registryCtl.GetActiveMachines() { mach := machineBootIDLegend(m, full) ip := m.PublicIP if len(ip) == 0 { ip = "-" } metadata := "-" if len(m.Metadata) != 0 { metadata = formatMetadata(m.Metadata) } fmt.Fprintf(out, "%s\t%s\t%s\n", mach, ip, metadata) } out.Flush() }
func listMachinesAction(c *cli.Context) { r := getRegistry(c) if !c.Bool("no-legend") { fmt.Fprintln(out, "MACHINE\tIP\tMETADATA") } full := c.Bool("full") for _, m := range r.GetActiveMachines() { mach := m.BootId if !full { mach = ellipsize(mach, 8) } ip := m.PublicIP if len(ip) == 0 { ip = "-" } metadata := "-" if len(m.Metadata) != 0 { metadata = formatMetadata(m.Metadata) } fmt.Fprintf(out, "%s\t%s\t%s\n", mach, ip, metadata) } out.Flush() }
func getTunnelFlag(context *cli.Context) string { tun := context.GlobalString("tunnel") if tun != "" && !strings.Contains(tun, ":") { tun += ":22" } return tun }
func listUnitsAction(c *cli.Context) { r := getRegistry(c) if !c.Bool("no-legend") { fmt.Fprintln(out, "UNIT\tLOAD\tACTIVE\tSUB\tDESC\tMACHINE") } names := make(map[string]bool, 0) sortable := make(sort.StringSlice, 0) for _, p := range r.GetAllPayloads() { if _, ok := names[p.Name]; !ok { names[p.Name] = true sortable = append(sortable, p.Name) } } for _, j := range r.GetAllJobs() { if _, ok := names[j.Name]; !ok { names[j.Name] = true sortable = append(sortable, j.Name) } } sortable.Sort() full := c.Bool("full") for _, name := range sortable { state := r.GetJobState(name) printJobState(name, state, full) } out.Flush() }
func getRegistry(context *cli.Context) *registry.Registry { tun := getTunnelFlag(context) endpoint := context.GlobalString("endpoint") machines := []string{endpoint} client := etcd.NewClient(machines) if tun != "" { sshClient, err := ssh.NewSSHClient("core", tun) if err != nil { panic(err) } dial := func(network, addr string) (net.Conn, error) { tcpaddr, err := net.ResolveTCPAddr(network, addr) if err != nil { return nil, err } return sshClient.DialTCP(network, nil, tcpaddr) } tr := http.Transport{ Dial: dial, TLSClientConfig: &tls.Config{ InsecureSkipVerify: true, }, } client.SetTransport(&tr) } return registry.New(client) }
func stopUnitAction(c *cli.Context) { r := getRegistry() for _, v := range c.Args() { name := path.Base(v) r.StopJob(name) } }
func destroyUnitsAction(c *cli.Context) { for _, v := range c.Args() { name := path.Base(v) registryCtl.StopJob(name) registryCtl.DestroyPayload(name) registryCtl.DestroySignatureSetOfPayload(name) } }
func destroyUnitsAction(c *cli.Context) { r := getRegistry() for _, v := range c.Args() { name := path.Base(v) r.StopJob(name) r.DestroyPayload(name) } }
func statusUnitsAction(c *cli.Context) { for i, v := range c.Args() { // This extra newline here to match systemctl status output if i != 0 { fmt.Printf("\n") } name := path.Base(v) printUnitStatus(c, name) } }
func journalAction(c *cli.Context) { if len(c.Args()) != 1 { fmt.Println("One unit file must be provided.") syscall.Exit(1) } jobName := c.Args()[0] js := registryCtl.GetJobState(jobName) if js == nil { fmt.Printf("%s does not appear to be running\n", jobName) syscall.Exit(1) } cmd := fmt.Sprintf("journalctl -u %s --no-pager -l -n %d", jobName, c.Int("lines")) if c.Bool("follow") { cmd += " -f" } // check if the job is running on this machine var channel *ssh.Channel var err error if machine.IsLocalMachineState(js.MachineState) { channel = runLocalCommand(cmd) } else { channel, err = runRemoteCommand(cmd, js.MachineState.PublicIP) if err != nil { log.Fatalf("Unable to run command over SSH: %v", err) } } readSSHChannel(channel) }
func sshAction(c *cli.Context) { unit := c.String("unit") machine := c.String("machine") if unit != "" && machine != "" { log.Fatal("Both flags, machine and unit provided, please specify only one") } args := c.Args() var err error var addr string switch { case machine != "": addr, _ = findAddressInMachineList(machine) case unit != "": addr, _ = findAddressInRunningUnits(unit) default: addr, err = globalMachineLookup(args) args = args[1:] } if err != nil { log.Fatal(err) } if addr == "" { log.Fatalf("Requested machine could not be found") } agentForwarding := c.Bool("agent") var sshClient *ssh.SSHForwardingClient if tun := getTunnelFlag(); tun != "" { sshClient, err = ssh.NewTunnelledSSHClient("core", tun, addr, getChecker(), agentForwarding) } else { sshClient, err = ssh.NewSSHClient("core", addr, getChecker(), agentForwarding) } if err != nil { log.Fatal(err.Error()) return } defer sshClient.Close() if len(args) > 0 { cmd := strings.Join(args, " ") channel, err := ssh.Execute(sshClient, cmd) if err != nil { log.Fatalf("Unable to run command over SSH: %s", err.Error()) } readSSHChannel(channel) } else { if err := ssh.Shell(sshClient); err != nil { log.Fatalf(err.Error()) } } }
func printUnitAction(c *cli.Context) { if len(c.Args()) != 1 { fmt.Println("One unit file must be provided.") syscall.Exit(1) } name := path.Base(c.Args()[0]) payload := registryCtl.GetPayload(name) if payload == nil { fmt.Println("Job not found.") syscall.Exit(1) } fmt.Print(payload.Unit.String()) }
func listUnitsAction(c *cli.Context) { if !c.Bool("no-legend") { fmt.Fprintln(out, "UNIT\tLOAD\tACTIVE\tSUB\tDESC\tMACHINE") } names, sortable := findAllUnits() full := c.Bool("full") for _, name := range sortable { state := registryCtl.GetJobState(name) description := names[name] printJobState(name, description, state, full) } out.Flush() }
func journalAction(c *cli.Context) { if len(c.Args()) != 1 { fmt.Println("One unit file must be provided.") syscall.Exit(1) } jobName := c.Args()[0] js := registryCtl.GetJobState(jobName) if js == nil { fmt.Printf("%s does not appear to be running\n", jobName) syscall.Exit(1) } addr := fmt.Sprintf("%s:22", js.MachineState.PublicIP) var err error var sshClient *gossh.ClientConn if tun := getTunnelFlag(); tun != "" { sshClient, err = ssh.NewTunnelledSSHClient("core", tun, addr) } else { sshClient, err = ssh.NewSSHClient("core", addr) } if err != nil { log.Fatal(err.Error()) } defer sshClient.Close() cmd := fmt.Sprintf("journalctl -u %s --no-pager -l -n %d", jobName, c.Int("lines")) if c.Bool("follow") { cmd += " -f" } stdout, err := ssh.Execute(sshClient, cmd) if err != nil { log.Fatalf("Unable to run command over SSH: %s", err.Error()) } for true { bytes, prefix, err := stdout.ReadLine() if err != nil { break } fmt.Print(string(bytes)) if !prefix { fmt.Print("\n") } } }
func listUnitsAction(c *cli.Context) { r := getRegistry() if !c.Bool("no-legend") { fmt.Fprintln(out, "UNIT\tLOAD\tACTIVE\tSUB\tDESC\tMACHINE") } names := make(map[string]string, 0) sortable := make(sort.StringSlice, 0) for _, p := range r.GetAllPayloads() { if _, ok := names[p.Name]; !ok { names[p.Name] = p.Unit.Description() sortable = append(sortable, p.Name) } } for _, j := range r.GetAllJobs() { if _, ok := names[j.Name]; !ok { var description string if j.Payload != nil { description = j.Payload.Unit.Description() } names[j.Name] = description sortable = append(sortable, j.Name) } } sortable.Sort() full := c.Bool("full") for _, name := range sortable { state := r.GetJobState(name) description := names[name] printJobState(name, description, state, full) } out.Flush() }
func submitUnitsAction(c *cli.Context) { r := getRegistry(c) // First, validate each of the provided payloads payloads := make([]job.JobPayload, len(c.Args())) for i, v := range c.Args() { payload, err := getJobPayloadFromFile(v) if err != nil { fmt.Println(err.Error()) return } payloads[i] = *payload } // Only after all the provided payloads have been validated // do we push any changes to the Registry for _, payload := range payloads { err := r.CreatePayload(&payload) if err != nil { fmt.Printf("Creation of payload %s failed: %v\n", payload.Name, err) return } } }
func submitUnitsAction(c *cli.Context) { toSign := c.Bool("sign") var sc *sign.SignatureCreator if toSign { var err error sc, err = sign.NewSignatureCreatorFromSSHAgent() if err != nil { fmt.Println("Fail to create SignatureVerifier:", err) return } } // First, validate each of the provided payloads payloads := make([]job.JobPayload, len(c.Args())) for i, v := range c.Args() { payload, err := getJobPayloadFromFile(v) if err != nil { fmt.Println(err.Error()) return } payloads[i] = *payload } // Only after all the provided payloads have been validated // do we push any changes to the Registry for _, payload := range payloads { err := registryCtl.CreatePayload(&payload) if err != nil { fmt.Printf("Creation of payload %s failed: %v\n", payload.Name, err) return } if toSign { s, err := sc.SignPayload(&payload) if err != nil { fmt.Printf("Creation of sign for payload %s failed: %v\n", payload.Name, err) return } registryCtl.CreateSignatureSet(s) } } }
func startUnitAction(c *cli.Context) { var err error r := getRegistry() payloads := make([]job.JobPayload, len(c.Args())) for i, v := range c.Args() { name := path.Base(v) payload := r.GetPayload(name) if payload == nil { payload, err = getJobPayloadFromFile(v) if err != nil { fmt.Println(err.Error()) return } err = r.CreatePayload(payload) if err != nil { fmt.Printf("Creation of payload %s failed: %v\n", payload.Name, err) return } } payloads[i] = *payload } requirements := parseRequirements(c.String("require")) // TODO: This must be done in a transaction! for _, jp := range payloads { j := job.NewJob(jp.Name, requirements, &jp, nil) err := r.CreateJob(j) if err != nil { fmt.Printf("Creation of job %s failed: %v\n", j.Name, err) } } }
func stopUnitAction(c *cli.Context) { for _, v := range c.Args() { name := path.Base(v) registryCtl.StopJob(name) } }
func sshAction(c *cli.Context) { r := getRegistry(c) args := c.Args() unit := c.String("unit") if len(args) == 0 && unit == "" { log.Fatalf("Provide one machine or unit") } var addr string if unit == "" { lookup := args[0] args = args[1:] states := r.GetActiveMachines() var match *machine.MachineState for i, _ := range states { machState := states[i] if !strings.HasPrefix(machState.BootId, lookup) { continue } else if match != nil { log.Fatalf("Found more than one Machine, be more specfic") } match = &machState } if match == nil { log.Fatalf("Could not find provided Machine") } addr = fmt.Sprintf("%s:22", match.PublicIP) } else { js := r.GetJobState(unit) if js == nil { log.Fatalf("Requested unit %s does not appear to be running", unit) } addr = fmt.Sprintf("%s:22", js.MachineState.PublicIP) } var err error var sshClient *gossh.ClientConn if tun := getTunnelFlag(c); tun != "" { sshClient, err = ssh.NewTunnelledSSHClient("core", tun, addr) } else { sshClient, err = ssh.NewSSHClient("core", addr) } if err != nil { log.Fatalf("Unable to establish SSH connection: %v", err) return } defer sshClient.Close() if len(args) > 0 { cmd := strings.Join(args, " ") stdout, err := ssh.Execute(sshClient, cmd) if err != nil { log.Fatalf("Unable to run command over SSH: %s", err.Error()) } for { bytes, prefix, err := stdout.ReadLine() if err != nil { break } print(string(bytes)) if !prefix { print("\n") } } } else { if err := ssh.Shell(sshClient); err != nil { log.Fatalf(err.Error()) } } }
func startUnitAction(c *cli.Context) { var err error // If signing is explicitly set to on, verification will be done also. toSign := c.Bool("sign") var sc *sign.SignatureCreator var sv *sign.SignatureVerifier if toSign { var err error sc, err = sign.NewSignatureCreatorFromSSHAgent() if err != nil { fmt.Println("Fail to create SignatureCreator:", err) return } sv, err = sign.NewSignatureVerifierFromSSHAgent() if err != nil { fmt.Println("Fail to create SignatureVerifier:", err) return } } payloads := make([]job.JobPayload, len(c.Args())) for i, v := range c.Args() { name := path.Base(v) payload := registryCtl.GetPayload(name) if payload == nil { payload, err = getJobPayloadFromFile(v) if err != nil { fmt.Println(err.Error()) return } err = registryCtl.CreatePayload(payload) if err != nil { fmt.Printf("Creation of payload %s failed: %v\n", payload.Name, err) return } if toSign { s, err := sc.SignPayload(payload) if err != nil { fmt.Printf("Creation of sign for payload %s failed: %v\n", payload.Name, err) return } registryCtl.CreateSignatureSet(s) } } if toSign { s := registryCtl.GetSignatureSetOfPayload(name) ok, err := sv.VerifyPayload(payload, s) if !ok || err != nil { fmt.Printf("Check of payload %s failed: %v\n", payload.Name, err) return } } payloads[i] = *payload } requirements := parseRequirements(c.String("require")) // TODO: This must be done in a transaction! for _, jp := range payloads { j := job.NewJob(jp.Name, requirements, &jp, nil) err := registryCtl.CreateJob(j) if err != nil { fmt.Printf("Creation of job %s failed: %v\n", j.Name, err) } } }
func sshAction(c *cli.Context) { unit := c.String("unit") machine := c.String("machine") if unit != "" && machine != "" { log.Fatal("Both flags, machine and unit provided, please specify only one") } args := c.Args() var err error var addr string switch { case machine != "": addr, _ = findAddressInMachineList(machine) case unit != "": addr, _ = findAddressInRunningUnits(unit) default: addr, err = globalMachineLookup(args) args = args[1:] } if err != nil { log.Fatal(err) } if addr == "" { log.Fatalf("Requested machine could not be found") } var sshClient *gossh.ClientConn if tun := getTunnelFlag(); tun != "" { sshClient, err = ssh.NewTunnelledSSHClient("core", tun, addr) } else { sshClient, err = ssh.NewSSHClient("core", addr) } if err != nil { log.Fatal(err.Error()) return } defer sshClient.Close() if len(args) > 0 { cmd := strings.Join(args, " ") stdout, err := ssh.Execute(sshClient, cmd) if err != nil { log.Fatalf("Unable to run command over SSH: %s", err.Error()) } for { bytes, prefix, err := stdout.ReadLine() if err != nil { break } fmt.Print(string(bytes)) if !prefix { fmt.Print("\n") } } } else { if err := ssh.Shell(sshClient); err != nil { log.Fatalf(err.Error()) } } }