public SecondaryStorageVmVO assignSecStorageVmFromRunningPool(
      long dataCenterId, SecondaryStorageVm.Role role) {

    if (s_logger.isTraceEnabled()) {
      s_logger.trace(
          "Assign  secondary storage vm from running pool for request from data center : "
              + dataCenterId);
    }

    SecondaryStorageVmAllocator allocator = getCurrentAllocator();
    assert (allocator != null);
    List<SecondaryStorageVmVO> runningList =
        _secStorageVmDao.getSecStorageVmListInStates(role, dataCenterId, State.Running);
    if (runningList != null && runningList.size() > 0) {
      if (s_logger.isTraceEnabled()) {
        s_logger.trace("Running secondary storage vm pool size : " + runningList.size());
        for (SecondaryStorageVmVO secStorageVm : runningList) {
          s_logger.trace("Running secStorageVm instance : " + secStorageVm.getHostName());
        }
      }

      Map<Long, Integer> loadInfo = new HashMap<Long, Integer>();

      return allocator.allocSecondaryStorageVm(runningList, loadInfo, dataCenterId);
    } else {
      if (s_logger.isTraceEnabled()) {
        s_logger.trace("Empty running secStorageVm pool for now in data center : " + dataCenterId);
      }
    }
    return null;
  }
  @Override
  public Pair<AfterScanAction, Object> scanPool(Long pool) {
    long dataCenterId = pool.longValue();

    List<SecondaryStorageVmVO> ssVms =
        _secStorageVmDao.getSecStorageVmListInStates(
            SecondaryStorageVm.Role.templateProcessor,
            dataCenterId,
            State.Running,
            State.Migrating,
            State.Starting,
            State.Stopped,
            State.Stopping);
    int vmSize = (ssVms == null) ? 0 : ssVms.size();
    List<HostVO> ssHosts = _hostDao.listSecondaryStorageHosts(dataCenterId);
    int hostSize = (ssHosts == null) ? 0 : ssHosts.size();
    if (hostSize > vmSize) {
      s_logger.info(
          "No secondary storage vms found in datacenter id="
              + dataCenterId
              + ", starting a new one");
      return new Pair<AfterScanAction, Object>(
          AfterScanAction.expand, SecondaryStorageVm.Role.templateProcessor);
    }

    return new Pair<AfterScanAction, Object>(
        AfterScanAction.nop, SecondaryStorageVm.Role.templateProcessor);
  }
  public SecondaryStorageVmVO assignSecStorageVmFromStoppedPool(
      long dataCenterId, SecondaryStorageVm.Role role) {
    List<SecondaryStorageVmVO> l =
        _secStorageVmDao.getSecStorageVmListInStates(
            role, dataCenterId, State.Starting, State.Stopped, State.Migrating);
    if (l != null && l.size() > 0) {
      return l.get(0);
    }

    return 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;
  }
  @Override
  public boolean generateFirewallConfiguration(Long ssAHostId) {
    if (ssAHostId == null) {
      return true;
    }
    HostVO ssAHost = _hostDao.findById(ssAHostId);
    Long zoneId = ssAHost.getDataCenterId();
    SecondaryStorageVmVO thisSecStorageVm = _secStorageVmDao.findByInstanceName(ssAHost.getName());

    if (thisSecStorageVm == null) {
      s_logger.warn("secondary storage VM " + ssAHost.getName() + " doesn't exist");
      return false;
    }

    List<SecondaryStorageVmVO> alreadyRunning =
        _secStorageVmDao.getSecStorageVmListInStates(
            SecondaryStorageVm.Role.templateProcessor,
            State.Running,
            State.Migrating,
            State.Starting);

    String copyPort =
        _useSSlCopy ? "443" : Integer.toString(TemplateConstants.DEFAULT_TMPLT_COPY_PORT);
    SecStorageFirewallCfgCommand cpc = new SecStorageFirewallCfgCommand();
    SecStorageFirewallCfgCommand thiscpc = new SecStorageFirewallCfgCommand();
    thiscpc.addPortConfig(
        thisSecStorageVm.getPublicIpAddress(),
        copyPort,
        true,
        TemplateConstants.DEFAULT_TMPLT_COPY_INTF);
    for (SecondaryStorageVmVO ssVm : alreadyRunning) {
      if (ssVm.getDataCenterIdToDeployIn() == zoneId) {
        continue;
      }
      if (ssVm.getPublicIpAddress() != null) {
        cpc.addPortConfig(
            ssVm.getPublicIpAddress(), copyPort, true, TemplateConstants.DEFAULT_TMPLT_COPY_INTF);
      }
      if (ssVm.getState() != State.Running) {
        continue;
      }
      String instanceName = ssVm.getInstanceName();
      HostVO host = _hostDao.findByName(instanceName);
      if (host == null) {
        continue;
      }
      Answer answer = _agentMgr.easySend(host.getId(), thiscpc);
      if (answer != null && answer.getResult()) {
        if (s_logger.isDebugEnabled()) {
          s_logger.debug("Successfully programmed firewall rules into " + ssVm.getHostName());
        }
      } else {
        if (s_logger.isDebugEnabled()) {
          s_logger.debug(
              "failed to program firewall rules into secondary storage vm : " + ssVm.getHostName());
        }
        return false;
      }
    }

    Answer answer = _agentMgr.easySend(ssAHostId, cpc);
    if (answer != null && answer.getResult()) {
      if (s_logger.isDebugEnabled()) {
        s_logger.debug(
            "Successfully programmed firewall rules into " + thisSecStorageVm.getHostName());
      }
    } else {
      if (s_logger.isDebugEnabled()) {
        s_logger.debug(
            "failed to program firewall rules into secondary storage vm : "
                + thisSecStorageVm.getHostName());
      }
      return false;
    }

    return true;
  }
  @Override
  public boolean generateSetupCommand(Long ssHostId) {
    HostVO cssHost = _hostDao.findById(ssHostId);
    Long zoneId = cssHost.getDataCenterId();
    if (cssHost.getType() == Host.Type.SecondaryStorageVM) {

      SecondaryStorageVmVO secStorageVm = _secStorageVmDao.findByInstanceName(cssHost.getName());
      if (secStorageVm == null) {
        s_logger.warn("secondary storage VM " + cssHost.getName() + " doesn't exist");
        return false;
      }

      List<HostVO> ssHosts = _hostDao.listSecondaryStorageHosts(zoneId);
      for (HostVO ssHost : ssHosts) {
        String secUrl = ssHost.getStorageUrl();
        SecStorageSetupCommand setupCmd = new SecStorageSetupCommand(secUrl);

        Answer answer = _agentMgr.easySend(ssHostId, setupCmd);
        if (answer != null && answer.getResult()) {
          SecStorageSetupAnswer an = (SecStorageSetupAnswer) answer;
          ssHost.setParent(an.get_dir());
          _hostDao.update(ssHost.getId(), ssHost);
          if (s_logger.isDebugEnabled()) {
            s_logger.debug(
                "Successfully programmed secondary storage "
                    + ssHost.getName()
                    + " in secondary storage VM "
                    + secStorageVm.getInstanceName());
          }
        } else {
          if (s_logger.isDebugEnabled()) {
            s_logger.debug(
                "Successfully programmed secondary storage "
                    + ssHost.getName()
                    + " in secondary storage VM "
                    + secStorageVm.getInstanceName());
          }
          return false;
        }
      }
    } else if (cssHost.getType() == Host.Type.SecondaryStorage) {
      List<SecondaryStorageVmVO> alreadyRunning =
          _secStorageVmDao.getSecStorageVmListInStates(
              SecondaryStorageVm.Role.templateProcessor, zoneId, State.Running);
      String secUrl = cssHost.getStorageUrl();
      SecStorageSetupCommand setupCmd = new SecStorageSetupCommand(secUrl);
      for (SecondaryStorageVmVO ssVm : alreadyRunning) {
        HostVO host = _hostDao.findByName(ssVm.getInstanceName());
        Answer answer = _agentMgr.easySend(host.getId(), setupCmd);
        if (answer != null && answer.getResult()) {
          if (s_logger.isDebugEnabled()) {
            s_logger.debug(
                "Successfully programmed secondary storage "
                    + host.getName()
                    + " in secondary storage VM "
                    + ssVm.getInstanceName());
          }
        } else {
          if (s_logger.isDebugEnabled()) {
            s_logger.debug(
                "Successfully programmed secondary storage "
                    + host.getName()
                    + " in secondary storage VM "
                    + ssVm.getInstanceName());
          }
          return false;
        }
      }
    }
    return true;
  }