github.com/juju/juju@v0.0.0-20240430160146-1752b71fcf00/environs/manual/sshprovisioner/provisioner.go (about)

     1  // Copyright 2016 Canonical Ltd.
     2  // Copyright 2016 Cloudbase Solutions SRL
     3  // Licensed under the AGPLv3, see LICENCE file for details.
     4  
     5  package sshprovisioner
     6  
     7  import (
     8  	"github.com/juju/loggo"
     9  
    10  	"github.com/juju/juju/environs/manual"
    11  	"github.com/juju/juju/rpc/params"
    12  )
    13  
    14  var (
    15  	logger = loggo.GetLogger("juju.environs.manual.sshprovisioner")
    16  )
    17  
    18  // ProvisionMachine returns a new machineId and nil if the provision process is done successfully
    19  // The func will manual provision a linux machine using as it's default protocol SSH
    20  func ProvisionMachine(args manual.ProvisionMachineArgs) (machineId string, err error) {
    21  	defer func() {
    22  		if machineId != "" && err != nil {
    23  			logger.Errorf("provisioning failed, removing machine %v: %v", machineId, err)
    24  			results, cleanupErr := args.Client.DestroyMachinesWithParams(false, false, false, nil, machineId)
    25  			if cleanupErr == nil {
    26  				cleanupErr = results[0].Error
    27  			}
    28  			if cleanupErr != nil {
    29  				logger.Errorf("error cleaning up machine: %s", cleanupErr)
    30  			}
    31  			machineId = ""
    32  		}
    33  	}()
    34  
    35  	// Create the "ubuntu" user and initialise passwordless sudo. We populate
    36  	// the ubuntu user's authorized_keys file with the public keys in the current
    37  	// user's ~/.ssh directory. The authenticationworker will later update the
    38  	// ubuntu user's authorized_keys.
    39  	if err = InitUbuntuUser(args.Host, args.User,
    40  		args.AuthorizedKeys, args.PrivateKey, args.Stdin, args.Stdout); err != nil {
    41  		return "", err
    42  	}
    43  
    44  	machineParams, err := gatherMachineParams(args.Host)
    45  	if err != nil {
    46  		return "", err
    47  	}
    48  
    49  	// Inform Juju that the machine exists.
    50  	machineId, err = manual.RecordMachineInState(args.Client, *machineParams)
    51  	if err != nil {
    52  		return "", err
    53  	}
    54  
    55  	provisioningScript, err := args.Client.ProvisioningScript(params.ProvisioningScriptParams{
    56  		MachineId:              machineId,
    57  		Nonce:                  machineParams.Nonce,
    58  		DisablePackageCommands: !args.EnableOSRefreshUpdate && !args.EnableOSUpgrade,
    59  	})
    60  
    61  	if err != nil {
    62  		logger.Errorf("cannot obtain provisioning script")
    63  		return "", err
    64  	}
    65  
    66  	// Finally, provision the machine agent.
    67  	err = runProvisionScript(provisioningScript, args.Host, args.Stderr)
    68  	if err != nil {
    69  		return machineId, err
    70  	}
    71  
    72  	logger.Infof("Provisioned machine %v", machineId)
    73  	return machineId, nil
    74  }