Example #1
0
func realMain() error {
	conf, err := NewConfig("config.toml")
	if err != nil {
		return err
	}

	db := mongodb.NewMongoDB(conf.MongoURL)
	opts := &amazon.ClientOptions{
		Credentials: credentials.NewStaticCredentials(conf.AccessKey, conf.SecretKey, ""),
		Regions:     amazon.ProductionRegions,
	}
	_, err = amazon.NewClientPerRegion(opts)
	if err != nil {
		return err
	}

	w := new(tabwriter.Writer)
	w.Init(os.Stdout, 10, 8, 0, '\t', 0)
	defer w.Flush()

	// We use a counting semaphore to limit the number of parallel SSH calls
	// per process and to start machines
	var semaSSH = make(chan bool, 50)

	var semaStart = make(chan bool, 10)

	// search via username, mongodb -> aws
	ms, err := machineFromMongodb(db)
	if err != nil {
		return err
	}

	ms.Print(w)

	ips := make([]string, 0)
	var attachWg sync.WaitGroup

	username := make([]string, len(ms.docs))
	for i, machine := range ms.docs {
		username[i] = machine.Credential
	}

	out, err := json.MarshalIndent(username, "", " ")
	if err != nil {
		return err
	}

	if err := ioutil.WriteFile("users.json", out, 0755); err != nil {
		return err
	}

	fmt.Printf("len(username) = %+v\n", len(username))
	for _, machine := range ms.docs {
		attachWg.Add(1)

		go func(machine koding.Machine) {
			semaStart <- true
			defer func() {
				attachWg.Done()
				<-semaStart
			}()

			if machine.Meta.Region == "" {
				return
			}

			// if machine.Status.State == "Running" ||
			// 	machine.Status.State == "NotInitialized" {
			// 	return
			// }

			if machine.IpAddress == "" {
				return
			}

			// log.Printf("Starting %+v\n", machine.Id.Hex())
			// _, err := exec.Command("kloudctl", "start", "-ids", machine.Id.Hex(), "--kloud-addr", "https://koding.com/kloud/kite").CombinedOutput()
			// if err != nil {
			// 	return
			// }
			//
			// time.Sleep(time.Minute * 1)

			// if machine.IpAddress == "" {
			// 	return
			// }

			ips = append(ips, machine.IpAddress)
		}(machine)
	}

	// return nil

	log.Println("starting all machines ...")
	attachWg.Wait()
	log.Println("starting is finished")

	command := "/opt/kite/klient/klient --version"
	update := "cd /tmp && wget https://s3.amazonaws.com/koding-klient/production/31/klient_0.1.31_production_amd64.deb && dpkg -i klient_0.1.31_production_amd64.deb && rm klient_0.1.31_production_amd64.deb"

	log.Printf("executing the command '%s' on %d machines\n\n", command, len(ips))

	var wg sync.WaitGroup
	for _, ip := range ips {
		wg.Add(1)

		go func(ip string) {
			semaSSH <- true // wait
			defer func() {
				wg.Done()
				<-semaSSH
			}()

			done := make(chan string, 0)
			go func() {
				out, err := executeSSHCommand(conf.PrivateKey, ip, command)
				if err != nil {
					return
				}

				done <- out
			}()

			select {
			case <-time.After(time.Second * 10):
				// cancel operation after 10 seconds
				// fmt.Printf("[%s] canceling operation\n", ip)
				return
			case out := <-done:
				if out == "0.1.30" {
					return
				}

				if out == "0.1.31" {
					return
				}

				fmt.Printf("[%s] version: %s updating\n", ip, out)
				_, err := executeSSHCommand(conf.PrivateKey, ip, update)
				if err != nil {
					log.Printf("[%s] updater err: %s\n", ip, err)
					return
				}
			}
		}(ip)
	}

	wg.Wait()

	// fmt.Printf("%d machines with version 0.1.30\n", v30)
	// fmt.Printf("%d machines with version 0.1.99\n", vOther)

	return nil
}
Example #2
0
func realMain() error {
	conf := new(Config)
	multiconfig.MustLoadWithPath("config.toml", conf)

	db := mongodb.NewMongoDB(conf.MongoURL)
	opts := &amazon.ClientOptions{
		Credentials: credentials.NewStaticCredentials(conf.AccessKey, conf.SecretKey, ""),
		Regions:     amazon.ProductionRegions,
		Log:         logging.NewLogger("userdebug"),
	}
	ec2clients, err := amazon.NewClients(opts)
	if err != nil {
		panic(err)
	}

	w := new(tabwriter.Writer)
	w.Init(os.Stdout, 10, 8, 0, '\t', 0)
	defer w.Flush()

	// search via username, mongodb -> aws
	if conf.Username != "" {
		ms, err := machinesFromUsername(db, conf.Username)
		if err == nil {
			ms.Print(w)

			for _, m := range ms.docs {
				// if the mongodb document has a region and instanceId, display it too
				if m.Meta.Region != "" && m.Meta.InstanceId != "" {
					client, err := ec2clients.Region(m.Meta.Region)
					if err != nil {
						return err
					}

					i, err := awsData(client, m.Meta.InstanceId)
					if err != nil {
						return err
					}

					i.Print(w)
				}
			}
		} else {
			fmt.Fprintf(os.Stderr, err.Error())
		}
	}

	// search via instanceId, aws -> mongodb
	if conf.InstanceId != "" {
		for _, client := range ec2clients.Regions() {
			i, err := awsData(client, conf.InstanceId)
			if err != nil {
				continue // if not found continue with next region
			}

			// if we find a mongoDB document display it
			ms, err := machinesFromInstanceId(db, conf.InstanceId)
			if err == nil {
				ms.Print(w)
			}

			i.Print(w)
			break
		}
	}

	return nil
}
Example #3
0
func NewMongoDB(url string) *MongoDB {
	return &MongoDB{
		DB: mongodb.NewMongoDB(url),
	}
}
Example #4
0
func Initialize(url string) {
	Mongo = mongodb.NewMongoDB(url)
}