private void createVmwareToolsIso() {
   String isoName = "vmware-tools.iso";
   VMTemplateVO tmplt = _tmpltDao.findByTemplateName(isoName);
   Long id;
   if (tmplt == null) {
     id = _tmpltDao.getNextInSequence(Long.class, "id");
     VMTemplateVO template =
         new VMTemplateVO(
             id,
             isoName,
             isoName,
             ImageFormat.ISO,
             true,
             true,
             TemplateType.PERHOST,
             null,
             null,
             true,
             64,
             Account.ACCOUNT_ID_SYSTEM,
             null,
             "VMware Tools Installer ISO",
             false,
             1,
             false,
             HypervisorType.VMware);
     _tmpltDao.persist(template);
   } else {
     id = tmplt.getId();
     tmplt.setTemplateType(TemplateType.PERHOST);
     tmplt.setUrl(null);
     _tmpltDao.update(id, tmplt);
   }
 }
  protected Void createTemplateAsyncCallback(
      AsyncCallbackDispatcher<? extends BaseImageStoreDriverImpl, DownloadAnswer> callback,
      CreateContext<CreateCmdResult> context) {
    if (s_logger.isDebugEnabled()) {
      s_logger.debug("Performing image store createTemplate async callback");
    }
    DownloadAnswer answer = callback.getResult();
    DataObject obj = context.data;
    DataStore store = obj.getDataStore();

    TemplateDataStoreVO tmpltStoreVO =
        _templateStoreDao.findByStoreTemplate(store.getId(), obj.getId());
    if (tmpltStoreVO != null) {
      if (tmpltStoreVO.getDownloadState() == VMTemplateStorageResourceAssoc.Status.DOWNLOADED) {
        if (s_logger.isDebugEnabled()) {
          s_logger.debug(
              "Template is already in DOWNLOADED state, ignore further incoming DownloadAnswer");
        }
        return null;
      }
      TemplateDataStoreVO updateBuilder = _templateStoreDao.createForUpdate();
      updateBuilder.setDownloadPercent(answer.getDownloadPct());
      updateBuilder.setDownloadState(answer.getDownloadStatus());
      updateBuilder.setLastUpdated(new Date());
      updateBuilder.setErrorString(answer.getErrorString());
      updateBuilder.setJobId(answer.getJobId());
      updateBuilder.setLocalDownloadPath(answer.getDownloadPath());
      updateBuilder.setInstallPath(answer.getInstallPath());
      updateBuilder.setSize(answer.getTemplateSize());
      updateBuilder.setPhysicalSize(answer.getTemplatePhySicalSize());
      _templateStoreDao.update(tmpltStoreVO.getId(), updateBuilder);
      // update size in vm_template table
      VMTemplateVO tmlptUpdater = _templateDao.createForUpdate();
      tmlptUpdater.setSize(answer.getTemplateSize());
      _templateDao.update(obj.getId(), tmlptUpdater);
    }

    AsyncCompletionCallback<CreateCmdResult> caller = context.getParentCallback();

    if (answer.getDownloadStatus() == VMTemplateStorageResourceAssoc.Status.DOWNLOAD_ERROR
        || answer.getDownloadStatus() == VMTemplateStorageResourceAssoc.Status.ABANDONED
        || answer.getDownloadStatus() == VMTemplateStorageResourceAssoc.Status.UNKNOWN) {
      CreateCmdResult result = new CreateCmdResult(null, null);
      result.setSuccess(false);
      result.setResult(answer.getErrorString());
      caller.complete(result);
    } else if (answer.getDownloadStatus() == VMTemplateStorageResourceAssoc.Status.DOWNLOADED) {
      if (answer.getCheckSum() != null) {
        VMTemplateVO templateDaoBuilder = _templateDao.createForUpdate();
        templateDaoBuilder.setChecksum(answer.getCheckSum());
        _templateDao.update(obj.getId(), templateDaoBuilder);
      }

      CreateCmdResult result = new CreateCmdResult(null, null);
      caller.complete(result);
    }
    return null;
  }
  private String generateCopyUrl(TemplateInfo srcTemplate) {
    DataStore srcStore = srcTemplate.getDataStore();
    EndPoint ep = _epSelector.select(srcTemplate);
    if (ep != null) {
      if (ep.getPublicAddr() == null) {
        s_logger.warn("A running secondary storage vm has a null public ip?");
        return null;
      }
      return generateCopyUrl(
          ep.getPublicAddr(),
          ((ImageStoreEntity) srcStore).getMountPoint(),
          srcTemplate.getInstallPath());
    }

    VMTemplateVO tmplt = _templateDao.findById(srcTemplate.getId());
    HypervisorType hyperType = tmplt.getHypervisorType();
    /*No secondary storage vm yet*/
    if (hyperType != null && hyperType == HypervisorType.KVM) {
      return "file://"
          + ((ImageStoreEntity) srcStore).getMountPoint()
          + "/"
          + srcTemplate.getInstallPath();
    }
    return null;
  }
 @Override
 public void addSystemVMTemplatesToSecondary(DataStore store) {
   long storeId = store.getId();
   List<VMTemplateVO> rtngTmplts = _templateDao.listAllSystemVMTemplates();
   for (VMTemplateVO tmplt : rtngTmplts) {
     TemplateDataStoreVO tmpltStore =
         _vmTemplateStoreDao.findByStoreTemplate(storeId, tmplt.getId());
     if (tmpltStore == null) {
       tmpltStore =
           new TemplateDataStoreVO(
               storeId,
               tmplt.getId(),
               new Date(),
               100,
               Status.DOWNLOADED,
               null,
               null,
               null,
               TemplateConstants.DEFAULT_SYSTEM_VM_TEMPLATE_PATH + tmplt.getId() + File.separator,
               tmplt.getUrl());
       tmpltStore.setSize(0L);
       tmpltStore.setPhysicalSize(0); // no size information for
       // pre-seeded system vm templates
       tmpltStore.setDataStoreRole(store.getRole());
       _vmTemplateStoreDao.persist(tmpltStore);
     }
   }
 }
 @Override
 public void addSystemVMTemplatesToHost(HostVO host, Map<String, TemplateInfo> templateInfos) {
   if (templateInfos == null) {
     return;
   }
   Long hostId = host.getId();
   List<VMTemplateVO> rtngTmplts = _templateDao.listAllSystemVMTemplates();
   for (VMTemplateVO tmplt : rtngTmplts) {
     TemplateInfo tmpltInfo = templateInfos.get(tmplt.getUniqueName());
     if (tmpltInfo == null) {
       continue;
     }
     VMTemplateHostVO tmpltHost = _vmTemplateHostDao.findByHostTemplate(hostId, tmplt.getId());
     if (tmpltHost == null) {
       tmpltHost =
           new VMTemplateHostVO(
               hostId,
               tmplt.getId(),
               new Date(),
               100,
               Status.DOWNLOADED,
               null,
               null,
               null,
               tmpltInfo.getInstallPath(),
               tmplt.getUrl());
       tmpltHost.setSize(tmpltInfo.getSize());
       tmpltHost.setPhysicalSize(tmpltInfo.getPhysicalSize());
       _vmTemplateHostDao.persist(tmpltHost);
     }
   }
 }
 private void initiateTemplateDownload(Long templateId, HostVO ssHost) {
   VMTemplateVO template = _templateDao.findById(templateId);
   if (template != null && (template.getUrl() != null)) {
     // find all storage hosts and tell them to initiate download
     downloadTemplateToStorage(template, ssHost);
   }
 }
  public TemplateProfile prepareDelete(DeleteTemplateCmd cmd) {
    Long templateId = cmd.getId();
    Long userId = UserContext.current().getCallerUserId();
    Account account = UserContext.current().getCaller();
    Long zoneId = cmd.getZoneId();

    VMTemplateVO template = _tmpltDao.findById(templateId.longValue());
    if (template == null) {
      throw new InvalidParameterValueException("unable to find template with id " + templateId);
    }

    userId =
        accountAndUserValidation(account, userId, null, template, "Unable to delete template ");

    UserVO user = _userDao.findById(userId);
    if (user == null) {
      throw new InvalidParameterValueException("Please specify a valid user.");
    }

    if (template.getFormat() == ImageFormat.ISO) {
      throw new InvalidParameterValueException("Please specify a valid template.");
    }

    return new TemplateProfile(userId, template, zoneId);
  }
  /** @param network */
  private void mockDAOs(final NetworkVO network, final NetworkOfferingVO offering) {
    when(_networkDao.acquireInLockTable(
            network.getId(), NetworkOrchestrationService.NetworkLockTimeout.value()))
        .thenReturn(network);
    when(_networksDao.acquireInLockTable(
            network.getId(), NetworkOrchestrationService.NetworkLockTimeout.value()))
        .thenReturn(network);
    when(_physicalProviderDao.findByServiceProvider(0L, "VirtualRouter"))
        .thenReturn(new PhysicalNetworkServiceProviderVO());
    when(_vrProviderDao.findByNspIdAndType(0L, Type.VirtualRouter))
        .thenReturn(new VirtualRouterProviderVO());
    when(_networkOfferingDao.findById(0L)).thenReturn(offering);
    // watchit: (in this test) there can be only one
    when(_routerDao.getNextInSequence(Long.class, "id")).thenReturn(0L);
    final ServiceOfferingVO svcoff =
        new ServiceOfferingVO(
            "name",
            /* cpu */ 1,
            /* ramsize */ 1024 * 1024,
            /* (clock?)speed */ 1024 * 1024 * 1024,
            /* rateMbps */ 1,
            /* multicastRateMbps */ 0,
            /* offerHA */ false,
            "displayText",
            ProvisioningType.THIN,
            /* useLocalStorage */ false,
            /* recreatable */ false,
            "tags",
            /* systemUse */ false,
            VirtualMachine.Type.DomainRouter,
            /* defaultUse */ false);
    when(_serviceOfferingDao.findById(0L)).thenReturn(svcoff);
    final DomainRouterVO router =
        new DomainRouterVO(
            /* id */ 1L,
            /* serviceOfferingId */ 1L,
            /* elementId */ 0L,
            "name",
            /* templateId */ 0L,
            HypervisorType.XenServer,
            /* guestOSId */ 0L,
            /* domainId */ 0L,
            /* accountId */ 1L,
            /* userId */ 1L,
            /* isRedundantRouter */ false,
            RedundantState.UNKNOWN,
            /* haEnabled */ false,
            /* stopPending */ false,
            /* vpcId */ null);

    when(_routerDao.getNextInSequence(Long.class, "id")).thenReturn(1L);
    when(_templateDao.findRoutingTemplate(
            HypervisorType.XenServer, "SystemVM Template (XenServer)"))
        .thenReturn(new VMTemplateVO());
    when(_routerDao.persist(any(DomainRouterVO.class))).thenReturn(router);
    when(_routerDao.findById(router.getId())).thenReturn(router);
  }
  @Override
  public void handleSysTemplateDownload(HostVO host) {
    List<HypervisorType> hypers =
        _resourceMgr.listAvailHypervisorInZone(host.getId(), host.getDataCenterId());
    HypervisorType hostHyper = host.getHypervisorType();
    if (hypers.contains(hostHyper)) {
      return;
    }

    Set<VMTemplateVO> toBeDownloaded = new HashSet<VMTemplateVO>();
    List<HostVO> ssHosts =
        _resourceMgr.listAllUpAndEnabledHostsInOneZoneByType(
            Host.Type.SecondaryStorage, host.getDataCenterId());
    if (ssHosts == null || ssHosts.isEmpty()) {
      return;
    }
    /*Download all the templates in zone with the same hypervisortype*/
    for (HostVO ssHost : ssHosts) {
      List<VMTemplateVO> rtngTmplts = _templateDao.listAllSystemVMTemplates();
      List<VMTemplateVO> defaultBuiltin = _templateDao.listDefaultBuiltinTemplates();

      for (VMTemplateVO rtngTmplt : rtngTmplts) {
        if (rtngTmplt.getHypervisorType() == hostHyper) {
          toBeDownloaded.add(rtngTmplt);
        }
      }

      for (VMTemplateVO builtinTmplt : defaultBuiltin) {
        if (builtinTmplt.getHypervisorType() == hostHyper) {
          toBeDownloaded.add(builtinTmplt);
        }
      }

      for (VMTemplateVO template : toBeDownloaded) {
        VMTemplateHostVO tmpltHost =
            _vmTemplateHostDao.findByHostTemplate(ssHost.getId(), template.getId());
        if (tmpltHost == null || tmpltHost.getDownloadState() != Status.DOWNLOADED) {
          downloadTemplateToStorage(template, ssHost);
        }
      }
    }
  }
  @Override
  public void handleSysTemplateDownload(HypervisorType hostHyper, Long dcId) {
    Set<VMTemplateVO> toBeDownloaded = new HashSet<VMTemplateVO>();
    List<DataStore> stores = _storeMgr.getImageStoresByScope(new ZoneScope(dcId));
    if (stores == null || stores.isEmpty()) {
      return;
    }

    /* Download all the templates in zone with the same hypervisortype */
    for (DataStore store : stores) {
      List<VMTemplateVO> rtngTmplts = _templateDao.listAllSystemVMTemplates();
      List<VMTemplateVO> defaultBuiltin = _templateDao.listDefaultBuiltinTemplates();

      for (VMTemplateVO rtngTmplt : rtngTmplts) {
        if (rtngTmplt.getHypervisorType() == hostHyper) {
          toBeDownloaded.add(rtngTmplt);
        }
      }

      for (VMTemplateVO builtinTmplt : defaultBuiltin) {
        if (builtinTmplt.getHypervisorType() == hostHyper) {
          toBeDownloaded.add(builtinTmplt);
        }
      }

      for (VMTemplateVO template : toBeDownloaded) {
        TemplateDataStoreVO tmpltHost =
            _vmTemplateStoreDao.findByStoreTemplate(store.getId(), template.getId());
        if (tmpltHost == null
            || tmpltHost.getState() != ObjectInDataStoreStateMachine.State.Ready) {
          associateTemplateToZone(template.getId(), dcId);
          s_logger.info(
              "Downloading builtin template "
                  + template.getUniqueName()
                  + " to data center: "
                  + dcId);
          TemplateInfo tmplt = _templateFactory.getTemplate(template.getId(), DataStoreRole.Image);
          createTemplateAsync(tmplt, store, null);
        }
      }
    }
  }
  private void checksumSync(long hostId) {
    SearchCriteria<VMTemplateHostVO> sc = ReadyTemplateStatesSearch.create();
    sc.setParameters(
        "download_state", com.cloud.storage.VMTemplateStorageResourceAssoc.Status.DOWNLOADED);
    sc.setParameters("host_id", hostId);

    List<VMTemplateHostVO> templateHostRefList = _vmTemplateHostDao.search(sc, null);
    s_logger.debug(
        "Found "
            + templateHostRefList.size()
            + " templates with no checksum. Will ask for computation");
    for (VMTemplateHostVO templateHostRef : templateHostRefList) {
      s_logger.debug("Getting checksum for template - " + templateHostRef.getTemplateId());
      String checksum = this.templateMgr.getChecksum(hostId, templateHostRef.getInstallPath());
      VMTemplateVO template = _templateDao.findById(templateHostRef.getTemplateId());
      s_logger.debug("Setting checksum " + checksum + " for template - " + template.getName());
      template.setChecksum(checksum);
      _templateDao.update(template.getId(), template);
    }
  }
  protected VMTemplateVO persistTemplate(TemplateProfile profile) {
    Long zoneId = profile.getZoneId();
    VMTemplateVO template =
        new VMTemplateVO(
            profile.getTemplateId(),
            profile.getName(),
            profile.getFormat(),
            profile.getIsPublic(),
            profile.getFeatured(),
            profile.getIsExtractable(),
            TemplateType.USER,
            profile.getUrl(),
            profile.getRequiresHVM(),
            profile.getBits(),
            profile.getAccountId(),
            profile.getCheckSum(),
            profile.getDisplayText(),
            profile.getPasswordEnabled(),
            profile.getGuestOsId(),
            profile.getBootable(),
            profile.getHypervisorType(),
            profile.getTemplateTag(),
            profile.getDetails());

    if (zoneId == null || zoneId == -1) {
      List<DataCenterVO> dcs = _dcDao.listAllIncludingRemoved();

      for (DataCenterVO dc : dcs) {
        _tmpltDao.addTemplateToZone(template, dc.getId());
      }
      template.setCrossZones(true);
    } else {
      _tmpltDao.addTemplateToZone(template, zoneId);
    }
    return template;
  }
  // update template_zone_ref for cross-zone template for newly added zone
  @Override
  public void associateCrosszoneTemplatesToZone(long dcId) {
    VMTemplateZoneVO tmpltZone;

    List<VMTemplateVO> allTemplates = _templateDao.listAll();
    for (VMTemplateVO vt : allTemplates) {
      if (vt.isCrossZones()) {
        tmpltZone = _vmTemplateZoneDao.findByZoneTemplate(dcId, vt.getId());
        if (tmpltZone == null) {
          VMTemplateZoneVO vmTemplateZone = new VMTemplateZoneVO(dcId, vt.getId(), new Date());
          _vmTemplateZoneDao.persist(vmTemplateZone);
        }
      }
    }
  }
  public boolean isZoneReady(Map<Long, ZoneHostInfo> zoneHostInfoMap, long dataCenterId) {
    ZoneHostInfo zoneHostInfo = zoneHostInfoMap.get(dataCenterId);
    if (zoneHostInfo != null
        && (zoneHostInfo.getFlags() & RunningHostInfoAgregator.ZoneHostInfo.ROUTING_HOST_MASK)
            != 0) {
      VMTemplateVO template = _templateDao.findSystemVMTemplate(dataCenterId);
      HostVO secHost = _hostDao.findSecondaryStorageHost(dataCenterId);
      if (secHost == null) {
        if (s_logger.isDebugEnabled()) {
          s_logger.debug(
              "No secondary storage available in zone "
                  + dataCenterId
                  + ", wait until it is ready to launch secondary storage vm");
        }
        return false;
      }

      boolean templateReady = false;
      if (template != null) {
        VMTemplateHostVO templateHostRef =
            _vmTemplateHostDao.findByHostTemplate(secHost.getId(), template.getId());
        templateReady =
            (templateHostRef != null) && (templateHostRef.getDownloadState() == Status.DOWNLOADED);
      }

      if (templateReady) {

        List<Pair<Long, Integer>> l =
            _storagePoolHostDao.getDatacenterStoragePoolHostInfo(dataCenterId, !_useLocalStorage);
        if (l != null && l.size() > 0 && l.get(0).second().intValue() > 0) {

          return true;
        } else {
          if (s_logger.isDebugEnabled()) {
            s_logger.debug(
                "Primary storage is not ready, wait until it is ready to launch secondary storage vm");
          }
        }
      } else {
        if (s_logger.isTraceEnabled()) {
          s_logger.trace("Zone host is ready, but secondary storage vm template is not ready");
        }
      }
    }
    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 boolean deleteHost(Long hostId) {
    List<SnapshotVO> snapshots = _snapshotDao.listByHostId(hostId);
    if (snapshots != null && !snapshots.isEmpty()) {
      throw new CloudRuntimeException(
          "Can not delete this secondary storage due to there are still snapshots on it ");
    }
    List<Long> list = _templateDao.listPrivateTemplatesByHost(hostId);
    if (list != null && !list.isEmpty()) {
      throw new CloudRuntimeException(
          "Can not delete this secondary storage due to there are still private template on it ");
    }
    _vmTemplateHostDao.deleteByHost(hostId);
    HostVO host = _hostDao.findById(hostId);
    host.setGuid(null);
    _hostDao.update(hostId, host);
    _hostDao.remove(hostId);

    return true;
  }
  private VMTemplateVO createTemplateInDb() {
    image = new VMTemplateVO();
    image.setTemplateType(TemplateType.USER);

    image.setUniqueName(UUID.randomUUID().toString());
    image.setName(UUID.randomUUID().toString());
    image.setPublicTemplate(true);
    image.setFeatured(true);
    image.setRequiresHvm(true);
    image.setBits(64);
    image.setFormat(Storage.ImageFormat.VHD);
    image.setEnablePassword(true);
    image.setEnableSshKey(true);
    image.setGuestOSId(1);
    image.setBootable(true);
    image.setPrepopulate(true);
    image.setCrossZones(true);
    image.setExtractable(true);
    image = imageDataDao.persist(image);
    return image;
  }
  @Override
  public boolean configure(String name, Map<String, Object> params) {
    final Map<String, String> configs = _configDao.getConfiguration("ManagementServer", params);
    _sslCopy = Boolean.parseBoolean(configs.get("secstorage.encrypt.copy"));
    _proxy = configs.get(Config.SecStorageProxy.key());

    _ssvmUrlDomain = configs.get("secstorage.ssl.cert.domain");

    _copyAuthPasswd = configs.get("secstorage.copy.password");

    _agentMgr.registerForHostEvents(new DownloadListener(this), true, false, false);

    ReadyTemplateStatesSearch = _vmTemplateHostDao.createSearchBuilder();
    ReadyTemplateStatesSearch.and(
        "download_state",
        ReadyTemplateStatesSearch.entity().getDownloadState(),
        SearchCriteria.Op.EQ);
    ReadyTemplateStatesSearch.and(
        "destroyed", ReadyTemplateStatesSearch.entity().getDestroyed(), SearchCriteria.Op.EQ);
    ReadyTemplateStatesSearch.and(
        "host_id", ReadyTemplateStatesSearch.entity().getHostId(), SearchCriteria.Op.EQ);

    SearchBuilder<VMTemplateVO> TemplatesWithNoChecksumSearch = _templateDao.createSearchBuilder();
    TemplatesWithNoChecksumSearch.and(
        "checksum", TemplatesWithNoChecksumSearch.entity().getChecksum(), SearchCriteria.Op.NULL);

    ReadyTemplateStatesSearch.join(
        "vm_template",
        TemplatesWithNoChecksumSearch,
        TemplatesWithNoChecksumSearch.entity().getId(),
        ReadyTemplateStatesSearch.entity().getTemplateId(),
        JoinBuilder.JoinType.INNER);
    TemplatesWithNoChecksumSearch.done();
    ReadyTemplateStatesSearch.done();

    return true;
  }
  @Override
  public void downloadBootstrapSysTemplate(DataStore store) {
    Set<VMTemplateVO> toBeDownloaded = new HashSet<VMTemplateVO>();

    List<VMTemplateVO> rtngTmplts = _templateDao.listAllSystemVMTemplates();

    for (VMTemplateVO rtngTmplt : rtngTmplts) {
      toBeDownloaded.add(rtngTmplt);
    }

    List<HypervisorType> availHypers =
        _clusterDao.getAvailableHypervisorInZone(store.getScope().getScopeId());
    if (availHypers.isEmpty()) {
      /*
       * This is for cloudzone, local secondary storage resource started
       * before cluster created
       */
      availHypers.add(HypervisorType.KVM);
    }
    /* Baremetal need not to download any template */
    availHypers.remove(HypervisorType.BareMetal);
    availHypers.add(HypervisorType.None); // bug 9809: resume ISO
    // download.

    for (VMTemplateVO template : toBeDownloaded) {
      if (availHypers.contains(template.getHypervisorType())) {
        // only download sys template applicable for current hypervisor
        TemplateDataStoreVO tmpltHost =
            _vmTemplateStoreDao.findByStoreTemplate(store.getId(), template.getId());
        if (tmpltHost == null
            || tmpltHost.getState() != ObjectInDataStoreStateMachine.State.Ready) {
          TemplateInfo tmplt = _templateFactory.getTemplate(template.getId(), DataStoreRole.Image);
          createTemplateAsync(tmplt, store, null);
        }
      }
    }
  }
  private String generateCopyUrl(HostVO sourceServer, VMTemplateHostVO srcTmpltHost) {
    List<SecondaryStorageVmVO> ssVms =
        _secStorageVmDao.getSecStorageVmListInStates(
            SecondaryStorageVm.Role.templateProcessor,
            sourceServer.getDataCenterId(),
            State.Running);
    if (ssVms.size() > 0) {
      SecondaryStorageVmVO ssVm = ssVms.get(0);
      if (ssVm.getPublicIpAddress() == null) {
        s_logger.warn("A running secondary storage vm has a null public ip?");
        return null;
      }
      return generateCopyUrl(
          ssVm.getPublicIpAddress(), sourceServer.getParent(), srcTmpltHost.getInstallPath());
    }

    VMTemplateVO tmplt = _templateDao.findById(srcTmpltHost.getTemplateId());
    HypervisorType hyperType = tmplt.getHypervisorType();
    /*No secondary storage vm yet*/
    if (hyperType != null && hyperType == HypervisorType.KVM) {
      return "file://" + sourceServer.getParent() + "/" + srcTmpltHost.getInstallPath();
    }
    return null;
  }
  public DomainRouterVO deployELBVm(
      Network guestNetwork, DeployDestination dest, Account owner, Map<Param, Object> params)
      throws ConcurrentOperationException, ResourceUnavailableException,
          InsufficientCapacityException {
    long dcId = dest.getDataCenter().getId();

    // lock guest network
    Long guestNetworkId = guestNetwork.getId();
    guestNetwork = _networkDao.acquireInLockTable(guestNetworkId);

    if (guestNetwork == null) {
      throw new ConcurrentOperationException("Unable to acquire network lock: " + guestNetworkId);
    }

    try {

      if (_networkModel.isNetworkSystem(guestNetwork)
          || guestNetwork.getGuestType() == Network.GuestType.Shared) {
        owner = _accountService.getSystemAccount();
      }

      if (s_logger.isDebugEnabled()) {
        s_logger.debug(
            "Starting a ELB vm for network configurations: " + guestNetwork + " in " + dest);
      }
      assert guestNetwork.getState() == Network.State.Implemented
              || guestNetwork.getState() == Network.State.Setup
              || guestNetwork.getState() == Network.State.Implementing
          : "Network is not yet fully implemented: " + guestNetwork;

      DataCenterDeployment plan = null;
      DomainRouterVO elbVm = null;

      plan = new DataCenterDeployment(dcId, dest.getPod().getId(), null, null, null, null);

      if (elbVm == null) {
        long id = _routerDao.getNextInSequence(Long.class, "id");
        if (s_logger.isDebugEnabled()) {
          s_logger.debug("Creating the ELB vm " + id);
        }

        List<? extends NetworkOffering> offerings =
            _networkModel.getSystemAccountNetworkOfferings(NetworkOffering.SystemControlNetwork);
        NetworkOffering controlOffering = offerings.get(0);
        NetworkVO controlConfig =
            _networkMgr.setupNetwork(_systemAcct, controlOffering, plan, null, null, false).get(0);

        List<Pair<NetworkVO, NicProfile>> networks = new ArrayList<Pair<NetworkVO, NicProfile>>(2);
        NicProfile guestNic = new NicProfile();
        guestNic.setDefaultNic(true);
        networks.add(new Pair<NetworkVO, NicProfile>(controlConfig, null));
        networks.add(new Pair<NetworkVO, NicProfile>((NetworkVO) guestNetwork, guestNic));

        VMTemplateVO template = _templateDao.findSystemVMTemplate(dcId);

        String typeString = "ElasticLoadBalancerVm";
        Long physicalNetworkId = _networkModel.getPhysicalNetworkId(guestNetwork);
        PhysicalNetworkServiceProvider provider =
            _physicalProviderDao.findByServiceProvider(physicalNetworkId, typeString);
        if (provider == null) {
          throw new CloudRuntimeException(
              "Cannot find service provider "
                  + typeString
                  + " in physical network "
                  + physicalNetworkId);
        }
        VirtualRouterProvider vrProvider =
            _vrProviderDao.findByNspIdAndType(
                provider.getId(), VirtualRouterProviderType.ElasticLoadBalancerVm);
        if (vrProvider == null) {
          throw new CloudRuntimeException(
              "Cannot find virtual router provider "
                  + typeString
                  + " as service provider "
                  + provider.getId());
        }

        elbVm =
            new DomainRouterVO(
                id,
                _elasticLbVmOffering.getId(),
                vrProvider.getId(),
                VirtualMachineName.getSystemVmName(id, _instance, _elbVmNamePrefix),
                template.getId(),
                template.getHypervisorType(),
                template.getGuestOSId(),
                owner.getDomainId(),
                owner.getId(),
                false,
                0,
                false,
                RedundantState.UNKNOWN,
                _elasticLbVmOffering.getOfferHA(),
                false,
                VirtualMachine.Type.ElasticLoadBalancerVm,
                null);
        elbVm.setRole(Role.LB);
        elbVm = _itMgr.allocate(elbVm, template, _elasticLbVmOffering, networks, plan, null, owner);
        // TODO: create usage stats
      }

      State state = elbVm.getState();
      if (state != State.Running) {
        elbVm =
            this.start(
                elbVm, _accountService.getSystemUser(), _accountService.getSystemAccount(), params);
      }

      return elbVm;
    } finally {
      _networkDao.releaseFromLockTable(guestNetworkId);
    }
  }
  public TemplateProfile prepare(
      boolean isIso,
      Long userId,
      String name,
      String displayText,
      Integer bits,
      Boolean passwordEnabled,
      Boolean requiresHVM,
      String url,
      Boolean isPublic,
      Boolean featured,
      Boolean isExtractable,
      String format,
      Long guestOSId,
      Long zoneId,
      HypervisorType hypervisorType,
      String chksum,
      Boolean bootable,
      String templateTag,
      Account templateOwner,
      Map details)
      throws ResourceAllocationException {
    // Long accountId = null;
    // parameters verification

    if (isPublic == null) {
      isPublic = Boolean.FALSE;
    }

    if (zoneId.longValue() == -1) {
      zoneId = null;
    }

    if (isIso) {
      if (bootable == null) {
        bootable = Boolean.TRUE;
      }
      GuestOS noneGuestOs = ApiDBUtils.findGuestOSByDisplayName(ApiConstants.ISO_GUEST_OS_NONE);
      if ((guestOSId == null || guestOSId == noneGuestOs.getId()) && bootable == true) {
        throw new InvalidParameterValueException("Please pass a valid GuestOS Id");
      }
      if (bootable == false) {
        guestOSId = noneGuestOs.getId(); // Guest os id of None.
      }
    } else {
      if (bits == null) {
        bits = Integer.valueOf(64);
      }
      if (passwordEnabled == null) {
        passwordEnabled = false;
      }
      if (requiresHVM == null) {
        requiresHVM = true;
      }
    }

    if (isExtractable == null) {
      isExtractable = Boolean.FALSE;
    }

    boolean isAdmin =
        _accountDao.findById(templateOwner.getId()).getType() == Account.ACCOUNT_TYPE_ADMIN;

    if (!isAdmin && zoneId == null) {
      throw new InvalidParameterValueException("Please specify a valid zone Id.");
    }

    if (url.toLowerCase().contains("file://")) {
      throw new InvalidParameterValueException("File:// type urls are currently unsupported");
    }

    boolean allowPublicUserTemplates =
        Boolean.parseBoolean(_configDao.getValue("allow.public.user.templates"));
    if (!isAdmin && !allowPublicUserTemplates && isPublic) {
      throw new InvalidParameterValueException("Only private templates/ISO can be created.");
    }

    if (!isAdmin || featured == null) {
      featured = Boolean.FALSE;
    }

    // If command is executed via 8096 port, set userId to the id of System
    // account (1)
    if (userId == null) {
      userId = Long.valueOf(1);
    }

    ImageFormat imgfmt = ImageFormat.valueOf(format.toUpperCase());
    if (imgfmt == null) {
      throw new IllegalArgumentException(
          "Image format is incorrect "
              + format
              + ". Supported formats are "
              + EnumUtils.listValues(ImageFormat.values()));
    }

    // Check that the resource limit for templates/ISOs won't be exceeded
    UserVO user = _userDao.findById(userId);
    if (user == null) {
      throw new IllegalArgumentException("Unable to find user with id " + userId);
    }

    _resourceLimitMgr.checkResourceLimit(templateOwner, ResourceType.template);

    if (templateOwner.getType() != Account.ACCOUNT_TYPE_ADMIN && zoneId == null) {
      throw new IllegalArgumentException("Only admins can create templates in all zones");
    }

    // If a zoneId is specified, make sure it is valid
    if (zoneId != null) {
      DataCenterVO zone = _dcDao.findById(zoneId);
      if (zone == null) {
        throw new IllegalArgumentException("Please specify a valid zone.");
      }
      Account caller = UserContext.current().getCaller();
      if (Grouping.AllocationState.Disabled == zone.getAllocationState()
          && !_accountMgr.isRootAdmin(caller.getType())) {
        throw new PermissionDeniedException(
            "Cannot perform this operation, Zone is currently disabled: " + zoneId);
      }
    }

    List<VMTemplateVO> systemvmTmplts = _tmpltDao.listAllSystemVMTemplates();
    for (VMTemplateVO template : systemvmTmplts) {
      if (template.getName().equalsIgnoreCase(name)
          || template.getDisplayText().equalsIgnoreCase(displayText)) {
        throw new IllegalArgumentException("Cannot use reserved names for templates");
      }
    }

    Long id = _tmpltDao.getNextInSequence(Long.class, "id");
    UserContext.current().setEventDetails("Id: " + id + " name: " + name);
    return new TemplateProfile(
        id,
        userId,
        name,
        displayText,
        bits,
        passwordEnabled,
        requiresHVM,
        url,
        isPublic,
        featured,
        isExtractable,
        imgfmt,
        guestOSId,
        zoneId,
        hypervisorType,
        templateOwner.getAccountName(),
        templateOwner.getDomainId(),
        templateOwner.getAccountId(),
        chksum,
        bootable,
        templateTag,
        details);
  }
  @Override
  public void handleTemplateSync(HostVO ssHost) {
    if (ssHost == null) {
      s_logger.warn("Huh? ssHost is null");
      return;
    }
    long sserverId = ssHost.getId();
    long zoneId = ssHost.getDataCenterId();
    if (!(ssHost.getType() == Host.Type.SecondaryStorage
        || ssHost.getType() == Host.Type.LocalSecondaryStorage)) {
      s_logger.warn("Huh? Agent id " + sserverId + " is not secondary storage host");
      return;
    }

    Map<String, TemplateInfo> templateInfos = listTemplate(ssHost);
    if (templateInfos == null) {
      return;
    }

    Set<VMTemplateVO> toBeDownloaded = new HashSet<VMTemplateVO>();
    List<VMTemplateVO> allTemplates = _templateDao.listAllInZone(zoneId);
    List<VMTemplateVO> rtngTmplts = _templateDao.listAllSystemVMTemplates();
    List<VMTemplateVO> defaultBuiltin = _templateDao.listDefaultBuiltinTemplates();

    if (rtngTmplts != null) {
      for (VMTemplateVO rtngTmplt : rtngTmplts) {
        if (!allTemplates.contains(rtngTmplt)) {
          allTemplates.add(rtngTmplt);
        }
      }
    }

    if (defaultBuiltin != null) {
      for (VMTemplateVO builtinTmplt : defaultBuiltin) {
        if (!allTemplates.contains(builtinTmplt)) {
          allTemplates.add(builtinTmplt);
        }
      }
    }

    toBeDownloaded.addAll(allTemplates);

    for (VMTemplateVO tmplt : allTemplates) {
      String uniqueName = tmplt.getUniqueName();
      VMTemplateHostVO tmpltHost = _vmTemplateHostDao.findByHostTemplate(sserverId, tmplt.getId());
      if (templateInfos.containsKey(uniqueName)) {
        TemplateInfo tmpltInfo = templateInfos.remove(uniqueName);
        toBeDownloaded.remove(tmplt);
        if (tmpltHost != null) {
          s_logger.info(
              "Template Sync found " + tmplt.getName() + " already in the template host table");
          if (tmpltHost.getDownloadState() != Status.DOWNLOADED) {
            tmpltHost.setErrorString("");
          }
          if (tmpltInfo.isCorrupted()) {
            tmpltHost.setDownloadState(Status.DOWNLOAD_ERROR);
            String msg =
                "Template "
                    + tmplt.getName()
                    + ":"
                    + tmplt.getId()
                    + " is corrupted on secondary storage "
                    + tmpltHost.getId();
            tmpltHost.setErrorString(msg);
            s_logger.info("msg");
            if (tmplt.getUrl() == null) {
              msg =
                  "Private Template ("
                      + tmplt
                      + ") with install path "
                      + tmpltInfo.getInstallPath()
                      + "is corrupted, please check in secondary storage: "
                      + tmpltHost.getHostId();
              s_logger.warn(msg);
            } else {
              toBeDownloaded.add(tmplt);
            }

          } else {
            tmpltHost.setDownloadPercent(100);
            tmpltHost.setDownloadState(Status.DOWNLOADED);
            tmpltHost.setInstallPath(tmpltInfo.getInstallPath());
            tmpltHost.setSize(tmpltInfo.getSize());
            tmpltHost.setPhysicalSize(tmpltInfo.getPhysicalSize());
            tmpltHost.setLastUpdated(new Date());

            // Skipping limit checks for SYSTEM Account and for the templates created from volumes
            // or snapshots
            // which already got checked and incremented during createTemplate API call.
            if (tmpltInfo.getSize() > 0
                && tmplt.getAccountId() != Account.ACCOUNT_ID_SYSTEM
                && tmplt.getUrl() != null) {
              long accountId = tmplt.getAccountId();
              try {
                _resourceLimitMgr.checkResourceLimit(
                    _accountMgr.getAccount(accountId),
                    com.cloud.configuration.Resource.ResourceType.secondary_storage,
                    tmpltInfo.getSize() - UriUtils.getRemoteSize(tmplt.getUrl()));
              } catch (ResourceAllocationException e) {
                s_logger.warn(e.getMessage());
                _alertMgr.sendAlert(
                    _alertMgr.ALERT_TYPE_RESOURCE_LIMIT_EXCEEDED,
                    ssHost.getDataCenterId(),
                    null,
                    e.getMessage(),
                    e.getMessage());
              } finally {
                _resourceLimitMgr.recalculateResourceCount(
                    accountId,
                    _accountMgr.getAccount(accountId).getDomainId(),
                    com.cloud.configuration.Resource.ResourceType.secondary_storage.getOrdinal());
              }
            }
          }
          _vmTemplateHostDao.update(tmpltHost.getId(), tmpltHost);
        } else {
          tmpltHost =
              new VMTemplateHostVO(
                  sserverId,
                  tmplt.getId(),
                  new Date(),
                  100,
                  Status.DOWNLOADED,
                  null,
                  null,
                  null,
                  tmpltInfo.getInstallPath(),
                  tmplt.getUrl());
          tmpltHost.setSize(tmpltInfo.getSize());
          tmpltHost.setPhysicalSize(tmpltInfo.getPhysicalSize());
          _vmTemplateHostDao.persist(tmpltHost);
          VMTemplateZoneVO tmpltZoneVO =
              _vmTemplateZoneDao.findByZoneTemplate(zoneId, tmplt.getId());
          if (tmpltZoneVO == null) {
            tmpltZoneVO = new VMTemplateZoneVO(zoneId, tmplt.getId(), new Date());
            _vmTemplateZoneDao.persist(tmpltZoneVO);
          } else {
            tmpltZoneVO.setLastUpdated(new Date());
            _vmTemplateZoneDao.update(tmpltZoneVO.getId(), tmpltZoneVO);
          }
        }

        continue;
      }
      if (tmpltHost != null && tmpltHost.getDownloadState() != Status.DOWNLOADED) {
        s_logger.info(
            "Template Sync did not find "
                + tmplt.getName()
                + " ready on server "
                + sserverId
                + ", will request download to start/resume shortly");

      } else if (tmpltHost == null) {
        s_logger.info(
            "Template Sync did not find "
                + tmplt.getName()
                + " on the server "
                + sserverId
                + ", will request download shortly");
        VMTemplateHostVO templtHost =
            new VMTemplateHostVO(
                sserverId,
                tmplt.getId(),
                new Date(),
                0,
                Status.NOT_DOWNLOADED,
                null,
                null,
                null,
                null,
                tmplt.getUrl());
        _vmTemplateHostDao.persist(templtHost);
        VMTemplateZoneVO tmpltZoneVO = _vmTemplateZoneDao.findByZoneTemplate(zoneId, tmplt.getId());
        if (tmpltZoneVO == null) {
          tmpltZoneVO = new VMTemplateZoneVO(zoneId, tmplt.getId(), new Date());
          _vmTemplateZoneDao.persist(tmpltZoneVO);
        } else {
          tmpltZoneVO.setLastUpdated(new Date());
          _vmTemplateZoneDao.update(tmpltZoneVO.getId(), tmpltZoneVO);
        }
      }
    }

    if (toBeDownloaded.size() > 0) {
      /* Only download templates whose hypervirsor type is in the zone */
      List<HypervisorType> availHypers = _clusterDao.getAvailableHypervisorInZone(zoneId);
      if (availHypers.isEmpty()) {
        /*
         * This is for cloudzone, local secondary storage resource
         * started before cluster created
         */
        availHypers.add(HypervisorType.KVM);
      }
      /* Baremetal need not to download any template */
      availHypers.remove(HypervisorType.BareMetal);
      availHypers.add(HypervisorType.None); // bug 9809: resume ISO
      // download.
      for (VMTemplateVO tmplt : toBeDownloaded) {
        if (tmplt.getUrl() == null) { // If url is null we can't
          // initiate the download
          continue;
        }
        // if this is private template, and there is no record for this
        // template in this sHost, skip
        if (!tmplt.isPublicTemplate() && !tmplt.isFeatured()) {
          VMTemplateHostVO tmpltHost =
              _vmTemplateHostDao.findByHostTemplate(sserverId, tmplt.getId());
          if (tmpltHost == null) {
            continue;
          }
        }
        if (availHypers.contains(tmplt.getHypervisorType())) {
          if (_swiftMgr.isSwiftEnabled()) {
            if (_swiftMgr.isTemplateInstalled(tmplt.getId())) {
              continue;
            }
          }
          s_logger.debug(
              "Template " + tmplt.getName() + " needs to be downloaded to " + ssHost.getName());
          downloadTemplateToStorage(tmplt, ssHost);
        } else {
          s_logger.info(
              "Skipping download of template "
                  + tmplt.getName()
                  + " since we don't have any "
                  + tmplt.getHypervisorType()
                  + " hypervisors");
        }
      }
    }

    for (String uniqueName : templateInfos.keySet()) {
      TemplateInfo tInfo = templateInfos.get(uniqueName);
      List<UserVmVO> userVmUsingIso = _userVmDao.listByIsoId(tInfo.getId());
      // check if there is any Vm using this ISO.
      if (userVmUsingIso == null || userVmUsingIso.isEmpty()) {
        DeleteTemplateCommand dtCommand =
            new DeleteTemplateCommand(ssHost.getStorageUrl(), tInfo.getInstallPath());
        try {
          _agentMgr.sendToSecStorage(ssHost, dtCommand, null);
        } catch (AgentUnavailableException e) {
          String err =
              "Failed to delete "
                  + tInfo.getTemplateName()
                  + " on secondary storage "
                  + sserverId
                  + " which isn't in the database";
          s_logger.error(err);
          return;
        }

        String description =
            "Deleted template "
                + tInfo.getTemplateName()
                + " on secondary storage "
                + sserverId
                + " since it isn't in the database";
        s_logger.info(description);
      }
    }
  }
  private void initiateTemplateDownload(
      DataObject template, AsyncCompletionCallback<DownloadAnswer> callback) {
    boolean downloadJobExists = false;
    TemplateDataStoreVO vmTemplateStore = null;
    DataStore store = template.getDataStore();

    vmTemplateStore = _vmTemplateStoreDao.findByStoreTemplate(store.getId(), template.getId());
    if (vmTemplateStore == null) {
      vmTemplateStore =
          new TemplateDataStoreVO(
              store.getId(),
              template.getId(),
              new Date(),
              0,
              Status.NOT_DOWNLOADED,
              null,
              null,
              "jobid0000",
              null,
              template.getUri());
      vmTemplateStore.setDataStoreRole(store.getRole());
      vmTemplateStore = _vmTemplateStoreDao.persist(vmTemplateStore);
    } else if ((vmTemplateStore.getJobId() != null) && (vmTemplateStore.getJobId().length() > 2)) {
      downloadJobExists = true;
    }

    Long maxTemplateSizeInBytes = getMaxTemplateSizeInBytes();
    if (vmTemplateStore != null) {
      start();
      VirtualMachineTemplate tmpl = _templateDao.findById(template.getId());
      DownloadCommand dcmd =
          new DownloadCommand((TemplateObjectTO) (template.getTO()), maxTemplateSizeInBytes);
      dcmd.setProxy(getHttpProxy());
      if (downloadJobExists) {
        dcmd =
            new DownloadProgressCommand(
                dcmd, vmTemplateStore.getJobId(), RequestType.GET_OR_RESTART);
      }
      if (vmTemplateStore.isCopy()) {
        dcmd.setCreds(TemplateConstants.DEFAULT_HTTP_AUTH_USER, _copyAuthPasswd);
      }
      EndPoint ep = _epSelector.select(template);
      if (ep == null) {
        String errMsg =
            "There is no secondary storage VM for downloading template to image store "
                + store.getName();
        s_logger.warn(errMsg);
        throw new CloudRuntimeException(errMsg);
      }
      DownloadListener dl = new DownloadListener(ep, store, template, _timer, this, dcmd, callback);
      ComponentContext.inject(dl); // initialize those auto-wired field in download listener.
      if (downloadJobExists) {
        // due to handling existing download job issues, we still keep
        // downloadState in template_store_ref to avoid big change in
        // DownloadListener to use
        // new ObjectInDataStore.State transition. TODO: fix this later
        // to be able to remove downloadState from template_store_ref.
        s_logger.info("found existing download job");
        dl.setCurrState(vmTemplateStore.getDownloadState());
      }

      try {
        ep.sendMessageAsync(dcmd, new UploadListener.Callback(ep.getId(), dl));
      } catch (Exception e) {
        s_logger.warn(
            "Unable to start /resume download of template "
                + template.getId()
                + " to "
                + store.getName(),
            e);
        dl.setDisconnected();
        dl.scheduleStatusCheck(RequestType.GET_OR_RESTART);
      }
    }
  }
  protected Map<String, Object> createSecStorageVmInstance(
      long dataCenterId, SecondaryStorageVm.Role role) {
    HostVO secHost = _hostDao.findSecondaryStorageHost(dataCenterId);
    if (secHost == null) {
      String msg =
          "No secondary storage available in zone "
              + dataCenterId
              + ", cannot create secondary storage vm";
      s_logger.warn(msg);
      throw new CloudRuntimeException(msg);
    }

    long id = _secStorageVmDao.getNextInSequence(Long.class, "id");
    String name = VirtualMachineName.getSystemVmName(id, _instance, "s").intern();
    Account systemAcct = _accountMgr.getSystemAccount();

    DataCenterDeployment plan = new DataCenterDeployment(dataCenterId);
    DataCenter dc = _dcDao.findById(plan.getDataCenterId());

    List<NetworkOfferingVO> defaultOffering =
        _networkMgr.getSystemAccountNetworkOfferings(NetworkOfferingVO.SystemPublicNetwork);

    if (dc.getNetworkType() == NetworkType.Basic || dc.isSecurityGroupEnabled()) {
      defaultOffering =
          _networkMgr.getSystemAccountNetworkOfferings(NetworkOfferingVO.SystemGuestNetwork);
    }

    List<NetworkOfferingVO> offerings =
        _networkMgr.getSystemAccountNetworkOfferings(
            NetworkOfferingVO.SystemControlNetwork, NetworkOfferingVO.SystemManagementNetwork);
    List<Pair<NetworkVO, NicProfile>> networks =
        new ArrayList<Pair<NetworkVO, NicProfile>>(offerings.size() + 1);
    NicProfile defaultNic = new NicProfile();
    defaultNic.setDefaultNic(true);
    defaultNic.setDeviceId(2);
    try {
      networks.add(
          new Pair<NetworkVO, NicProfile>(
              _networkMgr
                  .setupNetwork(systemAcct, defaultOffering.get(0), plan, null, null, false, false)
                  .get(0),
              defaultNic));
      for (NetworkOfferingVO offering : offerings) {
        networks.add(
            new Pair<NetworkVO, NicProfile>(
                _networkMgr
                    .setupNetwork(systemAcct, offering, plan, null, null, false, false)
                    .get(0),
                null));
      }
    } catch (ConcurrentOperationException e) {
      s_logger.info("Unable to setup due to concurrent operation. " + e);
      return new HashMap<String, Object>();
    }

    VMTemplateVO template = _templateDao.findSystemVMTemplate(dataCenterId);
    if (template == null) {
      s_logger.debug("Can't find a template to start");
      throw new CloudRuntimeException("Insufficient capacity exception");
    }

    SecondaryStorageVmVO secStorageVm =
        new SecondaryStorageVmVO(
            id,
            _serviceOffering.getId(),
            name,
            template.getId(),
            template.getHypervisorType(),
            template.getGuestOSId(),
            dataCenterId,
            systemAcct.getDomainId(),
            systemAcct.getId(),
            role,
            _serviceOffering.getOfferHA());
    try {
      secStorageVm =
          _itMgr.allocate(
              secStorageVm, template, _serviceOffering, networks, plan, null, systemAcct);
    } catch (InsufficientCapacityException e) {
      s_logger.warn("InsufficientCapacity", e);
      throw new CloudRuntimeException("Insufficient capacity exception", e);
    }

    Map<String, Object> context = new HashMap<String, Object>();
    context.put("secStorageVmId", secStorageVm.getId());
    return context;
  }
  @Test(priority = -1)
  public void setUp() {
    ComponentContext.initComponentsLifeCycle();

    host = hostDao.findByGuid(this.getHostGuid());
    if (host != null) {
      dcId = host.getDataCenterId();
      clusterId = host.getClusterId();
      podId = host.getPodId();
      imageStore = this.imageStoreDao.findByName(imageStoreName);
    } else {
      // create data center
      DataCenterVO dc =
          new DataCenterVO(
              UUID.randomUUID().toString(),
              "test",
              "8.8.8.8",
              null,
              "10.0.0.1",
              null,
              "10.0.0.1/24",
              null,
              null,
              NetworkType.Basic,
              null,
              null,
              true,
              true,
              null,
              null);
      dc = dcDao.persist(dc);
      dcId = dc.getId();
      // create pod

      HostPodVO pod =
          new HostPodVO(
              UUID.randomUUID().toString(),
              dc.getId(),
              this.getHostGateway(),
              this.getHostCidr(),
              8,
              "test");
      pod = podDao.persist(pod);
      podId = pod.getId();
      // create xen cluster
      ClusterVO cluster = new ClusterVO(dc.getId(), pod.getId(), "devcloud cluster");
      cluster.setHypervisorType(HypervisorType.VMware.toString());
      cluster.setClusterType(ClusterType.ExternalManaged);
      cluster.setManagedState(ManagedState.Managed);
      cluster = clusterDao.persist(cluster);
      clusterId = cluster.getId();

      // setup vcenter
      ClusterDetailsVO clusterDetailVO = new ClusterDetailsVO(cluster.getId(), "url", null);
      this.clusterDetailsDao.persist(clusterDetailVO);
      clusterDetailVO = new ClusterDetailsVO(cluster.getId(), "username", null);
      this.clusterDetailsDao.persist(clusterDetailVO);
      clusterDetailVO = new ClusterDetailsVO(cluster.getId(), "password", null);
      this.clusterDetailsDao.persist(clusterDetailVO);
      // create xen host

      host = new HostVO(this.getHostGuid());
      host.setName("devcloud vmware host");
      host.setType(Host.Type.Routing);
      host.setPrivateIpAddress(this.getHostIp());
      host.setDataCenterId(dc.getId());
      host.setVersion("6.0.1");
      host.setAvailable(true);
      host.setSetup(true);
      host.setPodId(podId);
      host.setLastPinged(0);
      host.setResourceState(ResourceState.Enabled);
      host.setHypervisorType(HypervisorType.VMware);
      host.setClusterId(cluster.getId());

      host = hostDao.persist(host);

      imageStore = new ImageStoreVO();
      imageStore.setName(imageStoreName);
      imageStore.setDataCenterId(dcId);
      imageStore.setProviderName("CloudStack ImageStore Provider");
      imageStore.setRole(DataStoreRole.Image);
      imageStore.setUrl(this.getSecondaryStorage());
      imageStore.setUuid(UUID.randomUUID().toString());
      imageStore.setProtocol("nfs");
      imageStore = imageStoreDao.persist(imageStore);
    }

    image = new VMTemplateVO();
    image.setTemplateType(TemplateType.USER);
    image.setUrl(this.getTemplateUrl());
    image.setUniqueName(UUID.randomUUID().toString());
    image.setName(UUID.randomUUID().toString());
    image.setPublicTemplate(true);
    image.setFeatured(true);
    image.setRequiresHvm(true);
    image.setBits(64);
    image.setFormat(Storage.ImageFormat.VHD);
    image.setEnablePassword(true);
    image.setEnableSshKey(true);
    image.setGuestOSId(1);
    image.setBootable(true);
    image.setPrepopulate(true);
    image.setCrossZones(true);
    image.setExtractable(true);

    image = imageDataDao.persist(image);

    /*
     * TemplateDataStoreVO templateStore = new TemplateDataStoreVO();
     *
     * templateStore.setDataStoreId(imageStore.getId());
     * templateStore.setDownloadPercent(100);
     * templateStore.setDownloadState(Status.DOWNLOADED);
     * templateStore.setDownloadUrl(imageStore.getUrl());
     * templateStore.setInstallPath(this.getImageInstallPath());
     * templateStore.setTemplateId(image.getId());
     * templateStoreDao.persist(templateStore);
     */

    DataStore store = this.dataStoreMgr.getDataStore(imageStore.getId(), DataStoreRole.Image);
    TemplateInfo template = templateFactory.getTemplate(image.getId(), DataStoreRole.Image);
    DataObject templateOnStore = store.create(template);
    TemplateObjectTO to = new TemplateObjectTO();
    to.setPath(this.getImageInstallPath());
    CopyCmdAnswer answer = new CopyCmdAnswer(to);
    templateOnStore.processEvent(Event.CreateOnlyRequested);
    templateOnStore.processEvent(Event.OperationSuccessed, answer);
  }
  @Override
  public DomainRouterVO deployRouter(
      final RouterDeploymentDefinition routerDeploymentDefinition, final boolean startRouter)
      throws InsufficientAddressCapacityException, InsufficientServerCapacityException,
          InsufficientCapacityException, StorageUnavailableException, ResourceUnavailableException {

    final ServiceOfferingVO routerOffering =
        _serviceOfferingDao.findById(routerDeploymentDefinition.getServiceOfferingId());
    final Account owner = routerDeploymentDefinition.getOwner();

    // Router is the network element, we don't know the hypervisor type yet.
    // Try to allocate the domR twice using diff hypervisors, and when
    // failed both times, throw the exception up
    final List<HypervisorType> hypervisors = getHypervisors(routerDeploymentDefinition);

    int allocateRetry = 0;
    int startRetry = 0;
    DomainRouterVO router = null;
    for (final Iterator<HypervisorType> iter = hypervisors.iterator(); iter.hasNext(); ) {
      final HypervisorType hType = iter.next();
      try {
        final long id = _routerDao.getNextInSequence(Long.class, "id");
        if (s_logger.isDebugEnabled()) {
          s_logger.debug(
              String.format(
                  "Allocating the VR with id=%s in datacenter %s with the hypervisor type %s",
                  id, routerDeploymentDefinition.getDest().getDataCenter(), hType));
        }

        final String templateName =
            retrieveTemplateName(
                hType, routerDeploymentDefinition.getDest().getDataCenter().getId());
        final VMTemplateVO template = _templateDao.findRoutingTemplate(hType, templateName);

        if (template == null) {
          s_logger.debug(hType + " won't support system vm, skip it");
          continue;
        }

        final boolean offerHA = routerOffering.getOfferHA();

        // routerDeploymentDefinition.getVpc().getId() ==> do not use
        // VPC because it is not a VPC offering.
        final Long vpcId =
            routerDeploymentDefinition.getVpc() != null
                ? routerDeploymentDefinition.getVpc().getId()
                : null;

        long userId = CallContext.current().getCallingUserId();
        if (CallContext.current().getCallingAccount().getId() != owner.getId()) {
          final List<UserVO> userVOs = _userDao.listByAccount(owner.getAccountId());
          if (!userVOs.isEmpty()) {
            userId = userVOs.get(0).getId();
          }
        }

        router =
            new DomainRouterVO(
                id,
                routerOffering.getId(),
                routerDeploymentDefinition.getVirtualProvider().getId(),
                VirtualMachineName.getRouterName(id, s_vmInstanceName),
                template.getId(),
                template.getHypervisorType(),
                template.getGuestOSId(),
                owner.getDomainId(),
                owner.getId(),
                userId,
                routerDeploymentDefinition.isRedundant(),
                RedundantState.UNKNOWN,
                offerHA,
                false,
                vpcId);

        router.setDynamicallyScalable(template.isDynamicallyScalable());
        router.setRole(Role.VIRTUAL_ROUTER);
        router = _routerDao.persist(router);

        reallocateRouterNetworks(routerDeploymentDefinition, router, template, null);
        router = _routerDao.findById(router.getId());
      } catch (final InsufficientCapacityException ex) {
        if (allocateRetry < 2 && iter.hasNext()) {
          s_logger.debug(
              "Failed to allocate the VR with hypervisor type "
                  + hType
                  + ", retrying one more time");
          continue;
        } else {
          throw ex;
        }
      } finally {
        allocateRetry++;
      }

      if (startRouter) {
        try {
          router =
              startVirtualRouter(
                  router,
                  _accountMgr.getSystemUser(),
                  _accountMgr.getSystemAccount(),
                  routerDeploymentDefinition.getParams());
          break;
        } catch (final InsufficientCapacityException ex) {
          if (startRetry < 2 && iter.hasNext()) {
            s_logger.debug(
                "Failed to start the VR  "
                    + router
                    + " with hypervisor type "
                    + hType
                    + ", "
                    + "destroying it and recreating one more time");
            // destroy the router
            destroyRouter(
                router.getId(), _accountMgr.getAccount(Account.ACCOUNT_ID_SYSTEM), User.UID_SYSTEM);
            continue;
          } else {
            throw ex;
          }
        } finally {
          startRetry++;
        }
      } else {
        // return stopped router
        return router;
      }
    }

    return router;
  }
  @Override
  public void handleTemplateSync(DataStore store) {
    if (store == null) {
      s_logger.warn("Huh? image store is null");
      return;
    }
    long storeId = store.getId();

    // add lock to make template sync for a data store only be done once
    String lockString = "templatesync.storeId:" + storeId;
    GlobalLock syncLock = GlobalLock.getInternLock(lockString);
    try {
      if (syncLock.lock(3)) {
        try {
          Long zoneId = store.getScope().getScopeId();

          Map<String, TemplateProp> templateInfos = listTemplate(store);
          if (templateInfos == null) {
            return;
          }

          Set<VMTemplateVO> toBeDownloaded = new HashSet<VMTemplateVO>();
          List<VMTemplateVO> allTemplates = null;
          if (zoneId == null) {
            // region wide store
            allTemplates = _templateDao.listAllActive();
          } else {
            // zone wide store
            allTemplates = _templateDao.listAllInZone(zoneId);
          }
          List<VMTemplateVO> rtngTmplts = _templateDao.listAllSystemVMTemplates();
          List<VMTemplateVO> defaultBuiltin = _templateDao.listDefaultBuiltinTemplates();

          if (rtngTmplts != null) {
            for (VMTemplateVO rtngTmplt : rtngTmplts) {
              if (!allTemplates.contains(rtngTmplt)) {
                allTemplates.add(rtngTmplt);
              }
            }
          }

          if (defaultBuiltin != null) {
            for (VMTemplateVO builtinTmplt : defaultBuiltin) {
              if (!allTemplates.contains(builtinTmplt)) {
                allTemplates.add(builtinTmplt);
              }
            }
          }

          toBeDownloaded.addAll(allTemplates);

          for (VMTemplateVO tmplt : allTemplates) {
            String uniqueName = tmplt.getUniqueName();
            TemplateDataStoreVO tmpltStore =
                _vmTemplateStoreDao.findByStoreTemplate(storeId, tmplt.getId());
            if (templateInfos.containsKey(uniqueName)) {
              TemplateProp tmpltInfo = templateInfos.remove(uniqueName);
              toBeDownloaded.remove(tmplt);
              if (tmpltStore != null) {
                s_logger.info("Template Sync found " + uniqueName + " already in the image store");
                if (tmpltStore.getDownloadState() != Status.DOWNLOADED) {
                  tmpltStore.setErrorString("");
                }
                if (tmpltInfo.isCorrupted()) {
                  tmpltStore.setDownloadState(Status.DOWNLOAD_ERROR);
                  String msg =
                      "Template "
                          + tmplt.getName()
                          + ":"
                          + tmplt.getId()
                          + " is corrupted on secondary storage "
                          + tmpltStore.getId();
                  tmpltStore.setErrorString(msg);
                  s_logger.info("msg");
                  if (tmplt.getUrl() == null) {
                    msg =
                        "Private Template ("
                            + tmplt
                            + ") with install path "
                            + tmpltInfo.getInstallPath()
                            + "is corrupted, please check in image store: "
                            + tmpltStore.getDataStoreId();
                    s_logger.warn(msg);
                  } else {
                    s_logger.info(
                        "Removing template_store_ref entry for corrupted template "
                            + tmplt.getName());
                    _vmTemplateStoreDao.remove(tmpltStore.getId());
                    toBeDownloaded.add(tmplt);
                  }

                } else {
                  tmpltStore.setDownloadPercent(100);
                  tmpltStore.setDownloadState(Status.DOWNLOADED);
                  tmpltStore.setState(ObjectInDataStoreStateMachine.State.Ready);
                  tmpltStore.setInstallPath(tmpltInfo.getInstallPath());
                  tmpltStore.setSize(tmpltInfo.getSize());
                  tmpltStore.setPhysicalSize(tmpltInfo.getPhysicalSize());
                  tmpltStore.setLastUpdated(new Date());
                  // update size in vm_template table
                  VMTemplateVO tmlpt = _templateDao.findById(tmplt.getId());
                  tmlpt.setSize(tmpltInfo.getSize());
                  _templateDao.update(tmplt.getId(), tmlpt);

                  // Skipping limit checks for SYSTEM Account and for the templates created from
                  // volumes or snapshots
                  // which already got checked and incremented during createTemplate API call.
                  if (tmpltInfo.getSize() > 0
                      && tmplt.getAccountId() != Account.ACCOUNT_ID_SYSTEM
                      && tmplt.getUrl() != null) {
                    long accountId = tmplt.getAccountId();
                    try {
                      _resourceLimitMgr.checkResourceLimit(
                          _accountMgr.getAccount(accountId),
                          com.cloud.configuration.Resource.ResourceType.secondary_storage,
                          tmpltInfo.getSize() - UriUtils.getRemoteSize(tmplt.getUrl()));
                    } catch (ResourceAllocationException e) {
                      s_logger.warn(e.getMessage());
                      _alertMgr.sendAlert(
                          AlertManager.AlertType.ALERT_TYPE_RESOURCE_LIMIT_EXCEEDED,
                          zoneId,
                          null,
                          e.getMessage(),
                          e.getMessage());
                    } finally {
                      _resourceLimitMgr.recalculateResourceCount(
                          accountId,
                          _accountMgr.getAccount(accountId).getDomainId(),
                          com.cloud.configuration.Resource.ResourceType.secondary_storage
                              .getOrdinal());
                    }
                  }
                }
                _vmTemplateStoreDao.update(tmpltStore.getId(), tmpltStore);
              } else {
                tmpltStore =
                    new TemplateDataStoreVO(
                        storeId,
                        tmplt.getId(),
                        new Date(),
                        100,
                        Status.DOWNLOADED,
                        null,
                        null,
                        null,
                        tmpltInfo.getInstallPath(),
                        tmplt.getUrl());
                tmpltStore.setSize(tmpltInfo.getSize());
                tmpltStore.setPhysicalSize(tmpltInfo.getPhysicalSize());
                tmpltStore.setDataStoreRole(store.getRole());
                _vmTemplateStoreDao.persist(tmpltStore);

                // update size in vm_template table
                VMTemplateVO tmlpt = _templateDao.findById(tmplt.getId());
                tmlpt.setSize(tmpltInfo.getSize());
                _templateDao.update(tmplt.getId(), tmlpt);
                associateTemplateToZone(tmplt.getId(), zoneId);
              }
            } else {
              s_logger.info(
                  "Template Sync did not find "
                      + uniqueName
                      + " on image store "
                      + storeId
                      + ", may request download based on available hypervisor types");
              if (tmpltStore != null) {
                if (isRegionStore(store)
                    && tmpltStore.getDownloadState()
                        == VMTemplateStorageResourceAssoc.Status.DOWNLOADED
                    && tmpltStore.getState() == State.Ready
                    && tmpltStore.getInstallPath() == null) {
                  s_logger.info(
                      "Keep fake entry in template store table for migration of previous NFS to object store");
                } else {
                  s_logger.info(
                      "Removing leftover template "
                          + uniqueName
                          + " entry from template store table");
                  // remove those leftover entries
                  _vmTemplateStoreDao.remove(tmpltStore.getId());
                }
              }
            }
          }

          if (toBeDownloaded.size() > 0) {
            /* Only download templates whose hypervirsor type is in the zone */
            List<HypervisorType> availHypers = _clusterDao.getAvailableHypervisorInZone(zoneId);
            if (availHypers.isEmpty()) {
              /*
               * This is for cloudzone, local secondary storage resource
               * started before cluster created
               */
              availHypers.add(HypervisorType.KVM);
            }
            /* Baremetal need not to download any template */
            availHypers.remove(HypervisorType.BareMetal);
            availHypers.add(HypervisorType.None); // bug 9809: resume ISO
            // download.
            for (VMTemplateVO tmplt : toBeDownloaded) {
              if (tmplt.getUrl() == null) { // If url is null we can't
                s_logger.info(
                    "Skip downloading template "
                        + tmplt.getUniqueName()
                        + " since no url is specified.");
                continue;
              }
              // if this is private template, skip sync to a new image store
              if (!tmplt.isPublicTemplate()
                  && !tmplt.isFeatured()
                  && tmplt.getTemplateType() != TemplateType.SYSTEM) {
                s_logger.info(
                    "Skip sync downloading private template "
                        + tmplt.getUniqueName()
                        + " to a new image store");
                continue;
              }

              // if this is a region store, and there is already an DOWNLOADED entry there without
              // install_path information, which
              // means that this is a duplicate entry from migration of previous NFS to staging.
              if (isRegionStore(store)) {
                TemplateDataStoreVO tmpltStore =
                    _vmTemplateStoreDao.findByStoreTemplate(storeId, tmplt.getId());
                if (tmpltStore != null
                    && tmpltStore.getDownloadState()
                        == VMTemplateStorageResourceAssoc.Status.DOWNLOADED
                    && tmpltStore.getState() == State.Ready
                    && tmpltStore.getInstallPath() == null) {
                  s_logger.info("Skip sync template for migration of previous NFS to object store");
                  continue;
                }
              }

              if (availHypers.contains(tmplt.getHypervisorType())) {
                s_logger.info(
                    "Downloading template "
                        + tmplt.getUniqueName()
                        + " to image store "
                        + store.getName());
                associateTemplateToZone(tmplt.getId(), zoneId);
                TemplateInfo tmpl =
                    _templateFactory.getTemplate(tmplt.getId(), DataStoreRole.Image);
                createTemplateAsync(tmpl, store, null);
              } else {
                s_logger.info(
                    "Skip downloading template "
                        + tmplt.getUniqueName()
                        + " since current data center does not have hypervisor "
                        + tmplt.getHypervisorType().toString());
              }
            }
          }

          for (String uniqueName : templateInfos.keySet()) {
            TemplateProp tInfo = templateInfos.get(uniqueName);
            if (_tmpltMgr.templateIsDeleteable(tInfo.getId())) {
              // we cannot directly call deleteTemplateSync here to
              // reuse delete logic since in this case, our db does not have
              // this template at all.
              TemplateObjectTO tmplTO = new TemplateObjectTO();
              tmplTO.setDataStore(store.getTO());
              tmplTO.setPath(tInfo.getInstallPath());
              tmplTO.setId(tInfo.getId());
              DeleteCommand dtCommand = new DeleteCommand(tmplTO);
              EndPoint ep = _epSelector.select(store);
              Answer answer = null;
              if (ep == null) {
                String errMsg =
                    "No remote endpoint to send command, check if host or ssvm is down?";
                s_logger.error(errMsg);
                answer = new Answer(dtCommand, false, errMsg);
              } else {
                answer = ep.sendMessage(dtCommand);
              }
              if (answer == null || !answer.getResult()) {
                s_logger.info("Failed to deleted template at store: " + store.getName());

              } else {
                String description =
                    "Deleted template "
                        + tInfo.getTemplateName()
                        + " on secondary storage "
                        + storeId;
                s_logger.info(description);
              }
            }
          }
        } finally {
          syncLock.unlock();
        }
      } else {
        s_logger.info(
            "Couldn't get global lock on "
                + lockString
                + ", another thread may be doing template sync on data store "
                + storeId
                + " now.");
      }
    } finally {
      syncLock.releaseRef();
    }
  }