Пример #1
0
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)
}
Пример #2
0
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()
}
Пример #3
0
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()
}
Пример #4
0
func getTunnelFlag(context *cli.Context) string {
	tun := context.GlobalString("tunnel")
	if tun != "" && !strings.Contains(tun, ":") {
		tun += ":22"
	}
	return tun
}
Пример #5
0
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()
}
Пример #6
0
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)
}
Пример #7
0
func stopUnitAction(c *cli.Context) {
	r := getRegistry()

	for _, v := range c.Args() {
		name := path.Base(v)
		r.StopJob(name)
	}
}
Пример #8
0
func destroyUnitsAction(c *cli.Context) {
	for _, v := range c.Args() {
		name := path.Base(v)
		registryCtl.StopJob(name)
		registryCtl.DestroyPayload(name)
		registryCtl.DestroySignatureSetOfPayload(name)
	}
}
Пример #9
0
func destroyUnitsAction(c *cli.Context) {
	r := getRegistry()

	for _, v := range c.Args() {
		name := path.Base(v)
		r.StopJob(name)
		r.DestroyPayload(name)
	}
}
Пример #10
0
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)
	}
}
Пример #11
0
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)
}
Пример #12
0
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())
		}
	}
}
Пример #13
0
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())
}
Пример #14
0
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()
}
Пример #15
0
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")
		}
	}
}
Пример #16
0
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()
}
Пример #17
0
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
		}
	}
}
Пример #18
0
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)
		}
	}
}
Пример #19
0
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)
		}
	}
}
Пример #20
0
func stopUnitAction(c *cli.Context) {
	for _, v := range c.Args() {
		name := path.Base(v)
		registryCtl.StopJob(name)
	}
}
Пример #21
0
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())
		}
	}
}
Пример #22
0
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)
		}
	}
}
Пример #23
0
Файл: ssh.go Проект: jsdir/fleet
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())
		}
	}
}