def _update_physical_state(self, context, host, instance, state): instance_id = None if instance: instance_id = instance.id db.phy_host_update(context, host.id, {'instance_id': instance_id, 'task_state' : state, })
def spawn(self, context, instance, image_meta, network_info=None, block_device_info=None): LOG.debug("spawn:") LOG.debug("instance=%s", instance.__dict__) LOG.debug("image_meta=%s", image_meta) LOG.debug("network_info=%s", network_info) LOG.debug("block_device_info=%s", block_device_info) # TODO: handle block devices host = self._find_suitable_phy_host(context, instance) if not host: LOG.info("no suitable physical host found") raise NoSuitablePhyHost() db.phy_host_update(context, host['id'], {'instance_id': instance['id'], 'task_state' : physical_states.BUILDING, }) nics_in_order = [] pifs = db.phy_interface_get_all_by_phy_host_id(context, host['id']) for pif in pifs: nics_in_order.append(pif['address']) if pif.vif_uuid: db.phy_interface_set_vif_uuid(context, pif.id, None) nics_in_order.append(host['pxe_mac_address']) image_root = os.path.join(FLAGS.instances_path, instance['name']) tftp_root = FLAGS.physical_tftp_root os.mkdir(image_root) if FLAGS.physical_pxe_vlan_per_host: parent_interface = FLAGS.physical_pxe_parent_interface pxe_ip_id = db.phy_pxe_ip_associate(context, host.id) pxe_ip = db.phy_pxe_ip_get(context, pxe_ip_id) vlan_num = host.pxe_vlan_id server_address = pxe_ip.server_address client_address = pxe_ip.address tftp_root = os.path.join(tftp_root, str(instance['id'])) pxe_interface = vlan.ensure_vlan(vlan_num, parent_interface) from nova.network import linux_net chain = 'phy-%s' % pxe_interface iptables = linux_net.iptables_manager iptables.ipv4['filter'].add_chain(chain) iptables.ipv4['filter'].add_rule('INPUT', '-i %s -j $%s' % (pxe_interface, chain)) iptables.ipv4['filter'].add_rule(chain, '--proto udp --sport=68 --dport=67 -j ACCEPT') iptables.ipv4['filter'].add_rule(chain, '-s %s -j ACCEPT' % client_address) iptables.ipv4['filter'].add_rule(chain, '-j DROP') iptables.apply() #execute('ip', 'address', # 'add', server_address, # 'peer', client_address, # 'dev', pxe_interface, # run_as_root=True) #execute('ip', 'link', 'set', pxe_interface, 'up', run_as_root=True) execute('ip', 'address', 'add', server_address + '/24', 'dev', pxe_interface, run_as_root=True) execute('ip', 'route', 'add', client_address, 'scope', 'host', 'dev', pxe_interface, run_as_root=True) os.mkdir(tftp_root) shutil.copyfile(FLAGS.physical_pxelinux_path, os.path.join(tftp_root, 'pxelinux.0')) os.mkdir(os.path.join(tftp_root, 'pxelinux.cfg')) pxe.start_pxe_server(interface=pxe_interface, tftp_root=tftp_root, client_address=client_address, pid_path=_dnsmasq_pid_path(pxe_interface), lease_path=_dnsmasq_lease_path(pxe_interface)) self.plug_vifs(instance, network_info) ifcfgs = [] if_num = -1 for (network,mapping) in network_info: LOG.debug("mapping['mac'] = %s", mapping['mac']) if_num += 1 device = "eth%d" % if_num pif = db.phy_interface_get_by_vif_uuid(context, mapping['vif_uuid']) if not pif: LOG.warn("vif_uuid:%s dose not associated to pif, unexpectedly", mapping['vif_uuid']) continue ifcfg = _build_ifcfg_string_from_mapping(device, pif.address, mapping) if FLAGS.physical_use_unsafe_vlan and mapping['should_create_vlan'] and network.get('vlan'): ifcfg += "," + network['vlan'] LOG.debug("ifcfg: %s", ifcfg) ifcfgs.append(ifcfg) self._firewall_driver.setup_basic_filtering(instance, network_info) self._firewall_driver.update_instance_filter(instance, network_info) ami_id = str(image_meta['id']) aki_id = str(instance['kernel_id']) ari_id = str(instance['ramdisk_id']) deploy_aki_id = FLAGS.physical_deploy_kernel deploy_ari_id = FLAGS.physical_deploy_ramdisk image_target = os.path.join(image_root, ami_id) kernel_target = os.path.join(tftp_root, aki_id) ramdisk_target = os.path.join(tftp_root, ari_id) deploy_kernel_target = os.path.join(tftp_root, deploy_aki_id) deploy_ramdisk_target = os.path.join(tftp_root, deploy_ari_id) LOG.debug("fetching image id=%s target=%s", ami_id, image_target) self._cache_image_x(context=context, target=image_target, image_id=ami_id, user_id=instance['user_id'], project_id=instance['project_id']) LOG.debug("injecting to image id=%s target=%s", ami_id, image_target) self._inject_to_image(image_target, instance, network_info, nics_in_order) LOG.debug("fetching kernel id=%s target=%s", aki_id, kernel_target) self._cache_image_x(context=context, image_id=aki_id, target=kernel_target, user_id=instance['user_id'], project_id=instance['project_id']) LOG.debug("fetching ramdisk id=%s target=%s", ari_id, ramdisk_target) self._cache_image_x(context=context, image_id=ari_id, target=ramdisk_target, user_id=instance['user_id'], project_id=instance['project_id']) LOG.debug("fetching deploy_kernel id=%s target=%s", aki_id, kernel_target) self._cache_image_x(context=context, image_id=deploy_aki_id, target=deploy_kernel_target, user_id=instance['user_id'], project_id=instance['project_id']) LOG.debug("fetching deploy_ramdisk id=%s target=%s", ari_id, ramdisk_target) self._cache_image_x(context=context, image_id=deploy_ari_id, target=deploy_ramdisk_target, user_id=instance['user_id'], project_id=instance['project_id']) LOG.debug("fetching images all done") pxe_config_path = os.path.join(tftp_root, 'pxelinux.cfg', "01-" + host.pxe_mac_address.replace(":", "-").lower()) root_mb = instance['root_gb'] * 1024 inst_type_id = instance['instance_type_id'] inst_type = instance_types.get_instance_type(inst_type_id) swap_mb = inst_type['swap'] if swap_mb < 1024: swap_mb = 1024 deployment_key = _random_alnum(32) deployment_id = db.phy_deployment_create(context, deployment_key, image_target, pxe_config_path, root_mb, swap_mb) # 'default deploy' will be replaced to 'default boot' by phy_deploy_work pxeconf = "default deploy\n" pxeconf += "\n" pxeconf += "label deploy\n" pxeconf += "kernel %s\n" % deploy_aki_id pxeconf += "append" pxeconf += " initrd=%s" % deploy_ari_id pxeconf += " selinux=0" pxeconf += " disk=cciss/c0d0,sda,hda" pxeconf += " iscsi_target_iqn=iqn-%s" % str(instance['uuid']) pxeconf += " deployment_id=%s" % deployment_id pxeconf += " deployment_key=%s" % deployment_key pxeconf += "\n" pxeconf += "ipappend 3\n" pxeconf += "\n" pxeconf += "label boot\n" pxeconf += "kernel %s\n" % aki_id pxeconf += "append" pxeconf += " initrd=%s" % ari_id # ${ROOT} will be replaced to UUID=... by phy_deploy_work pxeconf += " root=${ROOT} ro" pxeconf += "\n" pxeconf += "\n" f = open(pxe_config_path, 'w') f.write(pxeconf) f.close() if not host.ipmi_address: LOG.warn("Since ipmi_address is empty, power_off_on is not performed") LOG.debug("power on") pm = _get_ipmi(host.ipmi_address, host.ipmi_user, host.ipmi_password) state = pm.power_off() self._update_physical_state(context, host, instance, state) state = pm.power_on() self._update_physical_state(context, host, instance, state) if FLAGS.physical_console: (out,err) = execute(FLAGS.physical_console, '--ipmi_address=%s' % host.ipmi_address, '--ipmi_user=%s' % host.ipmi_user, '--ipmi_password=%s' % host.ipmi_password, '--terminal_port=%s' % host.terminal_port, '--pidfile=%s' % _console_pidfile(host.id), run_as_root=True) LOG.debug("physical_console: out=%s", out) LOG.debug("physical_console: err=%s", err)