1010
1111from ruamel .yaml import YAML
1212
13- from .inventory import ROOT , ansible_inventory , save
13+ from .inventory import LOCAL_SSH_ARGS , ROOT , ansible_inventory , save
1414from .models import Host , Inventory
1515
1616
@@ -20,10 +20,11 @@ def check_admin(host: Host, *, report_error: bool = False) -> bool:
2020 '-o' , 'PreferredAuthentications=publickey' ,
2121 '-o' , 'ControlMaster=no' , '-o' , 'ControlPath=none' , '-o' , 'ConnectTimeout=10' ,
2222 '-p' , str (host .admin .port ), '-i' , str (Path (host .admin .private_key_file ).expanduser ()),
23+ * (shlex .split (LOCAL_SSH_ARGS ) if host .local else []),
2324 * shlex .split (os .environ .get ('ANSIBLE_SSH_ARGS' , '' )),
2425 * shlex .split (os .environ .get ('ANSIBLE_SSH_COMMON_ARGS' , '' )),
2526 * shlex .split (os .environ .get ('ANSIBLE_SSH_EXTRA_ARGS' , '' )),
26- '-l' , host .admin .user , '--' , host .address , 'sudo -n true' ,
27+ '-l' , host .admin .user , '--' , '127.0.0.1' if host . local else host .address , 'sudo -n true' ,
2728 ]
2829 try :
2930 result = sp .run (command , capture_output = True , text = True , timeout = 30 )
@@ -52,6 +53,11 @@ def run_phase(inventory: Inventory, name: str, phase: str, password: str | None
5253 variables ['ansible_become_password' ] = password
5354 variables ['ansible_ssh_common_args' ] = '-o PubkeyAuthentication=no -o PreferredAuthentications=password,keyboard-interactive'
5455 variables ['megaproxy_bootstrap_phase' ] = phase
56+ if host .local and phase == 'account' :
57+ if os .geteuid () != 0 :
58+ raise ValueError ('Local bootstrap must run as root' )
59+ variables ['ansible_connection' ] = 'local'
60+ variables ['ansible_python_interpreter' ] = sys .executable
5561 # Bootstrap passwords exist only in a private temporary directory for this subprocess.
5662 with tempfile .TemporaryDirectory (prefix = 'megaproxy-bootstrap-' ) as directory :
5763 path = Path (directory ) / 'inventory.yml'
@@ -73,7 +79,7 @@ def bootstrap(path: Path, inventory: Inventory, limit: str | None = None) -> int
7379 print (f'Bootstrapping administrative access: { name } ' , flush = True )
7480 if not check_admin (host ):
7581 password = None
76- if host .admin .bootstrap_auth == 'password' :
82+ if host .admin .bootstrap_auth == 'password' and not host . local :
7783 password = getpass .getpass (f'Initial SSH password for { host .admin .bootstrap_user } @{ host .address } : ' )
7884 if not password :
7985 raise ValueError ('Initial SSH password must not be empty' )
0 commit comments