class StartOSInstallRunner(object): '''Handles running startosinstall to set up and kick off an upgrade install of macOS''' def __init__(self, installer, finishing_tasks=None, installinfo=None): self.installer = installer self.installinfo = installinfo self.finishing_tasks = finishing_tasks self.dmg_mountpoint = None self.got_sigusr1 = False def sigusr1_handler(self, dummy_signum, dummy_frame): '''Signal handler for SIGUSR1 from startosinstall, which tells us it's done setting up the macOS install and is ready and waiting to reboot''' display.display_debug1('Got SIGUSR1 from startosinstall') self.got_sigusr1 = True # do cleanup, record-keeping, notifications if self.installinfo and 'postinstall_script' in self.installinfo: # run the postinstall_script dummy_retcode = scriptutils.run_embedded_script( 'postinstall_script', self.installinfo) if self.finishing_tasks: self.finishing_tasks() # set Munki to run at boot after the OS upgrade is complete try: bootstrapping.set_bootstrap_mode() except bootstrapping.SetupError, err: display.display_error( 'Could not set up Munki to run after OS upgrade is complete: ' '%s', err) if pkgutils.hasValidDiskImageExt(self.installer): # remove the diskimage to free up more space for the actual install try: os.unlink(self.installer) except (IOError, OSError): pass # ask authrestartd if we can do an auth restart, or look for a recovery # key (via munkilib.authrestart methods) if (authrestartd.verify_can_attempt_auth_restart() or authrestart.can_attempt_auth_restart()): # # set a secret preference to tell the osinstaller process to exit # instead of restart # this is the equivalent of: # `defaults write /Library/Preferences/.GlobalPreferences # IAQuitInsteadOfReboot -bool YES` # # This preference is referred to in a framework inside the # Install macOS.app: # Contents/Frameworks/OSInstallerSetup.framework/Versions/A/ # Frameworks/OSInstallerSetupInternal.framework/Versions/A/ # OSInstallerSetupInternal # # It might go away in future versions of the macOS installer. # CFPreferencesSetValue('IAQuitInsteadOfReboot', True, '.GlobalPreferences', kCFPreferencesAnyUser, kCFPreferencesCurrentHost) # now tell startosinstall it's OK to proceed subprocess.call(['/usr/bin/killall', '-SIGUSR1', 'startosinstall'])
def setup_authrestart_if_applicable(): '''Sets up the ability to do an authrestart if applicable''' # ask authrestartd if we can do an auth restart, or look for a recovery # key (via munkilib.authrestart methods) if (authrestartd.verify_can_attempt_auth_restart() or authrestart.can_attempt_auth_restart()): display.display_info( 'FileVault is active and we can do an authrestart') #os_version_tuple = osutils.getOsVersion(as_tuple=True) if False: # was: os_version_tuple >= (10, 12): # setup delayed auth restart so that when startosinstall does a # restart, it completes without user credentials display.display_info('Setting up delayed authrestart...') authrestartd.setup_delayed_authrestart() # make sure the special secret InstallAssistant preference is not # set CFPreferencesSetValue('IAQuitInsteadOfReboot', None, '.GlobalPreferences', kCFPreferencesAnyUser, kCFPreferencesCurrentHost) else: # # set an undocumented preference to tell the osinstaller # process to exit instead of restart # this is the equivalent of: # `defaults write /Library/Preferences/.GlobalPreferences # IAQuitInsteadOfReboot -bool YES` # # This preference is referred to in a framework inside the # Install macOS.app: # Contents/Frameworks/OSInstallerSetup.framework/Versions/A/ # Frameworks/OSInstallerSetupInternal.framework/Versions/A/ # OSInstallerSetupInternal # # It might go away in future versions of the macOS installer. # (but it's still there in the macOS 12.0.1 installer!) # display.display_info( 'Configuring startosinstall to quit instead of restart...') CFPreferencesSetValue('IAQuitInsteadOfReboot', True, '.GlobalPreferences', kCFPreferencesAnyUser, kCFPreferencesCurrentHost)