/**
  * @param networks
  * @param offerings
  * @throws ConcurrentOperationException
  */
 private void mockMgrs() throws ConcurrentOperationException {
   final Service service = Service.Connectivity;
   testNetwork.setState(Network.State.Implementing);
   testNetwork.setTrafficType(TrafficType.Guest);
   when(_networkMdl.isProviderEnabledInPhysicalNetwork(0L, "VirtualRouter")).thenReturn(true);
   when(_networkMdl.isProviderSupportServiceInNetwork(
           testNetwork.getId(), service, Network.Provider.VirtualRouter))
       .thenReturn(true);
   when(_networkMdl.isProviderForNetwork(Network.Provider.VirtualRouter, 0L)).thenReturn(true);
   when(testVMProfile.getType()).thenReturn(VirtualMachine.Type.User);
   when(testVMProfile.getHypervisorType()).thenReturn(HypervisorType.XenServer);
   final List<NetworkVO> networks = new ArrayList<NetworkVO>(1);
   networks.add(testNetwork);
   final List<NetworkOfferingVO> offerings = new ArrayList<NetworkOfferingVO>(1);
   offerings.add(testOffering);
   doReturn(offerings)
       .when(_networkModel)
       .getSystemAccountNetworkOfferings(NetworkOffering.SystemControlNetwork);
   doReturn(networks)
       .when(_networkMgr)
       .setupNetwork(
           any(Account.class),
           any(NetworkOffering.class),
           any(DeploymentPlan.class),
           any(String.class),
           any(String.class),
           anyBoolean());
   // being anti-social and testing my own case first
   doReturn(HypervisorType.XenServer).when(_resourceMgr).getDefaultHypervisor(anyLong());
   doReturn(new AccountVO()).when(_accountMgr).getAccount(testNetwork.getAccountId());
 }
  @Override
  public boolean finalizeCommandsOnStart(
      Commands cmds, VirtualMachineProfile<SecondaryStorageVmVO> profile) {

    NicProfile managementNic = null;
    NicProfile controlNic = null;
    for (NicProfile nic : profile.getNics()) {
      if (nic.getTrafficType() == TrafficType.Management) {
        managementNic = nic;
      } else if (nic.getTrafficType() == TrafficType.Control && nic.getIp4Address() != null) {
        controlNic = nic;
      }
    }

    if (controlNic == null) {
      if (managementNic == null) {
        s_logger.error(
            "Management network doesn't exist for the secondaryStorageVm "
                + profile.getVirtualMachine());
        return false;
      }
      controlNic = managementNic;
    }

    CheckSshCommand check =
        new CheckSshCommand(profile.getInstanceName(), controlNic.getIp4Address(), 3922, 5, 20);
    cmds.addCommand("checkSsh", check);

    return true;
  }
  @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;
  }
  @Override
  public boolean finalizeDeployment(
      Commands cmds,
      VirtualMachineProfile<SecondaryStorageVmVO> profile,
      DeployDestination dest,
      ReservationContext context) {

    finalizeCommandsOnStart(cmds, profile);

    SecondaryStorageVmVO secVm = profile.getVirtualMachine();
    DataCenter dc = dest.getDataCenter();
    List<NicProfile> nics = profile.getNics();
    for (NicProfile nic : nics) {
      if ((nic.getTrafficType() == TrafficType.Public
              && dc.getNetworkType() == NetworkType.Advanced)
          || (nic.getTrafficType() == TrafficType.Guest
              && (dc.getNetworkType() == NetworkType.Basic || dc.isSecurityGroupEnabled()))) {
        secVm.setPublicIpAddress(nic.getIp4Address());
        secVm.setPublicNetmask(nic.getNetmask());
        secVm.setPublicMacAddress(nic.getMacAddress());
      } else if (nic.getTrafficType() == TrafficType.Management) {
        secVm.setPrivateIpAddress(nic.getIp4Address());
        secVm.setPrivateMacAddress(nic.getMacAddress());
      }
    }
    _secStorageVmDao.update(secVm.getId(), secVm);
    return true;
  }
  @Override
  public boolean finalizeDeployment(
      Commands cmds,
      VirtualMachineProfile<DomainRouterVO> profile,
      DeployDestination dest,
      ReservationContext context)
      throws ResourceUnavailableException {
    DomainRouterVO elbVm = profile.getVirtualMachine();

    List<NicProfile> nics = profile.getNics();
    for (NicProfile nic : nics) {
      if (nic.getTrafficType() == TrafficType.Public) {
        elbVm.setPublicIpAddress(nic.getIp4Address());
        elbVm.setPublicNetmask(nic.getNetmask());
        elbVm.setPublicMacAddress(nic.getMacAddress());
      } else if (nic.getTrafficType() == TrafficType.Control) {
        elbVm.setPrivateIpAddress(nic.getIp4Address());
        elbVm.setPrivateMacAddress(nic.getMacAddress());
      }
    }
    _routerDao.update(elbVm.getId(), elbVm);

    finalizeCommandsOnStart(cmds, profile);
    return true;
  }
  @Test
  public void testZoneWideStorageAllocator() {
    try {
      createDb();

      StoragePoolVO pool = storagePoolDao.findById(storagePoolId);
      pool.setScope(ScopeType.ZONE);
      storagePoolDao.update(pool.getId(), pool);

      DiskProfile profile = new DiskProfile(volume, diskOffering, HypervisorType.KVM);
      VirtualMachineProfile vmProfile = Mockito.mock(VirtualMachineProfile.class);
      Mockito.when(vmProfile.getHypervisorType()).thenReturn(HypervisorType.KVM);
      Mockito.when(
              storageMgr.storagePoolHasEnoughSpace(
                  Mockito.anyListOf(Volume.class), Mockito.any(StoragePool.class)))
          .thenReturn(true);
      DeploymentPlan plan = new DataCenterDeployment(dcId, podId, clusterId, null, null, null);
      int foundAcct = 0;
      for (StoragePoolAllocator allocator : allocators) {
        List<StoragePool> pools =
            allocator.allocateToPool(profile, vmProfile, plan, new ExcludeList(), 1);
        if (!pools.isEmpty()) {
          Assert.assertEquals(pools.get(0).getId(), storage.getId());
          foundAcct++;
        }
      }

      if (foundAcct > 1 || foundAcct == 0) {
        Assert.fail();
      }
    } catch (Exception e) {
      cleanDb();
      Assert.fail();
    }
  }
  @Override
  public boolean finalizeVirtualMachineProfile(
      final VirtualMachineProfile profile,
      final DeployDestination dest,
      final ReservationContext context) {
    final DomainRouterVO domainRouterVO = _routerDao.findById(profile.getId());

    final Long vpcId = domainRouterVO.getVpcId();

    if (vpcId != null) {
      if (domainRouterVO.getState() == State.Starting
          || domainRouterVO.getState() == State.Running) {
        String defaultDns1 = null;
        String defaultDns2 = null;
        // remove public and guest nics as we will plug them later
        final Iterator<NicProfile> it = profile.getNics().iterator();
        while (it.hasNext()) {
          final NicProfile nic = it.next();
          if (nic.getTrafficType() == TrafficType.Public
              || nic.getTrafficType() == TrafficType.Guest) {
            // save dns information
            if (nic.getTrafficType() == TrafficType.Public) {
              defaultDns1 = nic.getIPv4Dns1();
              defaultDns2 = nic.getIPv4Dns2();
            }
            s_logger.debug(
                "Removing nic "
                    + nic
                    + " of type "
                    + nic.getTrafficType()
                    + " from the nics passed on vm start. "
                    + "The nic will be plugged later");
            it.remove();
          }
        }

        // add vpc cidr/dns/networkdomain to the boot load args
        final StringBuilder buf = profile.getBootArgsBuilder();
        final Vpc vpc = _entityMgr.findById(Vpc.class, vpcId);
        buf.append(" vpccidr=" + vpc.getCidr() + " domain=" + vpc.getNetworkDomain());

        buf.append(" dns1=").append(defaultDns1);
        if (defaultDns2 != null) {
          buf.append(" dns2=").append(defaultDns2);
        }
      }
    }

    return super.finalizeVirtualMachineProfile(profile, dest, context);
  }
  @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());
  }
  private List<String> parseKickstartUrl(VirtualMachineProfile profile) {
    String tpl = profile.getTemplate().getUrl();
    assert tpl != null : "How can a null template get here!!!";
    String[] tpls = tpl.split(";");
    CloudRuntimeException err =
        new CloudRuntimeException(
            String.format(
                "template url[%s] is not correctly encoded. it must be in format of ks=http_link_to_kickstartfile;kernel=nfs_path_to_pxe_kernel;initrd=nfs_path_to_pxe_initrd",
                tpl));
    if (tpls.length != 3) {
      throw err;
    }

    String ks = null;
    String kernel = null;
    String initrd = null;

    for (String t : tpls) {
      String[] kv = t.split("=");
      if (kv.length != 2) {
        throw err;
      }
      if (kv[0].equals("ks")) {
        ks = kv[1];
      } else if (kv[0].equals("kernel")) {
        kernel = kv[1];
      } else if (kv[0].equals("initrd")) {
        initrd = kv[1];
      } else {
        throw err;
      }
    }

    return Arrays.asList(ks, kernel, initrd);
  }
 @Override
 public void finalizeStop(VirtualMachineProfile<DomainRouterVO> profile, StopAnswer answer) {
   if (answer != null) {
     VMInstanceVO vm = profile.getVirtualMachine();
     DomainRouterVO elbVm = _routerDao.findById(vm.getId());
     processStopOrRebootAnswer(elbVm, answer);
   }
 }
  @Override
  public VirtualMachineTO implement(VirtualMachineProfile vm) {
    VirtualMachineTO to = toVirtualMachineTO(vm);

    VMInstanceVO vo = _vmDao.findById(vm.getId());
    if (vo.getLastHostId() == null) {
      to.setBootArgs(BaremetalManager.DO_PXE);
    }

    Map<String, String> details = new HashMap<String, String>();
    details.put("template", vm.getTemplate().getUrl());
    to.setDetails(details);

    // Determine the VM's OS description
    GuestOSVO guestOS = _guestOsDao.findById(vm.getVirtualMachine().getGuestOSId());
    to.setOs(guestOS.getDisplayName());

    return to;
  }
 @Override
 public void finalizeStop(final VirtualMachineProfile profile, final Answer answer) {
   super.finalizeStop(profile, answer);
   // Mark VPN connections as Disconnected
   final DomainRouterVO router = _routerDao.findById(profile.getId());
   final Long vpcId = router.getVpcId();
   if (vpcId != null) {
     _s2sVpnMgr.markDisconnectVpnConnByVpc(vpcId);
   }
 }
  @Override
  public boolean release(
      NicProfile nic, VirtualMachineProfile<? extends VirtualMachine> vm, String reservationId) {
    assert nic.getTrafficType() == TrafficType.Control;

    if (vm.getHypervisorType() == HypervisorType.VmWare
        && vm.getType() == VirtualMachine.Type.DomainRouter) {
      super.release(nic, vm, reservationId);
      return true;
    }

    _dcDao.releaseLinkLocalIpAddress(nic.getId(), reservationId);
    nic.setIp4Address(null);
    nic.setMacAddress(null);
    nic.setNetmask(null);
    nic.setFormat(null);
    nic.setGateway(null);

    return true;
  }
  @Override
  public NicProfile allocate(
      Network config, NicProfile nic, VirtualMachineProfile<? extends VirtualMachine> vm)
      throws InsufficientVirtualNetworkCapcityException, InsufficientAddressCapacityException {

    if (config.getTrafficType() != TrafficType.Control) {
      return null;
    }

    if (vm.getHypervisorType() == HypervisorType.VmWare
        && vm.getType() != VirtualMachine.Type.DomainRouter) {
      NicProfile nicProf = new NicProfile(ReservationStrategy.Create, null, null, null, null);
      String mac = _networkMgr.getNextAvailableMacAddressInNetwork(config.getId());
      nicProf.setMacAddress(mac);
      return nicProf;
    }

    if (nic != null) {
      throw new CloudRuntimeException("Does not support nic specification at this time: " + nic);
    }

    return new NicProfile(ReservationStrategy.Start, null, null, null, null);
  }
  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 boolean prepare(
      Network network,
      NicProfile nic,
      VirtualMachineProfile vm,
      DeployDestination dest,
      ReservationContext context)
      throws ConcurrentOperationException, ResourceUnavailableException,
          InsufficientCapacityException {
    if (vm.getType() != Type.User) {
      return false;
    }

    // ensure that there is an ASA 1000v assigned to this network
    NetworkAsa1000vMapVO asaForNetwork = _networkAsa1000vMapDao.findByNetworkId(network.getId());
    if (asaForNetwork == null) {
      return false;
    }

    return true;
  }
Example #17
0
  @Override
  public boolean release(
      final Network network,
      final NicProfile nic,
      final VirtualMachineProfile vm,
      final ReservationContext context)
      throws ConcurrentOperationException, ResourceUnavailableException {
    if (!canHandle(network, Service.Connectivity)) {
      return false;
    }
    if (nic.getBroadcastType() != Networks.BroadcastDomainType.Vswitch) {
      return false;
    }

    if (nic.getTrafficType() != Networks.TrafficType.Guest) {
      return false;
    }

    final HostVO host = _hostDao.findById(vm.getVirtualMachine().getHostId());
    _ovsTunnelMgr.checkAndRemoveHostFromTunnelNetwork(network, host);
    return true;
  }
  protected void getIp(
      NicProfile nic,
      DataCenter dc,
      VirtualMachineProfile<? extends VirtualMachine> vm,
      Network network)
      throws InsufficientVirtualNetworkCapcityException, InsufficientAddressCapacityException,
          ConcurrentOperationException {
    if (nic.getIp4Address() == null) {
      PublicIp ip =
          _networkMgr.assignPublicIpAddress(
              dc.getId(),
              vm.getOwner(),
              dc.getNetworkType().equals(NetworkType.Basic)
                  ? VlanType.DirectAttached
                  : VlanType.VirtualNetwork,
              null);
      nic.setIp4Address(ip.getAddress().toString());
      nic.setGateway(ip.getGateway());
      nic.setNetmask(ip.getNetmask());
      if (ip.getVlanTag() != null && ip.getVlanTag().equalsIgnoreCase("untagged")) {
        nic.setIsolationUri(URI.create("vlan://untagged"));
        nic.setBroadcastUri(URI.create("vlan://untagged"));
        nic.setBroadcastType(BroadcastDomainType.Native);
      } else if (ip.getVlanTag() != null) {
        nic.setIsolationUri(IsolationType.Vlan.toUri(ip.getVlanTag()));
        nic.setBroadcastUri(IsolationType.Vlan.toUri(ip.getVlanTag()));
        nic.setBroadcastType(BroadcastDomainType.Vlan);
      }

      nic.setFormat(AddressFormat.Ip4);
      nic.setReservationId(String.valueOf(ip.getVlanTag()));
      nic.setMacAddress(ip.getMacAddress());
    }
    nic.setDns1(dc.getDns1());
    nic.setDns2(dc.getDns2());
  }
  @Override
  public boolean finalizeCommandsOnStart(
      Commands cmds, VirtualMachineProfile<DomainRouterVO> profile) {
    DomainRouterVO elbVm = profile.getVirtualMachine();
    DataCenterVO dcVo = _dcDao.findById(elbVm.getDataCenterId());

    NicProfile controlNic = null;
    Long guestNetworkId = null;

    if (profile.getHypervisorType() == HypervisorType.VMware
        && dcVo.getNetworkType() == NetworkType.Basic) {
      // TODO this is a ugly to test hypervisor type here
      // for basic network mode, we will use the guest NIC for control NIC
      for (NicProfile nic : profile.getNics()) {
        if (nic.getTrafficType() == TrafficType.Guest && nic.getIp4Address() != null) {
          controlNic = nic;
          guestNetworkId = nic.getNetworkId();
        }
      }
    } else {
      for (NicProfile nic : profile.getNics()) {
        if (nic.getTrafficType() == TrafficType.Control && nic.getIp4Address() != null) {
          controlNic = nic;
        } else if (nic.getTrafficType() == TrafficType.Guest) {
          guestNetworkId = nic.getNetworkId();
        }
      }
    }

    if (controlNic == null) {
      s_logger.error("Control network doesn't exist for the ELB vm " + elbVm);
      return false;
    }

    cmds.addCommand(
        "checkSsh",
        new CheckSshCommand(profile.getInstanceName(), controlNic.getIp4Address(), 3922));

    // Re-apply load balancing rules
    List<LoadBalancerVO> lbs = _elbVmMapDao.listLbsForElbVm(elbVm.getId());
    List<LoadBalancingRule> lbRules = new ArrayList<LoadBalancingRule>();
    for (LoadBalancerVO lb : lbs) {
      List<LbDestination> dstList = _lbMgr.getExistingDestinations(lb.getId());
      List<LbStickinessPolicy> policyList = _lbMgr.getStickinessPolicies(lb.getId());
      List<LbHealthCheckPolicy> hcPolicyList = _lbMgr.getHealthCheckPolicies(lb.getId());
      LoadBalancingRule loadBalancing =
          new LoadBalancingRule(lb, dstList, policyList, hcPolicyList);
      lbRules.add(loadBalancing);
    }

    s_logger.debug(
        "Found "
            + lbRules.size()
            + " load balancing rule(s) to apply as a part of ELB vm "
            + elbVm
            + " start.");
    if (!lbRules.isEmpty()) {
      createApplyLoadBalancingRulesCommands(lbRules, elbVm, cmds, guestNetworkId);
    }

    return true;
  }
  @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;
  }
  @Override
  public boolean finalizeVirtualMachineProfile(
      VirtualMachineProfile<SecondaryStorageVmVO> profile,
      DeployDestination dest,
      ReservationContext context) {

    SecondaryStorageVmVO vm = profile.getVirtualMachine();
    Map<String, String> details = _vmDetailsDao.findDetails(vm.getId());
    vm.setDetails(details);

    HostVO secHost = _hostDao.findSecondaryStorageHost(dest.getDataCenter().getId());
    assert (secHost != null);

    StringBuilder buf = profile.getBootArgsBuilder();
    buf.append(" template=domP type=secstorage");
    buf.append(" host=").append(_mgmt_host);
    buf.append(" port=").append(_mgmt_port);
    buf.append(" name=").append(profile.getVirtualMachine().getHostName());

    buf.append(" zone=").append(dest.getDataCenter().getId());
    buf.append(" pod=").append(dest.getPod().getId());

    buf.append(" guid=").append(profile.getVirtualMachine().getHostName());

    if (_configDao.isPremium()) {
      if (profile.getHypervisorType() == HypervisorType.Hyperv) {
        buf.append(" resource=com.cloud.storage.resource.CifsSecondaryStorageResource");
      } else {
        buf.append(" resource=com.cloud.storage.resource.PremiumSecondaryStorageResource");
      }
    } else {
      buf.append(" resource=com.cloud.storage.resource.NfsSecondaryStorageResource");
    }
    buf.append(" instance=SecStorage");
    buf.append(" sslcopy=").append(Boolean.toString(_useSSlCopy));
    buf.append(" role=").append(profile.getVirtualMachine().getRole().toString());

    boolean externalDhcp = false;
    String externalDhcpStr =
        _configDao.getValue("direct.attach.network.externalIpAllocator.enabled");
    if (externalDhcpStr != null && externalDhcpStr.equalsIgnoreCase("true")) {
      externalDhcp = true;
    }

    for (NicProfile nic : profile.getNics()) {
      int deviceId = nic.getDeviceId();
      if (nic.getIp4Address() == null) {
        buf.append(" eth").append(deviceId).append("mask=").append("0.0.0.0");
        buf.append(" eth").append(deviceId).append("ip=").append("0.0.0.0");
      } else {
        buf.append(" eth").append(deviceId).append("ip=").append(nic.getIp4Address());
        buf.append(" eth").append(deviceId).append("mask=").append(nic.getNetmask());
      }

      buf.append(" eth").append(deviceId).append("mask=").append(nic.getNetmask());
      if (nic.isDefaultNic()) {
        buf.append(" gateway=").append(nic.getGateway());
      }
      if (nic.getTrafficType() == TrafficType.Management) {
        String mgmt_cidr = _configDao.getValue(Config.ManagementNetwork.key());
        if (NetUtils.isValidCIDR(mgmt_cidr)) {
          buf.append(" mgmtcidr=").append(mgmt_cidr);
        }
        buf.append(" localgw=").append(dest.getPod().getGateway());
        buf.append(" private.network.device=").append("eth").append(deviceId);
      } else if (nic.getTrafficType() == TrafficType.Public) {
        buf.append(" public.network.device=").append("eth").append(deviceId);
      }
    }

    /* External DHCP mode */
    if (externalDhcp) {
      buf.append(" bootproto=dhcp");
    }

    DataCenterVO dc = _dcDao.findById(profile.getVirtualMachine().getDataCenterIdToDeployIn());
    buf.append(" internaldns1=").append(dc.getInternalDns1());
    if (dc.getInternalDns2() != null) {
      buf.append(" internaldns2=").append(dc.getInternalDns2());
    }
    buf.append(" dns1=").append(dc.getDns1());
    if (dc.getDns2() != null) {
      buf.append(" dns2=").append(dc.getDns2());
    }

    String bootArgs = buf.toString();
    if (s_logger.isDebugEnabled()) {
      s_logger.debug("Boot Args for " + profile + ": " + bootArgs);
    }

    return true;
  }
  @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;
    }
  }
 @Override
 public void VmCheckAndCreateTunnel(
     VirtualMachineProfile<? extends VirtualMachine> vm, DeployDestination dest) {
   CheckAndCreateTunnel(vm.getVirtualMachine(), dest);
 }
  @Override
  public boolean finalizeCommandsOnStart(final Commands cmds, final VirtualMachineProfile profile) {
    final DomainRouterVO domainRouterVO = _routerDao.findById(profile.getId());

    final boolean isVpc = domainRouterVO.getVpcId() != null;
    if (!isVpc) {
      return super.finalizeCommandsOnStart(cmds, profile);
    }

    if (domainRouterVO.getState() == State.Starting || domainRouterVO.getState() == State.Running) {
      // 1) FORM SSH CHECK COMMAND
      final NicProfile controlNic = getControlNic(profile);
      if (controlNic == null) {
        s_logger.error("Control network doesn't exist for the router " + domainRouterVO);
        return false;
      }

      finalizeSshAndVersionAndNetworkUsageOnStart(cmds, profile, domainRouterVO, controlNic);

      // 2) FORM PLUG NIC COMMANDS
      final List<Pair<Nic, Network>> guestNics = new ArrayList<Pair<Nic, Network>>();
      final List<Pair<Nic, Network>> publicNics = new ArrayList<Pair<Nic, Network>>();
      final Map<String, String> vlanMacAddress = new HashMap<String, String>();

      final List<? extends Nic> routerNics = _nicDao.listByVmId(profile.getId());
      for (final Nic routerNic : routerNics) {
        final Network network = _networkModel.getNetwork(routerNic.getNetworkId());
        if (network.getTrafficType() == TrafficType.Guest) {
          final Pair<Nic, Network> guestNic = new Pair<Nic, Network>(routerNic, network);
          guestNics.add(guestNic);
        } else if (network.getTrafficType() == TrafficType.Public) {
          final Pair<Nic, Network> publicNic = new Pair<Nic, Network>(routerNic, network);
          publicNics.add(publicNic);
          final String vlanTag = BroadcastDomainType.getValue(routerNic.getBroadcastUri());
          vlanMacAddress.put(vlanTag, routerNic.getMacAddress());
        }
      }

      final List<Command> usageCmds = new ArrayList<Command>();

      // 3) PREPARE PLUG NIC COMMANDS
      try {
        // add VPC router to public networks
        final List<PublicIp> sourceNat = new ArrayList<PublicIp>(1);
        for (final Pair<Nic, Network> nicNtwk : publicNics) {
          final Nic publicNic = nicNtwk.first();
          final Network publicNtwk = nicNtwk.second();
          final IPAddressVO userIp =
              _ipAddressDao.findByIpAndSourceNetworkId(
                  publicNtwk.getId(), publicNic.getIPv4Address());

          if (userIp.isSourceNat()) {
            final PublicIp publicIp =
                PublicIp.createFromAddrAndVlan(userIp, _vlanDao.findById(userIp.getVlanId()));
            sourceNat.add(publicIp);

            if (domainRouterVO.getPublicIpAddress() == null) {
              final DomainRouterVO routerVO = _routerDao.findById(domainRouterVO.getId());
              routerVO.setPublicIpAddress(publicNic.getIPv4Address());
              routerVO.setPublicNetmask(publicNic.getIPv4Netmask());
              routerVO.setPublicMacAddress(publicNic.getMacAddress());
              _routerDao.update(routerVO.getId(), routerVO);
            }
          }
          final PlugNicCommand plugNicCmd =
              new PlugNicCommand(
                  _nwHelper.getNicTO(
                      domainRouterVO,
                      publicNic.getNetworkId(),
                      publicNic.getBroadcastUri().toString()),
                  domainRouterVO.getInstanceName(),
                  domainRouterVO.getType());
          cmds.addCommand(plugNicCmd);
          final VpcVO vpc = _vpcDao.findById(domainRouterVO.getVpcId());
          final NetworkUsageCommand netUsageCmd =
              new NetworkUsageCommand(
                  domainRouterVO.getPrivateIpAddress(),
                  domainRouterVO.getInstanceName(),
                  true,
                  publicNic.getIPv4Address(),
                  vpc.getCidr());
          usageCmds.add(netUsageCmd);
          UserStatisticsVO stats =
              _userStatsDao.findBy(
                  domainRouterVO.getAccountId(),
                  domainRouterVO.getDataCenterId(),
                  publicNtwk.getId(),
                  publicNic.getIPv4Address(),
                  domainRouterVO.getId(),
                  domainRouterVO.getType().toString());
          if (stats == null) {
            stats =
                new UserStatisticsVO(
                    domainRouterVO.getAccountId(),
                    domainRouterVO.getDataCenterId(),
                    publicNic.getIPv4Address(),
                    domainRouterVO.getId(),
                    domainRouterVO.getType().toString(),
                    publicNtwk.getId());
            _userStatsDao.persist(stats);
          }
        }

        // create ip assoc for source nat
        if (!sourceNat.isEmpty()) {
          _commandSetupHelper.createVpcAssociatePublicIPCommands(
              domainRouterVO, sourceNat, cmds, vlanMacAddress);
        }

        // add VPC router to guest networks
        for (final Pair<Nic, Network> nicNtwk : guestNics) {
          final Nic guestNic = nicNtwk.first();
          // plug guest nic
          final PlugNicCommand plugNicCmd =
              new PlugNicCommand(
                  _nwHelper.getNicTO(domainRouterVO, guestNic.getNetworkId(), null),
                  domainRouterVO.getInstanceName(),
                  domainRouterVO.getType());
          cmds.addCommand(plugNicCmd);
          if (!_networkModel.isPrivateGateway(guestNic.getNetworkId())) {
            // set guest network
            final VirtualMachine vm = _vmDao.findById(domainRouterVO.getId());
            final NicProfile nicProfile =
                _networkModel.getNicProfile(vm, guestNic.getNetworkId(), null);
            final SetupGuestNetworkCommand setupCmd =
                _commandSetupHelper.createSetupGuestNetworkCommand(
                    domainRouterVO, true, nicProfile);
            cmds.addCommand(setupCmd);
          } else {

            // set private network
            final PrivateIpVO ipVO =
                _privateIpDao.findByIpAndSourceNetworkId(
                    guestNic.getNetworkId(), guestNic.getIPv4Address());
            final Network network = _networkDao.findById(guestNic.getNetworkId());
            BroadcastDomainType.getValue(network.getBroadcastUri());
            final String netmask = NetUtils.getCidrNetmask(network.getCidr());
            final PrivateIpAddress ip =
                new PrivateIpAddress(
                    ipVO,
                    network.getBroadcastUri().toString(),
                    network.getGateway(),
                    netmask,
                    guestNic.getMacAddress());

            final List<PrivateIpAddress> privateIps = new ArrayList<PrivateIpAddress>(1);
            privateIps.add(ip);
            _commandSetupHelper.createVpcAssociatePrivateIPCommands(
                domainRouterVO, privateIps, cmds, true);

            final Long privateGwAclId =
                _vpcGatewayDao.getNetworkAclIdForPrivateIp(
                    ipVO.getVpcId(), ipVO.getNetworkId(), ipVO.getIpAddress());

            if (privateGwAclId != null) {
              // set network acl on private gateway
              final List<NetworkACLItemVO> networkACLs =
                  _networkACLItemDao.listByACL(privateGwAclId);
              s_logger.debug(
                  "Found "
                      + networkACLs.size()
                      + " network ACLs to apply as a part of VPC VR "
                      + domainRouterVO
                      + " start for private gateway ip = "
                      + ipVO.getIpAddress());

              _commandSetupHelper.createNetworkACLsCommands(
                  networkACLs, domainRouterVO, cmds, ipVO.getNetworkId(), true);
            }
          }
        }
      } catch (final Exception ex) {
        s_logger.warn(
            "Failed to add router " + domainRouterVO + " to network due to exception ", ex);
        return false;
      }

      // 4) RE-APPLY ALL STATIC ROUTE RULES
      final List<? extends StaticRoute> routes =
          _staticRouteDao.listByVpcId(domainRouterVO.getVpcId());
      final List<StaticRouteProfile> staticRouteProfiles =
          new ArrayList<StaticRouteProfile>(routes.size());
      final Map<Long, VpcGateway> gatewayMap = new HashMap<Long, VpcGateway>();
      for (final StaticRoute route : routes) {
        VpcGateway gateway = gatewayMap.get(route.getVpcGatewayId());
        if (gateway == null) {
          gateway = _entityMgr.findById(VpcGateway.class, route.getVpcGatewayId());
          gatewayMap.put(gateway.getId(), gateway);
        }
        staticRouteProfiles.add(new StaticRouteProfile(route, gateway));
      }

      s_logger.debug(
          "Found "
              + staticRouteProfiles.size()
              + " static routes to apply as a part of vpc route "
              + domainRouterVO
              + " start");
      if (!staticRouteProfiles.isEmpty()) {
        _commandSetupHelper.createStaticRouteCommands(staticRouteProfiles, domainRouterVO, cmds);
      }

      // 5) RE-APPLY ALL REMOTE ACCESS VPNs
      final RemoteAccessVpnVO vpn =
          _vpnDao.findByAccountAndVpc(domainRouterVO.getAccountId(), domainRouterVO.getVpcId());
      if (vpn != null) {
        _commandSetupHelper.createApplyVpnCommands(true, vpn, domainRouterVO, cmds);
      }

      // 6) REPROGRAM GUEST NETWORK
      boolean reprogramGuestNtwks = true;
      if (profile.getParameter(Param.ReProgramGuestNetworks) != null
          && (Boolean) profile.getParameter(Param.ReProgramGuestNetworks) == false) {
        reprogramGuestNtwks = false;
      }

      final VirtualRouterProvider vrProvider =
          _vrProviderDao.findById(domainRouterVO.getElementId());
      if (vrProvider == null) {
        throw new CloudRuntimeException(
            "Cannot find related virtual router provider of router: "
                + domainRouterVO.getHostName());
      }
      final Provider provider = Network.Provider.getProvider(vrProvider.getType().toString());
      if (provider == null) {
        throw new CloudRuntimeException(
            "Cannot find related provider of virtual router provider: "
                + vrProvider.getType().toString());
      }

      for (final Pair<Nic, Network> nicNtwk : guestNics) {
        final Nic guestNic = nicNtwk.first();
        final AggregationControlCommand startCmd =
            new AggregationControlCommand(
                Action.Start,
                domainRouterVO.getInstanceName(),
                controlNic.getIPv4Address(),
                _routerControlHelper.getRouterIpInNetwork(
                    guestNic.getNetworkId(), domainRouterVO.getId()));
        cmds.addCommand(startCmd);
        if (reprogramGuestNtwks) {
          finalizeIpAssocForNetwork(
              cmds, domainRouterVO, provider, guestNic.getNetworkId(), vlanMacAddress);
          finalizeNetworkRulesForNetwork(cmds, domainRouterVO, provider, guestNic.getNetworkId());
        }

        finalizeUserDataAndDhcpOnStart(cmds, domainRouterVO, provider, guestNic.getNetworkId());
        final AggregationControlCommand finishCmd =
            new AggregationControlCommand(
                Action.Finish,
                domainRouterVO.getInstanceName(),
                controlNic.getIPv4Address(),
                _routerControlHelper.getRouterIpInNetwork(
                    guestNic.getNetworkId(), domainRouterVO.getId()));
        cmds.addCommand(finishCmd);
      }

      // Add network usage commands
      cmds.addCommands(usageCmds);
    }
    return true;
  }
  @Override
  public boolean addUserData(NicProfile nic, VirtualMachineProfile profile) {
    UserVmVO vm = _vmDao.findById(profile.getVirtualMachine().getId());
    _vmDao.loadDetails(vm);

    String serviceOffering =
        _serviceOfferingDao
            .findByIdIncludingRemoved(vm.getId(), vm.getServiceOfferingId())
            .getDisplayText();
    String zoneName = _dcDao.findById(vm.getDataCenterId()).getName();
    NicVO nvo = _nicDao.findById(nic.getId());
    VmDataCommand cmd =
        new VmDataCommand(
            nvo.getIPv4Address(), vm.getInstanceName(), _ntwkModel.getExecuteInSeqNtwkElmtCmd());
    // if you add new metadata files, also edit
    // systemvm/patches/debian/config/var/www/html/latest/.htaccess
    cmd.addVmData("userdata", "user-data", vm.getUserData());
    cmd.addVmData("metadata", "service-offering", StringUtils.unicodeEscape(serviceOffering));
    cmd.addVmData("metadata", "availability-zone", StringUtils.unicodeEscape(zoneName));
    cmd.addVmData("metadata", "local-ipv4", nic.getIPv4Address());
    cmd.addVmData("metadata", "local-hostname", StringUtils.unicodeEscape(vm.getInstanceName()));
    cmd.addVmData("metadata", "public-ipv4", nic.getIPv4Address());
    cmd.addVmData("metadata", "public-hostname", StringUtils.unicodeEscape(vm.getInstanceName()));
    cmd.addVmData("metadata", "instance-id", String.valueOf(vm.getId()));
    cmd.addVmData("metadata", "vm-id", String.valueOf(vm.getInstanceName()));
    cmd.addVmData("metadata", "public-keys", null);
    String cloudIdentifier = _configDao.getValue("cloud.identifier");
    if (cloudIdentifier == null) {
      cloudIdentifier = "";
    } else {
      cloudIdentifier = "CloudStack-{" + cloudIdentifier + "}";
    }
    cmd.addVmData("metadata", "cloud-identifier", cloudIdentifier);

    List<PhysicalNetworkVO> phys = _phynwDao.listByZone(vm.getDataCenterId());
    if (phys.isEmpty()) {
      throw new CloudRuntimeException(
          String.format("Cannot find physical network in zone %s", vm.getDataCenterId()));
    }
    if (phys.size() > 1) {
      throw new CloudRuntimeException(
          String.format(
              "Baremetal only supports one physical network in zone, but zone %s has %s physical networks",
              vm.getDataCenterId(), phys.size()));
    }
    PhysicalNetworkVO phy = phys.get(0);

    QueryBuilder<BaremetalPxeVO> sc = QueryBuilder.create(BaremetalPxeVO.class);
    // TODO: handle both kickstart and PING
    // sc.addAnd(sc.getEntity().getPodId(), Op.EQ, vm.getPodIdToDeployIn());
    sc.and(sc.entity().getPhysicalNetworkId(), Op.EQ, phy.getId());
    BaremetalPxeVO pxeVo = sc.find();
    if (pxeVo == null) {
      throw new CloudRuntimeException(
          "No PXE server found in pod: "
              + vm.getPodIdToDeployIn()
              + ", you need to add it before starting VM");
    }

    try {
      Answer ans = _agentMgr.send(pxeVo.getHostId(), cmd);
      if (!ans.getResult()) {
        s_logger.debug(
            String.format(
                "Add userdata to vm:%s failed because %s", vm.getInstanceName(), ans.getDetails()));
        return false;
      } else {
        return true;
      }
    } catch (Exception e) {
      s_logger.debug(String.format("Add userdata to vm:%s failed", vm.getInstanceName()), e);
      return false;
    }
  }
  private boolean preparePxeInAdvancedZone(
      VirtualMachineProfile profile,
      NicProfile nic,
      Network network,
      DeployDestination dest,
      ReservationContext context)
      throws Exception {
    DomainRouterVO vr = getVirtualRouter(network);
    List<NicVO> nics = _nicDao.listByVmId(vr.getId());
    NicVO mgmtNic = null;
    for (NicVO nicvo : nics) {
      if (ControlNetworkGuru.class.getSimpleName().equals(nicvo.getReserver())) {
        mgmtNic = nicvo;
        break;
      }
    }

    if (mgmtNic == null) {
      throw new CloudRuntimeException(
          String.format("cannot find management nic on virtual router[id:%s]", vr.getId()));
    }

    String internalServerIp = _configDao.getValue(Config.BaremetalInternalStorageServer.key());
    if (internalServerIp == null) {
      throw new CloudRuntimeException(
          String.format(
              "please specify 'baremetal.internal.storage.server.ip', which is the http server/nfs server storing kickstart files and ISO files, in global setting"));
    }

    List<String> tuple = parseKickstartUrl(profile);
    String cmd =
        String.format(
            "/usr/bin/prepare_pxe.sh %s %s %s %s %s %s",
            tuple.get(1),
            tuple.get(2),
            profile.getTemplate().getUuid(),
            String.format("01-%s", nic.getMacAddress().replaceAll(":", "-")).toLowerCase(),
            tuple.get(0),
            nic.getMacAddress().toLowerCase());
    s_logger.debug(
        String.format(
            "prepare pxe on virtual router[ip:%s], cmd: %s", mgmtNic.getIp4Address(), cmd));
    Pair<Boolean, String> ret =
        SshHelper.sshExecute(
            mgmtNic.getIp4Address(), 3922, "root", getSystemVMKeyFile(), null, cmd);
    if (!ret.first()) {
      throw new CloudRuntimeException(
          String.format(
              "failed preparing PXE in virtual router[id:%s], because %s",
              vr.getId(), ret.second()));
    }

    // String internalServerIp = "10.223.110.231";
    cmd =
        String.format(
            "/usr/bin/baremetal_snat.sh %s %s %s",
            mgmtNic.getIp4Address(), internalServerIp, mgmtNic.getGateway());
    s_logger.debug(
        String.format(
            "prepare SNAT on virtual router[ip:%s], cmd: %s", mgmtNic.getIp4Address(), cmd));
    ret =
        SshHelper.sshExecute(
            mgmtNic.getIp4Address(), 3922, "root", getSystemVMKeyFile(), null, cmd);
    if (!ret.first()) {
      throw new CloudRuntimeException(
          String.format(
              "failed preparing PXE in virtual router[id:%s], because %s",
              vr.getId(), ret.second()));
    }

    return true;
  }