@Override public boolean prepare( VirtualMachineProfile profile, NicProfile nic, Network network, DeployDestination dest, ReservationContext context) { try { if (DataCenter.NetworkType.Basic.equals(dest.getDataCenter().getNetworkType())) { if (!preparePxeInBasicZone(profile, nic, dest, context)) { return false; } } else { if (!preparePxeInAdvancedZone(profile, nic, network, dest, context)) { return false; } } IpmISetBootDevCommand bootCmd = new IpmISetBootDevCommand(BootDev.pxe); Answer aws = _agentMgr.send(dest.getHost().getId(), bootCmd); if (!aws.getResult()) { s_logger.warn( "Unable to set host: " + dest.getHost().getId() + " to PXE boot because " + aws.getDetails()); } return aws.getResult(); } catch (Exception e) { s_logger.warn("Cannot prepare PXE server", e); return false; } }
@Override public void reserve( NicProfile nic, Network config, VirtualMachineProfile<? extends VirtualMachine> vm, DeployDestination dest, ReservationContext context) throws InsufficientVirtualNetworkCapcityException, InsufficientAddressCapacityException { assert nic.getTrafficType() == TrafficType.Control; if (dest.getHost().getHypervisorType() == HypervisorType.VmWare && vm.getType() == VirtualMachine.Type.DomainRouter) { super.reserve(nic, config, vm, dest, context); String mac = _networkMgr.getNextAvailableMacAddressInNetwork(config.getId()); nic.setMacAddress(mac); return; } String ip = _dcDao.allocateLinkLocalIpAddress( dest.getDataCenter().getId(), dest.getPod().getId(), nic.getId(), context.getReservationId()); nic.setIp4Address(ip); nic.setMacAddress(NetUtils.long2Mac(NetUtils.ip2Long(ip) | (14l << 40))); nic.setNetmask("255.255.0.0"); nic.setFormat(AddressFormat.Ip4); nic.setGateway(NetUtils.getLinkLocalGateway()); }
@Override @DB public boolean prepare( Network network, NicProfile nic, VirtualMachineProfile<? extends VirtualMachine> vm, DeployDestination dest, ReservationContext context) throws ConcurrentOperationException, ResourceUnavailableException, InsufficientCapacityException { Host host = dest.getHost(); if (host == null || host.getHypervisorType() != HypervisorType.BareMetal) { return true; } Transaction txn = Transaction.currentTxn(); txn.start(); nic.setMacAddress(host.getPrivateMacAddress()); NicVO vo = _nicDao.findById(nic.getId()); assert vo != null : "Where ths nic " + nic.getId() + " going???"; vo.setMacAddress(nic.getMacAddress()); _nicDao.update(vo.getId(), vo); txn.commit(); s_logger.debug( "Bare Metal changes mac address of nic " + nic.getId() + " to " + nic.getMacAddress()); return _dhcpMgr.addVirtualMachineIntoNetwork(network, nic, vm, dest, context); }
@Override public boolean prepareMigration( final NicProfile nic, final Network network, final VirtualMachineProfile vm, final DeployDestination dest, final ReservationContext context) { if (!canHandle(network, Service.Connectivity)) { return false; } if (nic.getBroadcastType() != Networks.BroadcastDomainType.Vswitch) { return false; } if (nic.getTrafficType() != Networks.TrafficType.Guest) { return false; } if (vm.getType() != VirtualMachine.Type.User && vm.getType() != VirtualMachine.Type.DomainRouter) { return false; } // prepare the tunnel network on the host, in order for VM to get launched _ovsTunnelMgr.checkAndPrepareHostForTunnelNetwork(network, dest.getHost()); return true; }
// we use context.reservationId for dedup of guru & element operations. public boolean createNicEnv( Network network, NicProfile nic, DeployDestination dest, ReservationContext context) { String tenantNetworkUuid = _sspUuidDao.findUuidByNetwork(network); if (tenantNetworkUuid == null) { s_logger.debug("Skipping #createNicEnv() for nic on " + network.toString()); return true; } String reservationId = context.getReservationId(); List<SspUuidVO> tenantPortUuidVos = _sspUuidDao.listUUidVoByNicProfile(nic); for (SspUuidVO tenantPortUuidVo : tenantPortUuidVos) { if (reservationId.equals(tenantPortUuidVo.getReservationId())) { s_logger.info("Skipping because reservation found " + reservationId); return true; } } String tenantPortUuid = null; for (SspClient client : fetchSspClients(network.getPhysicalNetworkId(), network.getDataCenterId(), true)) { SspClient.TenantPort sspPort = client.createTenantPort(tenantNetworkUuid); if (sspPort != null) { tenantPortUuid = sspPort.uuid; nic.setReservationId(reservationId); SspUuidVO uuid = new SspUuidVO(); uuid.setUuid(tenantPortUuid); uuid.setObjClass(SspUuidVO.objClassNicProfile); uuid.setObjId(nic.getId()); uuid.setReservationId(reservationId); _sspUuidDao.persist(uuid); break; } } if (tenantPortUuid == null) { s_logger.debug("#createNicEnv() failed for nic on " + network.toString()); return false; } for (SspClient client : fetchSspClients(network.getPhysicalNetworkId(), network.getDataCenterId(), true)) { SspClient.TenantPort sspPort = client.updateTenantVifBinding(tenantPortUuid, dest.getHost().getPrivateIpAddress()); if (sspPort != null) { if (sspPort.vlanId != null) { nic.setBroadcastType(BroadcastDomainType.Vlan); nic.setBroadcastUri(BroadcastDomainType.Vlan.toUri(String.valueOf(sspPort.vlanId))); } return true; } } s_logger.error("Updating vif failed " + nic.toString()); return false; }
private boolean preparePxeInBasicZone( VirtualMachineProfile profile, NicProfile nic, DeployDestination dest, ReservationContext context) throws AgentUnavailableException, OperationTimedoutException { NetworkVO nwVO = _nwDao.findById(nic.getNetworkId()); QueryBuilder<BaremetalPxeVO> sc = QueryBuilder.create(BaremetalPxeVO.class); sc.and(sc.entity().getDeviceType(), Op.EQ, BaremetalPxeType.KICK_START.toString()); sc.and(sc.entity().getPhysicalNetworkId(), Op.EQ, nwVO.getPhysicalNetworkId()); BaremetalPxeVO pxeVo = sc.find(); if (pxeVo == null) { throw new CloudRuntimeException( "No kickstart PXE server found in pod: " + dest.getPod().getId() + ", you need to add it before starting VM"); } VMTemplateVO template = _tmpDao.findById(profile.getTemplateId()); List<String> tuple = parseKickstartUrl(profile); String ks = tuple.get(0); String kernel = tuple.get(1); String initrd = tuple.get(2); PrepareKickstartPxeServerCommand cmd = new PrepareKickstartPxeServerCommand(); cmd.setKsFile(ks); cmd.setInitrd(initrd); cmd.setKernel(kernel); cmd.setMac(nic.getMacAddress()); cmd.setTemplateUuid(template.getUuid()); Answer aws = _agentMgr.send(pxeVo.getHostId(), cmd); if (!aws.getResult()) { s_logger.warn( "Unable to set host: " + dest.getHost().getId() + " to PXE boot because " + aws.getDetails()); return false; } return true; }
@Override public String reserveVirtualMachine( VMEntityVO vmEntityVO, String plannerToUse, DeploymentPlan planToDeploy, ExcludeList exclude) throws InsufficientCapacityException, ResourceUnavailableException { // call planner and get the deployDestination. // load vm instance and offerings and call virtualMachineManagerImpl // FIXME: profile should work on VirtualMachineEntity VMInstanceVO vm = _vmDao.findByUuid(vmEntityVO.getUuid()); VirtualMachineProfileImpl<VMInstanceVO> vmProfile = new VirtualMachineProfileImpl<VMInstanceVO>(vm); DataCenterDeployment plan = new DataCenterDeployment( vm.getDataCenterId(), vm.getPodIdToDeployIn(), null, null, null, null); if (planToDeploy != null && planToDeploy.getDataCenterId() != 0) { plan = new DataCenterDeployment( planToDeploy.getDataCenterId(), planToDeploy.getPodId(), planToDeploy.getClusterId(), planToDeploy.getHostId(), planToDeploy.getPoolId(), planToDeploy.getPhysicalNetworkId()); } List<VolumeVO> vols = _volsDao.findReadyRootVolumesByInstance(vm.getId()); if (!vols.isEmpty()) { VolumeVO vol = vols.get(0); StoragePoolVO pool = _storagePoolDao.findById(vol.getPoolId()); if (!pool.isInMaintenance()) { long rootVolDcId = pool.getDataCenterId(); Long rootVolPodId = pool.getPodId(); Long rootVolClusterId = pool.getClusterId(); if (planToDeploy != null && planToDeploy.getDataCenterId() != 0) { Long clusterIdSpecified = planToDeploy.getClusterId(); if (clusterIdSpecified != null && rootVolClusterId != null) { if (rootVolClusterId.longValue() != clusterIdSpecified.longValue()) { // cannot satisfy the plan passed in to the // planner throw new ResourceUnavailableException( "Root volume is ready in different cluster, Deployment plan provided cannot be satisfied, unable to create a deployment for " + vm, Cluster.class, clusterIdSpecified); } } plan = new DataCenterDeployment( planToDeploy.getDataCenterId(), planToDeploy.getPodId(), planToDeploy.getClusterId(), planToDeploy.getHostId(), vol.getPoolId(), null, null); } else { plan = new DataCenterDeployment( rootVolDcId, rootVolPodId, rootVolClusterId, null, vol.getPoolId(), null, null); } } } DeploymentPlanner planner = ComponentContext.getComponent(plannerToUse); DeployDestination dest = null; if (planner.canHandle(vmProfile, plan, exclude)) { dest = planner.plan(vmProfile, plan, exclude); } if (dest != null) { // save destination with VMEntityVO VMReservationVO vmReservation = new VMReservationVO( vm.getId(), dest.getDataCenter().getId(), dest.getPod().getId(), dest.getCluster().getId(), dest.getHost().getId()); Map<Long, Long> volumeReservationMap = new HashMap<Long, Long>(); for (Volume vo : dest.getStorageForDisks().keySet()) { volumeReservationMap.put(vo.getId(), dest.getStorageForDisks().get(vo).getId()); } vmReservation.setVolumeReservation(volumeReservationMap); vmEntityVO.setVmReservation(vmReservation); _vmEntityDao.persist(vmEntityVO); return vmReservation.getUuid(); } else { throw new InsufficientServerCapacityException( "Unable to create a deployment for " + vmProfile, DataCenter.class, plan.getDataCenterId()); } }
@Override public boolean finalizeVirtualMachineProfile( VirtualMachineProfile<DomainRouterVO> profile, DeployDestination dest, ReservationContext context) { DomainRouterVO elbVm = profile.getVirtualMachine(); List<NicProfile> elbNics = profile.getNics(); Long guestNtwkId = null; for (NicProfile routerNic : elbNics) { if (routerNic.getTrafficType() == TrafficType.Guest) { guestNtwkId = routerNic.getNetworkId(); break; } } NetworkVO guestNetwork = _networkDao.findById(guestNtwkId); DataCenter dc = dest.getDataCenter(); StringBuilder buf = profile.getBootArgsBuilder(); buf.append(" template=domP type=" + _systemVmType); buf.append(" name=").append(profile.getHostName()); NicProfile controlNic = null; String defaultDns1 = null; String defaultDns2 = null; for (NicProfile nic : profile.getNics()) { int deviceId = nic.getDeviceId(); buf.append(" eth").append(deviceId).append("ip=").append(nic.getIp4Address()); buf.append(" eth").append(deviceId).append("mask=").append(nic.getNetmask()); if (nic.isDefaultNic()) { buf.append(" gateway=").append(nic.getGateway()); defaultDns1 = nic.getDns1(); defaultDns2 = nic.getDns2(); } if (nic.getTrafficType() == TrafficType.Management) { buf.append(" localgw=").append(dest.getPod().getGateway()); } else if (nic.getTrafficType() == TrafficType.Control) { // control command is sent over management network in VMware if (dest.getHost().getHypervisorType() == HypervisorType.VMware) { if (s_logger.isInfoEnabled()) { s_logger.info( "Check if we need to add management server explicit route to ELB vm. pod cidr: " + dest.getPod().getCidrAddress() + "/" + dest.getPod().getCidrSize() + ", pod gateway: " + dest.getPod().getGateway() + ", management host: " + _mgmtHost); } if (s_logger.isDebugEnabled()) { s_logger.debug("Added management server explicit route to ELB vm."); } // always add management explicit route, for basic networking setup buf.append(" mgmtcidr=").append(_mgmtCidr); buf.append(" localgw=").append(dest.getPod().getGateway()); if (dc.getNetworkType() == NetworkType.Basic) { // ask elb vm to setup SSH on guest network buf.append(" sshonguest=true"); } } controlNic = nic; } } String domain = guestNetwork.getNetworkDomain(); if (domain != null) { buf.append(" domain=" + domain); } buf.append(" dns1=").append(defaultDns1); if (defaultDns2 != null) { buf.append(" dns2=").append(defaultDns2); } if (s_logger.isDebugEnabled()) { s_logger.debug("Boot Args for " + profile + ": " + buf.toString()); } if (controlNic == null) { throw new CloudRuntimeException("Didn't start a control port"); } return true; }
@DB protected void CheckAndCreateTunnel(VirtualMachine instance, DeployDestination dest) { if (!_isEnabled) { return; } if (instance.getType() != VirtualMachine.Type.User && instance.getType() != VirtualMachine.Type.DomainRouter) { return; } long hostId = dest.getHost().getId(); long accountId = instance.getAccountId(); List<UserVmVO> vms = _userVmDao.listByAccountId(accountId); List<DomainRouterVO> routers = _routerDao.findBy(accountId, instance.getDataCenterIdToDeployIn()); List<VMInstanceVO> ins = new ArrayList<VMInstanceVO>(); if (vms != null) { ins.addAll(vms); } if (routers.size() != 0) { ins.addAll(routers); } List<Pair<Long, Integer>> toHosts = new ArrayList<Pair<Long, Integer>>(); List<Pair<Long, Integer>> fromHosts = new ArrayList<Pair<Long, Integer>>(); int key; for (VMInstanceVO v : ins) { Long rh = v.getHostId(); if (rh == null || rh.longValue() == hostId) { continue; } OvsTunnelAccountVO ta = _tunnelAccountDao.getByFromToAccount(hostId, rh.longValue(), accountId); if (ta == null) { key = getGreKey(hostId, rh.longValue(), accountId); if (key == -1) { s_logger.warn( String.format( "Cannot get GRE key for from=%1$s to=%2$s accountId=%3$s, tunnel create failed", hostId, rh.longValue(), accountId)); continue; } Pair<Long, Integer> p = new Pair<Long, Integer>(rh, Integer.valueOf(key)); if (!toHosts.contains(p)) { toHosts.add(p); } } ta = _tunnelAccountDao.getByFromToAccount(rh.longValue(), hostId, accountId); if (ta == null) { key = getGreKey(rh.longValue(), hostId, accountId); if (key == -1) { s_logger.warn( String.format( "Cannot get GRE key for from=%1$s to=%2$s accountId=%3$s, tunnel create failed", rh.longValue(), hostId, accountId)); continue; } Pair<Long, Integer> p = new Pair<Long, Integer>(rh, Integer.valueOf(key)); if (!fromHosts.contains(p)) { fromHosts.add(p); } } } try { String myIp = dest.getHost().getPrivateIpAddress(); for (Pair<Long, Integer> i : toHosts) { HostVO rHost = _hostDao.findById(i.first()); Commands cmds = new Commands( new OvsCreateTunnelCommand( rHost.getPrivateIpAddress(), i.second().toString(), Long.valueOf(hostId), i.first(), accountId, myIp)); s_logger.debug("Ask host " + hostId + " to create gre tunnel to " + i.first()); Answer[] answers = _agentMgr.send(hostId, cmds); handleCreateTunnelAnswer(answers); } for (Pair<Long, Integer> i : fromHosts) { HostVO rHost = _hostDao.findById(i.first()); Commands cmd2s = new Commands( new OvsCreateTunnelCommand( myIp, i.second().toString(), i.first(), Long.valueOf(hostId), accountId, rHost.getPrivateIpAddress())); s_logger.debug("Ask host " + i.first() + " to create gre tunnel to " + hostId); Answer[] answers = _agentMgr.send(i.first(), cmd2s); handleCreateTunnelAnswer(answers); } } catch (Exception e) { s_logger.debug("Ovs Tunnel network created tunnel failed", e); } }
@Override public boolean prepare( VirtualMachineProfile<UserVmVO> profile, NicProfile pxeNic, DeployDestination dest, ReservationContext context) { SearchCriteriaService<BaremetalPxeVO, BaremetalPxeVO> sc = SearchCriteria2.create(BaremetalPxeVO.class); sc.addAnd(sc.getEntity().getDeviceType(), Op.EQ, BaremetalPxeType.PING.toString()); sc.addAnd(sc.getEntity().getPodId(), Op.EQ, dest.getPod().getId()); BaremetalPxeVO pxeVo = sc.find(); if (pxeVo == null) { throw new CloudRuntimeException( "No PING PXE server found in pod: " + dest.getPod().getId() + ", you need to add it before starting VM"); } long pxeServerId = pxeVo.getHostId(); String mac = pxeNic.getMacAddress(); String ip = pxeNic.getIp4Address(); String gateway = pxeNic.getGateway(); String mask = pxeNic.getNetmask(); String dns = pxeNic.getDns1(); if (dns == null) { dns = pxeNic.getDns2(); } try { String tpl = profile.getTemplate().getUrl(); assert tpl != null : "How can a null template get here!!!"; PreparePxeServerCommand cmd = new PreparePxeServerCommand( ip, mac, mask, gateway, dns, tpl, profile.getVirtualMachine().getInstanceName(), dest.getHost().getName()); PreparePxeServerAnswer ans = (PreparePxeServerAnswer) _agentMgr.send(pxeServerId, cmd); if (!ans.getResult()) { s_logger.warn( "Unable tot program PXE server: " + pxeVo.getId() + " because " + ans.getDetails()); return false; } IpmISetBootDevCommand bootCmd = new IpmISetBootDevCommand(BootDev.pxe); Answer anw = _agentMgr.send(dest.getHost().getId(), bootCmd); if (!anw.getResult()) { s_logger.warn( "Unable to set host: " + dest.getHost().getId() + " to PXE boot because " + anw.getDetails()); } return anw.getResult(); } catch (Exception e) { s_logger.warn("Cannot prepare PXE server", e); return false; } }