Beispiel #1
0
// Install installs the service.
func (s *Service) Install() error {
	fr, err := os.Open(s.KlientBin)
	if err != nil {
		return err
	}
	defer fr.Close()

	cfg := s.config()

	if absPath, err := filepath.Abs(s.KlientBin); err != nil || absPath != cfg.Executable {
		if err := os.MkdirAll(filepath.Dir(cfg.Executable), 0755); err != nil {
			return err
		}

		fw, err := os.OpenFile(cfg.Executable, os.O_WRONLY|os.O_TRUNC|os.O_CREATE, 0755)
		if err != nil {
			return err
		}

		_, err = io.Copy(fw, fr)
		if err := nonil(err, fw.Close()); err != nil {
			return err
		}
	}

	svc, err := service.New(nopService{}, cfg)
	if err != nil {
		return err
	}

	// All the following are best-effort methods
	// to either ensure log files have proper
	// permissions so klient can upload them,
	// or sets static routes for local routing
	// webterm optimizations.
	//
	// Ignore the errors as they're not vital.
	_ = uploader.FixPerms()
	_ = tlsproxy.Init()
	_ = svc.Uninstall()

	return svc.Install()
}
Beispiel #2
0
// Register registers with the username to the given kontrolURL via the users
// password or the given token.
func Register(koding *url.URL, username, token string, debug bool) error {
	var err error

	// Open up a prompt if the username is not passed via a flag and it's not a
	// token based authentication. If token is empty, it means the user can be
	// authenticated via password
	if token == "" && username == "" {
		username, err = ask("Username:"******"" {
			return errors.New("Username can not be empty.")
		}
	}

	k := kite.New("klient", konfig.Version)
	k.Config.Environment = konfig.Environment
	k.Config.Region = konfig.Region
	k.Config.Username = username

	if debug {
		k.SetLogLevel(kite.DEBUG)
	}

	// Production Koding servers are only working over HTTP
	k.Config.Transport = config.XHRPolling

	// Give a warning if an existing kite.key exists
	newKonfig := cfg.NewKonfigURL(koding)

	if konfig := configcli.List()[newKonfig.ID()]; konfig != nil && konfig.KiteKey != "" {
		result, err := ask(fmt.Sprintf("An existing kite.key for %s detected. Type 'yes' to override and continue:", konfig.KodingPublic()))
		if err != nil {
			return err
		}

		if result != "yes" {
			return errors.New("aborting registration")
		}
	}

	kontrol := k.NewClient(newKonfig.Endpoints.Kontrol().Public.String())
	if err := kontrol.DialTimeout(30 * time.Second); err != nil {
		return err
	}
	defer kontrol.Close()

	// Register is always called with sudo, so Init should have enough
	// permissions.
	if err := tlsproxy.Init(); err != nil {
		return err
	}

	authType := "password"
	if token != "" {
		authType = "token"
	}

	var args = struct {
		Username string
		Token    string
		AuthType string
	}{
		Username: username,
		Token:    token,
		AuthType: authType,
	}

	// If authtType is password, this causes Kontrol to execute the
	// 'kite.getPass' method (builtin method in the Kite library) on our own
	// local kite (the one we declared above) method bidirectional. So once we
	// execute this, we immediately get a prompt asking for our password, which
	// is then transfered back to Kontrol. If we have a token, it will not ask
	// for a password and will create retunr the key immediately if the token
	// is valid for the given username (which is passed via the args).
	result, err := kontrol.TellWithTimeout("registerMachine", 5*time.Minute, args)
	if err != nil {
		return err
	}

	newKonfig.KiteKey = result.MustString()

	if err := configcli.Use(newKonfig); err != nil {
		return err
	}

	// Using authenticated here instead of registered, so it is a
	// middleground in UX for both raw `klient -register` usage, and also
	// `kd install` usage. `kd install` is very user facing, and
	// registration is potentially confusing to the end user (since
	// they are already registered to koding.com.. etc)
	fmt.Println("Authenticated successfully")

	return nil
}