#!/usr/bin/python import os import json import subprocess from cloudinit.sources.DataSourceConfigDrive import find_candidate_devs, read_config_drive from cloudinit.util import mount_cb from six.moves.urllib.request import urlopen from six.moves.urllib.parse import urlencode def shell(cmd): sp = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE) out, err = sp.communicate() return out, err INSTANCE_ID_RUN_PATH = "/run/cloud-init/.instance-id" # Ensure /run/cloud-init/.instance-id not exists so we can reload DataSource from ConfigDrive. if os.path.isfile(INSTANCE_ID_RUN_PATH): os.unlink(INSTANCE_ID_RUN_PATH) # Before resetroot, We must ensure if 169.254.169.254 have gateway gateways = [] for dev in find_candidate_devs(): results = mount_cb(dev, read_config_drive) network_data = results.get("networkdata") networks = network_data.get("networks",None) found = dev if found: if not networks: continue for network in networks: routes = network.get("routes", None) if not routes: continue for route in routes: gateway = route.get('gateway') gateways.append(gateway) break if gateways: gateway = gateways[0] cmd = "route add -host 169.254.169.254 gw %s" % gateway out,err = shell(cmd) data = urlopen("http://169.254.169.254/openstack/latest/meta_data.json").read() json_data = json.loads(data.decode("utf-8")) meta = json_data.get("meta") if meta: adminPass = meta.get("admin_pass") if adminPass: os.system("echo 'root:%s' | chpasswd" % adminPass) params = urlencode({"delete":True}) f = urlopen("http://169.254.169.254/openstack/latest/password", params) f.read()
但谈何容易。