summaryrefslogtreecommitdiff
path: root/azurelinuxagent/pa/deprovision/default.py
diff options
context:
space:
mode:
Diffstat (limited to 'azurelinuxagent/pa/deprovision/default.py')
-rw-r--r--azurelinuxagent/pa/deprovision/default.py129
1 files changed, 114 insertions, 15 deletions
diff --git a/azurelinuxagent/pa/deprovision/default.py b/azurelinuxagent/pa/deprovision/default.py
index ced87ee..90d16c7 100644
--- a/azurelinuxagent/pa/deprovision/default.py
+++ b/azurelinuxagent/pa/deprovision/default.py
@@ -17,13 +17,17 @@
# Requires Python 2.4+ and Openssl 1.0+
#
+import glob
+import os.path
import signal
import sys
+
import azurelinuxagent.common.conf as conf
-from azurelinuxagent.common.exception import ProtocolError
-from azurelinuxagent.common.future import read_input
import azurelinuxagent.common.utils.fileutil as fileutil
import azurelinuxagent.common.utils.shellutil as shellutil
+
+from azurelinuxagent.common.exception import ProtocolError
+from azurelinuxagent.common.future import read_input
from azurelinuxagent.common.osutil import get_osutil
from azurelinuxagent.common.protocol import get_protocol_util
@@ -68,15 +72,19 @@ class DeprovisionHandler(object):
def regen_ssh_host_key(self, warnings, actions):
warnings.append("WARNING! All SSH host key pairs will be deleted.")
actions.append(DeprovisionAction(fileutil.rm_files,
- ['/etc/ssh/ssh_host_*key*']))
+ [conf.get_ssh_key_glob()]))
def stop_agent_service(self, warnings, actions):
warnings.append("WARNING! The waagent service will be stopped.")
actions.append(DeprovisionAction(self.osutil.stop_agent_service))
+ def del_dirs(self, warnings, actions):
+ dirs = [conf.get_lib_dir(), conf.get_ext_log_dir()]
+ actions.append(DeprovisionAction(fileutil.rm_dirs, dirs))
+
def del_files(self, warnings, actions):
- files_to_del = ['/root/.bash_history', '/var/log/waagent.log']
- actions.append(DeprovisionAction(fileutil.rm_files, files_to_del))
+ files = ['/root/.bash_history', '/var/log/waagent.log']
+ actions.append(DeprovisionAction(fileutil.rm_files, files))
def del_resolv(self, warnings, actions):
warnings.append("WARNING! /etc/resolv.conf will be deleted.")
@@ -92,9 +100,63 @@ class DeprovisionHandler(object):
actions.append(DeprovisionAction(fileutil.rm_files, ["/var/db/dhclient.leases.hn0",
"/var/lib/NetworkManager/dhclient-*.lease"]))
- def del_lib_dir(self, warnings, actions):
- dirs_to_del = [conf.get_lib_dir()]
- actions.append(DeprovisionAction(fileutil.rm_dirs, dirs_to_del))
+
+ def del_lib_dir_files(self, warnings, actions):
+ known_files = [
+ 'HostingEnvironmentConfig.xml',
+ 'Incarnation',
+ 'Protocol',
+ 'SharedConfig.xml',
+ 'WireServerEndpoint'
+ ]
+ known_files_glob = [
+ 'Extensions.*.xml',
+ 'ExtensionsConfig.*.xml',
+ 'GoalState.*.xml'
+ ]
+
+ lib_dir = conf.get_lib_dir()
+ files = [f for f in \
+ [os.path.join(lib_dir, kf) for kf in known_files] \
+ if os.path.isfile(f)]
+ for p in known_files_glob:
+ files += glob.glob(os.path.join(lib_dir, p))
+
+ if len(files) > 0:
+ actions.append(DeprovisionAction(fileutil.rm_files, files))
+
+ def cloud_init_dirs(self, include_once=True):
+ dirs = [
+ "/var/lib/cloud/instance",
+ "/var/lib/cloud/instances/",
+ "/var/lib/cloud/data"
+ ]
+ if include_once:
+ dirs += [
+ "/var/lib/cloud/scripts/per-once"
+ ]
+ return dirs
+
+ def cloud_init_files(self, include_once=True):
+ files = [
+ "/etc/sudoers.d/90-cloud-init-users"
+ ]
+ if include_once:
+ files += [
+ "/var/lib/cloud/sem/config_scripts_per_once.once"
+ ]
+ return files
+
+ def del_cloud_init(self, warnings, actions, include_once=True):
+ dirs = [d for d in self.cloud_init_dirs(include_once=include_once) \
+ if os.path.isdir(d)]
+ if len(dirs) > 0:
+ actions.append(DeprovisionAction(fileutil.rm_dirs, dirs))
+
+ files = [f for f in self.cloud_init_files(include_once=include_once) \
+ if os.path.isfile(f)]
+ if len(files) > 0:
+ actions.append(DeprovisionAction(fileutil.rm_files, files))
def reset_hostname(self, warnings, actions):
localhost = ["localhost.localdomain"]
@@ -117,7 +179,8 @@ class DeprovisionHandler(object):
if conf.get_delete_root_password():
self.del_root_password(warnings, actions)
- self.del_lib_dir(warnings, actions)
+ self.del_cloud_init(warnings, actions)
+ self.del_dirs(warnings, actions)
self.del_files(warnings, actions)
self.del_resolv(warnings, actions)
@@ -126,19 +189,55 @@ class DeprovisionHandler(object):
return warnings, actions
+ def setup_changed_unique_id(self):
+ warnings = []
+ actions = []
+
+ self.del_cloud_init(warnings, actions, include_once=False)
+ self.del_dhcp_lease(warnings, actions)
+ self.del_lib_dir_files(warnings, actions)
+ self.del_resolv(warnings, actions)
+
+ return warnings, actions
+
def run(self, force=False, deluser=False):
warnings, actions = self.setup(deluser)
- for warning in warnings:
- print(warning)
- if not force:
- confirm = read_input("Do you want to proceed (y/n)")
- if not confirm.lower().startswith('y'):
- return
+ self.do_warnings(warnings)
+ self.do_confirmation(force=force)
+ self.do_actions(actions)
+
+ def run_changed_unique_id(self):
+ '''
+ Clean-up files and directories that may interfere when the VM unique
+ identifier has changed.
+ While users *should* manually deprovision a VM, the files removed by
+ this routine will help keep the agent from getting confused
+ (since incarnation and extension settings, among other items, will
+ no longer be monotonically increasing).
+ '''
+ warnings, actions = self.setup_changed_unique_id()
+
+ self.do_warnings(warnings)
+ self.do_actions(actions)
+
+ def do_actions(self, actions):
self.actions_running = True
for action in actions:
action.invoke()
+ self.actions_running = False
+
+ def do_confirmation(self, force=False):
+ if force:
+ return True
+
+ confirm = read_input("Do you want to proceed (y/n)")
+ return True if confirm.lower().startswith('y') else False
+
+ def do_warnings(self, warnings):
+ for warning in warnings:
+ print(warning)
def handle_interrupt_signal(self, signum, frame):
if not self.actions_running: