Esempio n. 1
0
/*
	Execute a create_ovs_queues for each host in the list. The create queues script is unique inasmuch
	as it expects an input file that is supplied either as a filename as $1, or on stdin if $1 is omitted.
	To send the data file for the command to execute, we'll create a tmp file on the local machine which
	is a script that echos the data into the script:
		cat <<endKat | create_ovs_queues
			data passed to us
		endKat

	We'll use the brokers 'send script for execution' feature rather to execute our script.
*/
func do_setqueues(req json_action, broker *ssh_broker.Broker, path *string, timeout time.Duration) {
	var (
		err error
	)

	startt := time.Now().Unix()

	fname := fmt.Sprintf("/tmp/tegu_setq_%d_%x_%02d.data", os.Getpid(), time.Now().Unix(), rand.Intn(10))
	sheep.Baa(3, "adjusting queues: creating %s will contain %d items", fname, len(req.Qdata))

	f, err := os.Create(fname)
	if err != nil {
		sheep.Baa(0, "ERR: unable to create data file: %s: %s	[TGUAGN002]", fname, err)
		return
	}

	fmt.Fprintf(f, "#!/usr/bin/env ksh\ncat <<endKat | PATH=%s:$PATH create_ovs_queues\n", *path)
	for i := range req.Qdata {
		sheep.Baa(3, "writing queue info: %s", req.Qdata[i])
		fmt.Fprintf(f, "%s\n", req.Qdata[i])
	}
	fmt.Fprintf(f, "endKat\n")

	err = f.Close()
	if err != nil {
		sheep.Baa(0, "ERR: unable to create data file (close): %s: %s	[TGUAGN003]", fname, err)
		return
	}

	ssh_rch := make(chan *ssh_broker.Broker_msg, 256) // channel for ssh results
	// do NOT close the channel here; only senders should close

	wait4 := 0 // number of responses to wait for
	for i := range req.Hosts {
		sheep.Baa(1, "via broker on %s: create_ovs_queues embedded in %s", req.Hosts[i], fname)

		err := broker.NBRun_on_host(req.Hosts[i], fname, "", wait4, ssh_rch) // sends the file as input to be executed on the host
		if err != nil {
			msg_007(req.Hosts[i], "create_ovs_queues", err)
		} else {
			wait4++
		}
	}

	timer_pop := false
	errcount := 0
	for wait4 > 0 && !timer_pop { // collect responses logging any errors
		select {
		case <-time.After(timeout * time.Second): // timeout
			msg_008(wait4)
			timer_pop = true

		case resp := <-ssh_rch: // response back from the broker
			wait4--
			_, stderr, elapsed, err := resp.Get_results()
			host, _, _ := resp.Get_info()
			sheep.Baa(2, "create-q: received response from %s elap=%d err=%v, waiting for %d more", host, elapsed, err != nil, wait4)
			if err != nil {
				sheep.Baa(0, "ERR: unable to execute set queue command on %s: data=%s: %s  [TGUAGN004]", host, fname, err)
				errcount++
			} else {
				sheep.Baa(1, "queues adjusted succesfully on: %s", host)
			}
			if err != nil || sheep.Would_baa(2) {
				dump_stderr(stderr, "create-q"+host) // always dump on error, or if chatty
			}
		}
	}

	endt := time.Now().Unix()
	sheep.Baa(1, "create-q: timeout=%v %ds elapsed %d hosts %d errors", timer_pop, endt-startt, len(req.Hosts), errcount)

	if errcount == 0 { // ditch the script we built earlier if all successful
		os.Remove(fname)
	} else {
		sheep.Baa(1, "create-q: %d errors, generated script file kept: %s", fname)
	}

}