public TemplateProfile prepareDelete(DeleteIsoCmd cmd) {
    TemplateProfile profile = super.prepareDelete(cmd);
    Long zoneId = profile.getZoneId();

    if (zoneId != null && (_ssvmMgr.findSecondaryStorageHost(zoneId) == null)) {
      throw new InvalidParameterValueException(
          "Failed to find a secondary storage host in the specified zone.");
    }

    return profile;
  }
  @Override
  public VMTemplateVO create(TemplateProfile profile) {
    VMTemplateVO template = persistTemplate(profile);

    if (template == null) {
      throw new CloudRuntimeException("Unable to persist the template " + profile.getTemplate());
    }

    _downloadMonitor.downloadTemplateToStorage(template, profile.getZoneId());
    _resourceLimitMgr.incrementResourceCount(profile.getAccountId(), ResourceType.template);

    return template;
  }
  @Override
  public TemplateProfile prepare(RegisterTemplateCmd cmd) throws ResourceAllocationException {
    TemplateProfile profile = super.prepare(cmd);
    String url = profile.getUrl();

    if ((!url.toLowerCase().endsWith("vhd"))
        && (!url.toLowerCase().endsWith("vhd.zip"))
        && (!url.toLowerCase().endsWith("vhd.bz2"))
        && (!url.toLowerCase().endsWith("vhd.gz"))
        && (!url.toLowerCase().endsWith("qcow2"))
        && (!url.toLowerCase().endsWith("qcow2.zip"))
        && (!url.toLowerCase().endsWith("qcow2.bz2"))
        && (!url.toLowerCase().endsWith("qcow2.gz"))
        && (!url.toLowerCase().endsWith("ova"))
        && (!url.toLowerCase().endsWith("ova.zip"))
        && (!url.toLowerCase().endsWith("ova.bz2"))
        && (!url.toLowerCase().endsWith("ova.gz"))
        && (!url.toLowerCase().endsWith("img"))
        && (!url.toLowerCase().endsWith("raw"))) {
      throw new InvalidParameterValueException(
          "Please specify a valid " + cmd.getFormat().toLowerCase());
    }

    if ((cmd.getFormat().equalsIgnoreCase("vhd")
            && (!url.toLowerCase().endsWith("vhd")
                && !url.toLowerCase().endsWith("vhd.zip")
                && !url.toLowerCase().endsWith("vhd.bz2")
                && !url.toLowerCase().endsWith("vhd.gz")))
        || (cmd.getFormat().equalsIgnoreCase("qcow2")
            && (!url.toLowerCase().endsWith("qcow2")
                && !url.toLowerCase().endsWith("qcow2.zip")
                && !url.toLowerCase().endsWith("qcow2.bz2")
                && !url.toLowerCase().endsWith("qcow2.gz")))
        || (cmd.getFormat().equalsIgnoreCase("ova")
            && (!url.toLowerCase().endsWith("ova")
                && !url.toLowerCase().endsWith("ova.zip")
                && !url.toLowerCase().endsWith("ova.bz2")
                && !url.toLowerCase().endsWith("ova.gz")))
        || (cmd.getFormat().equalsIgnoreCase("raw")
            && (!url.toLowerCase().endsWith("img") && !url.toLowerCase().endsWith("raw")))) {
      throw new InvalidParameterValueException(
          "Please specify a valid URL. URL:"
              + url
              + " is an invalid for the format "
              + cmd.getFormat().toLowerCase());
    }

    profile.setUrl(validateUrl(url));
    return profile;
  }
  @Override
  public TemplateProfile prepare(RegisterIsoCmd cmd) throws ResourceAllocationException {
    TemplateProfile profile = super.prepare(cmd);
    String url = profile.getUrl();

    if ((!url.toLowerCase().endsWith("iso"))
        && (!url.toLowerCase().endsWith("iso.zip"))
        && (!url.toLowerCase().endsWith("iso.bz2"))
        && (!url.toLowerCase().endsWith("iso.gz"))) {
      throw new InvalidParameterValueException("Please specify a valid iso");
    }

    profile.setUrl(validateUrl(url));
    return profile;
  }
  public TemplateProfile prepareDelete(DeleteTemplateCmd cmd) {
    TemplateProfile profile = super.prepareDelete(cmd);
    VMTemplateVO template = profile.getTemplate();
    Long zoneId = profile.getZoneId();

    if (template.getTemplateType() == TemplateType.SYSTEM) {
      throw new InvalidParameterValueException("The DomR template cannot be deleted.");
    }

    if (zoneId != null && (_ssvmMgr.findSecondaryStorageHost(zoneId) == null)) {
      throw new InvalidParameterValueException(
          "Failed to find a secondary storage host in the specified zone.");
    }

    return profile;
  }
  @Override
  @DB
  public boolean delete(TemplateProfile profile) {
    boolean success = true;

    VMTemplateVO template = profile.getTemplate();
    Long zoneId = profile.getZoneId();
    Long templateId = template.getId();

    String zoneName;
    List<HostVO> secondaryStorageHosts;
    if (!template.isCrossZones() && zoneId != null) {
      DataCenterVO zone = _dcDao.findById(zoneId);
      zoneName = zone.getName();
      secondaryStorageHosts = _ssvmMgr.listSecondaryStorageHostsInOneZone(zoneId);
    } else {
      zoneName = "(all zones)";
      secondaryStorageHosts = _ssvmMgr.listSecondaryStorageHostsInAllZones();
    }

    s_logger.debug(
        "Attempting to mark template host refs for template: "
            + template.getName()
            + " as destroyed in zone: "
            + zoneName);

    // Make sure the template is downloaded to all the necessary secondary storage hosts
    for (HostVO secondaryStorageHost : secondaryStorageHosts) {
      long hostId = secondaryStorageHost.getId();
      List<VMTemplateHostVO> templateHostVOs = _tmpltHostDao.listByHostTemplate(hostId, templateId);
      for (VMTemplateHostVO templateHostVO : templateHostVOs) {
        if (templateHostVO.getDownloadState() == Status.DOWNLOAD_IN_PROGRESS) {
          String errorMsg = "Please specify a template that is not currently being downloaded.";
          s_logger.debug(
              "Template: "
                  + template.getName()
                  + " is currently being downloaded to secondary storage host: "
                  + secondaryStorageHost.getName()
                  + "; cant' delete it.");
          throw new CloudRuntimeException(errorMsg);
        }
      }
    }

    Account account = _accountDao.findByIdIncludingRemoved(template.getAccountId());
    String eventType = "";

    if (template.getFormat().equals(ImageFormat.ISO)) {
      eventType = EventTypes.EVENT_ISO_DELETE;
    } else {
      eventType = EventTypes.EVENT_TEMPLATE_DELETE;
    }

    // Iterate through all necessary secondary storage hosts and mark the template on each host as
    // destroyed
    for (HostVO secondaryStorageHost : secondaryStorageHosts) {
      long hostId = secondaryStorageHost.getId();
      long sZoneId = secondaryStorageHost.getDataCenterId();
      List<VMTemplateHostVO> templateHostVOs = _tmpltHostDao.listByHostTemplate(hostId, templateId);
      for (VMTemplateHostVO templateHostVO : templateHostVOs) {
        VMTemplateHostVO lock = _tmpltHostDao.acquireInLockTable(templateHostVO.getId());
        try {
          if (lock == null) {
            s_logger.debug(
                "Failed to acquire lock when deleting templateHostVO with ID: "
                    + templateHostVO.getId());
            success = false;
            break;
          }
          UsageEventVO usageEvent =
              new UsageEventVO(eventType, account.getId(), sZoneId, templateId, null);
          _usageEventDao.persist(usageEvent);
          templateHostVO.setDestroyed(true);
          _tmpltHostDao.update(templateHostVO.getId(), templateHostVO);
          String installPath = templateHostVO.getInstallPath();
          if (installPath != null) {
            Answer answer =
                _agentMgr.sendToSecStorage(
                    secondaryStorageHost,
                    new DeleteTemplateCommand(secondaryStorageHost.getStorageUrl(), installPath));

            if (answer == null || !answer.getResult()) {
              s_logger.debug(
                  "Failed to delete "
                      + templateHostVO
                      + " due to "
                      + ((answer == null) ? "answer is null" : answer.getDetails()));
            } else {
              _tmpltHostDao.remove(templateHostVO.getId());
              s_logger.debug("Deleted template at: " + installPath);
            }
          } else {
            _tmpltHostDao.remove(templateHostVO.getId());
          }
          VMTemplateZoneVO templateZone = _tmpltZoneDao.findByZoneTemplate(sZoneId, templateId);

          if (templateZone != null) {
            _tmpltZoneDao.remove(templateZone.getId());
          }
        } finally {
          if (lock != null) {
            _tmpltHostDao.releaseFromLockTable(lock.getId());
          }
        }
      }

      if (!success) {
        break;
      }
    }

    s_logger.debug(
        "Successfully marked template host refs for template: "
            + template.getName()
            + " as destroyed in zone: "
            + zoneName);

    // If there are no more non-destroyed template host entries for this template, delete it
    if (success && (_tmpltHostDao.listByTemplateId(templateId).size() == 0)) {
      long accountId = template.getAccountId();

      VMTemplateVO lock = _tmpltDao.acquireInLockTable(templateId);

      try {
        if (lock == null) {
          s_logger.debug("Failed to acquire lock when deleting template with ID: " + templateId);
          success = false;
        } else if (_tmpltDao.remove(templateId)) {
          // Decrement the number of templates
          _resourceLimitMgr.decrementResourceCount(accountId, ResourceType.template);
        }

      } finally {
        if (lock != null) {
          _tmpltDao.releaseFromLockTable(lock.getId());
        }
      }

      s_logger.debug(
          "Removed template: "
              + template.getName()
              + " because all of its template host refs were marked as destroyed.");
    }

    return success;
  }
  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;
  }