Ejemplo n.º 1
0
  // @Test
  public void testCopyBaseImage() {
    DataStore primaryStore = createPrimaryDataStore();
    primaryStoreId = primaryStore.getId();
    primaryStore = this.dataStoreMgr.getPrimaryDataStore(primaryStoreId);
    VolumeVO volume = createVolume(image.getId(), primaryStore.getId());
    VolumeInfo volInfo = this.volFactory.getVolume(volume.getId());
    AsyncCallFuture<VolumeApiResult> future =
        this.volumeService.createVolumeFromTemplateAsync(
            volInfo,
            this.primaryStoreId,
            this.templateFactory.getTemplate(this.image.getId(), DataStoreRole.Image));
    try {
      VolumeApiResult result = future.get();

      AssertJUnit.assertTrue(result.isSuccess());

      VolumeInfo newVol = result.getVolume();
      this.volumeService.destroyVolume(newVol.getId());
      VolumeInfo vol = this.volFactory.getVolume(volume.getId());
      this.volumeService.expungeVolumeAsync(vol);
    } catch (InterruptedException e) {
      // TODO Auto-generated catch block
      e.printStackTrace();
    } catch (ExecutionException e) {
      // TODO Auto-generated catch block
      e.printStackTrace();
    } catch (ConcurrentOperationException e) {
      // TODO Auto-generated catch block
      e.printStackTrace();
    }
  }
Ejemplo n.º 2
0
  @Test
  public void testCreateTemplateFromVolume() {
    DataStore primaryStore = createPrimaryDataStore();
    primaryStoreId = primaryStore.getId();
    primaryStore = this.dataStoreMgr.getPrimaryDataStore(primaryStoreId);
    VolumeVO volume = createVolume(null, primaryStore.getId());
    VolumeInfo volInfo = this.volFactory.getVolume(volume.getId());
    AsyncCallFuture<VolumeApiResult> future =
        this.volumeService.createVolumeAsync(volInfo, primaryStore);
    try {
      VolumeApiResult result = future.get();

      AssertJUnit.assertTrue(result.isSuccess());
      volInfo = result.getVolume();
      VMTemplateVO templateVO = createTemplateInDb();
      TemplateInfo tmpl = this.templateFactory.getTemplate(templateVO.getId(), DataStoreRole.Image);
      DataStore imageStore = this.dataStoreMgr.getImageStore(this.dcId);

      this.imageService.createTemplateFromVolumeAsync(volInfo, tmpl, imageStore);
    } catch (InterruptedException e) {
      // TODO Auto-generated catch block
      e.printStackTrace();
    } catch (ExecutionException e) {
      // TODO Auto-generated catch block
      e.printStackTrace();
    }
  }
Ejemplo n.º 3
0
  @Test
  public void testDeleteDisk() {
    DataStore primaryStore = createPrimaryDataStore();
    primaryStoreId = primaryStore.getId();
    primaryStore = this.dataStoreMgr.getPrimaryDataStore(primaryStoreId);
    VolumeVO volume = createVolume(null, primaryStore.getId());
    VolumeInfo volInfo = this.volFactory.getVolume(volume.getId());
    AsyncCallFuture<VolumeApiResult> future =
        this.volumeService.createVolumeAsync(volInfo, primaryStore);
    try {
      VolumeApiResult result = future.get();
      VolumeInfo vol = result.getVolume();

      this.volumeService.destroyVolume(volInfo.getId());
      volInfo = this.volFactory.getVolume(vol.getId());
      this.volumeService.expungeVolumeAsync(volInfo);
    } catch (InterruptedException e) {
      // TODO Auto-generated catch block
      e.printStackTrace();
    } catch (ExecutionException e) {
      // TODO Auto-generated catch block
      e.printStackTrace();
    } catch (ConcurrentOperationException e) {
      // TODO Auto-generated catch block
      e.printStackTrace();
    }
  }
  @Override
  public void createAsync(
      DataStore dataStore,
      DataObject dataObject,
      AsyncCompletionCallback<CreateCmdResult> callback) {
    String iqn = null;
    String errMsg = null;

    if (dataObject.getType() == DataObjectType.VOLUME) {
      VolumeInfo volumeInfo = (VolumeInfo) dataObject;
      AccountVO account = _accountDao.findById(volumeInfo.getAccountId());
      String sfAccountName = getSfAccountName(account.getUuid(), account.getAccountId());

      long storagePoolId = dataStore.getId();
      SolidFireConnection sfConnection = getSolidFireConnection(storagePoolId);

      if (!sfAccountExists(sfAccountName, sfConnection)) {
        SolidFireUtil.SolidFireAccount sfAccount =
            createSolidFireAccount(sfAccountName, sfConnection);

        updateCsDbWithAccountInfo(account.getId(), sfAccount);
      }

      SolidFireUtil.SolidFireVolume sfVolume = createSolidFireVolume(volumeInfo, sfConnection);

      iqn = sfVolume.getIqn();

      VolumeVO volume = this._volumeDao.findById(volumeInfo.getId());

      volume.set_iScsiName(iqn);
      volume.setFolder(String.valueOf(sfVolume.getId()));
      volume.setPoolType(StoragePoolType.IscsiLUN);
      volume.setPoolId(storagePoolId);

      _volumeDao.update(volume.getId(), volume);

      StoragePoolVO storagePool = _storagePoolDao.findById(dataStore.getId());

      long capacityBytes = storagePool.getCapacityBytes();
      long usedBytes = storagePool.getUsedBytes();

      usedBytes += volumeInfo.getSize();

      storagePool.setUsedBytes(usedBytes > capacityBytes ? capacityBytes : usedBytes);

      _storagePoolDao.update(storagePoolId, storagePool);
    } else {
      errMsg = "Invalid DataObjectType (" + dataObject.getType() + ") passed to createAsync";
    }

    // path = iqn
    // size is pulled from DataObject instance, if errMsg is null
    CreateCmdResult result = new CreateCmdResult(iqn, new Answer(null, errMsg == null, errMsg));

    result.setResult(errMsg);

    callback.complete(result);
  }
Ejemplo n.º 5
0
 @Test
 public void testCreateDataDisk() {
   DataStore primaryStore = createPrimaryDataStore();
   primaryStoreId = primaryStore.getId();
   primaryStore = this.dataStoreMgr.getPrimaryDataStore(primaryStoreId);
   VolumeVO volume = createVolume(null, primaryStore.getId());
   VolumeInfo volInfo = this.volFactory.getVolume(volume.getId());
   this.volumeService.createVolumeAsync(volInfo, primaryStore);
 }
Ejemplo n.º 6
0
  // @Test(priority=3)
  public void createAndDeleteDataDisk() {
    DataStore primaryStore = this.primaryStore;
    VolumeVO volume = createVolume(null, primaryStore.getId());
    VolumeInfo vol = volumeFactory.getVolume(volume.getId(), primaryStore);
    AsyncCallFuture<VolumeApiResult> future = volumeService.createVolumeAsync(vol, primaryStore);
    try {
      future.get();
    } catch (InterruptedException e) {
      // TODO Auto-generated catch block
      e.printStackTrace();
    } catch (ExecutionException e) {
      // TODO Auto-generated catch block
      e.printStackTrace();
    }

    // delete the volume
    vol = volumeFactory.getVolume(volume.getId(), primaryStore);
    future = volumeService.expungeVolumeAsync(vol);
    try {
      future.get();
    } catch (InterruptedException e) {
      // TODO Auto-generated catch block
      e.printStackTrace();
    } catch (ExecutionException e) {
      // TODO Auto-generated catch block
      e.printStackTrace();
    }
  }
 @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);
     }
   }
 }
  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;
  }
  @Override
  public AsyncCallFuture<TemplateApiResult> copyTemplate(
      TemplateInfo srcTemplate, DataStore destStore) {
    // generate a URL from source template ssvm to download to destination data store
    String url = generateCopyUrl(srcTemplate);
    if (url == null) {
      s_logger.warn(
          "Unable to start/resume copy of template "
              + srcTemplate.getUniqueName()
              + " to "
              + destStore.getName()
              + ", no secondary storage vm in running state in source zone");
      throw new CloudRuntimeException("No secondary VM in running state in source template zone ");
    }

    TemplateObject tmplForCopy =
        (TemplateObject) _templateFactory.getTemplate(srcTemplate, destStore);
    if (s_logger.isDebugEnabled()) {
      s_logger.debug("Setting source template url to " + url);
    }
    tmplForCopy.setUrl(url);

    if (s_logger.isDebugEnabled()) {
      s_logger.debug("Mark template_store_ref entry as Creating");
    }
    AsyncCallFuture<TemplateApiResult> future = new AsyncCallFuture<TemplateApiResult>();
    DataObject templateOnStore = destStore.create(tmplForCopy);
    templateOnStore.processEvent(Event.CreateOnlyRequested);

    if (s_logger.isDebugEnabled()) {
      s_logger.debug("Invoke datastore driver createAsync to create template on destination store");
    }
    try {
      TemplateOpContext<TemplateApiResult> context =
          new TemplateOpContext<TemplateApiResult>(null, (TemplateObject) templateOnStore, future);
      AsyncCallbackDispatcher<TemplateServiceImpl, CreateCmdResult> caller =
          AsyncCallbackDispatcher.create(this);
      caller
          .setCallback(caller.getTarget().copyTemplateCrossZoneCallBack(null, null))
          .setContext(context);
      destStore.getDriver().createAsync(destStore, templateOnStore, caller);
    } catch (CloudRuntimeException ex) {
      // clean up already persisted template_store_ref entry in case of createTemplateCallback is
      // never called
      TemplateDataStoreVO templateStoreVO =
          _vmTemplateStoreDao.findByStoreTemplate(destStore.getId(), srcTemplate.getId());
      if (templateStoreVO != null) {
        TemplateInfo tmplObj = _templateFactory.getTemplate(srcTemplate, destStore);
        tmplObj.processEvent(ObjectInDataStoreStateMachine.Event.OperationFailed);
      }
      TemplateApiResult res = new TemplateApiResult((TemplateObject) templateOnStore);
      res.setResult(ex.getMessage());
      future.complete(res);
    }
    return future;
  }
Ejemplo n.º 10
0
 @Test(priority = 2)
 public void createVolumeFromTemplate() {
   DataStore primaryStore = this.primaryStore;
   TemplateInfo te = createTemplate();
   VolumeVO volume = createVolume(te.getId(), primaryStore.getId());
   VolumeInfo vol = volumeFactory.getVolume(volume.getId(), primaryStore);
   // ve.createVolumeFromTemplate(primaryStore.getId(), new VHD(), te);
   AsyncCallFuture<VolumeApiResult> future =
       volumeService.createVolumeFromTemplateAsync(vol, primaryStore.getId(), te);
   try {
     future.get();
   } catch (InterruptedException e) {
     // TODO Auto-generated catch block
     e.printStackTrace();
   } catch (ExecutionException e) {
     // TODO Auto-generated catch block
     e.printStackTrace();
   }
 }
 @Override
 public void createAsync(
     DataStore dataStore, DataObject data, AsyncCompletionCallback<CreateCmdResult> callback) {
   CreateContext<CreateCmdResult> context = new CreateContext<CreateCmdResult>(callback, data);
   AsyncCallbackDispatcher<BaseImageStoreDriverImpl, DownloadAnswer> caller =
       AsyncCallbackDispatcher.create(this);
   caller.setContext(context);
   if (data.getType() == DataObjectType.TEMPLATE) {
     caller.setCallback(caller.getTarget().createTemplateAsyncCallback(null, null));
     if (s_logger.isDebugEnabled()) {
       s_logger.debug("Downloading template to data store " + dataStore.getId());
     }
     _downloadMonitor.downloadTemplateToStorage(data, caller);
   } else if (data.getType() == DataObjectType.VOLUME) {
     caller.setCallback(caller.getTarget().createVolumeAsyncCallback(null, null));
     if (s_logger.isDebugEnabled()) {
       s_logger.debug("Downloading volume to data store " + dataStore.getId());
     }
     _downloadMonitor.downloadVolumeToStorage(data, caller);
   }
 }
 @Override
 public boolean attachZone(DataStore dataStore, ZoneScope scope, HypervisorType hypervisorType) {
   List<HostVO> hosts =
       _resourceMgr.listAllUpAndEnabledHostsInOneZoneByHypervisor(
           hypervisorType, scope.getScopeId());
   s_logger.debug("In createPool. Attaching the pool to each of the hosts.");
   List<HostVO> poolHosts = new ArrayList<HostVO>();
   for (HostVO host : hosts) {
     try {
       this.storageMgr.connectHostToSharedPool(host.getId(), dataStore.getId());
       poolHosts.add(host);
     } catch (Exception e) {
       s_logger.warn("Unable to establish a connection between " + host + " and " + dataStore, e);
     }
   }
   if (poolHosts.isEmpty()) {
     s_logger.warn("No host can access storage pool " + dataStore + " in this zone.");
     primaryDataStoreDao.expunge(dataStore.getId());
     throw new CloudRuntimeException(
         "Failed to create storage pool as it is not accessible to hosts.");
   }
   this.dataStoreHelper.attachZone(dataStore, hypervisorType);
   return true;
 }
  @Override
  public void deleteAsync(
      DataStore dataStore, DataObject dataObject, AsyncCompletionCallback<CommandResult> callback) {
    String errMsg = null;

    if (dataObject.getType() == DataObjectType.VOLUME) {
      VolumeInfo volumeInfo = (VolumeInfo) dataObject;
      AccountVO account = _accountDao.findById(volumeInfo.getAccountId());
      AccountDetailVO accountDetails =
          _accountDetailsDao.findDetail(account.getAccountId(), SolidFireUtil.ACCOUNT_ID);
      long sfAccountId = Long.parseLong(accountDetails.getValue());

      long storagePoolId = dataStore.getId();
      SolidFireConnection sfConnection = getSolidFireConnection(storagePoolId);

      deleteSolidFireVolume(volumeInfo, sfConnection);

      _volumeDao.deleteVolumesByInstance(volumeInfo.getId());

      //            if (!sfAccountHasVolume(sfAccountId, sfConnection)) {
      //                // delete the account from the SolidFire SAN
      //                deleteSolidFireAccount(sfAccountId, sfConnection);
      //
      //                // delete the info in the account_details table
      //                // that's related to the SolidFire account
      //                _accountDetailsDao.deleteDetails(account.getAccountId());
      //            }

      StoragePoolVO storagePool = _storagePoolDao.findById(storagePoolId);

      long usedBytes = storagePool.getUsedBytes();

      usedBytes -= volumeInfo.getSize();

      storagePool.setUsedBytes(usedBytes < 0 ? 0 : usedBytes);

      _storagePoolDao.update(storagePoolId, storagePool);
    } else {
      errMsg = "Invalid DataObjectType (" + dataObject.getType() + ") passed to deleteAsync";
    }

    CommandResult result = new CommandResult();

    result.setResult(errMsg);

    callback.complete(result);
  }
  @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);
        }
      }
    }
  }
  @Override
  public void createTemplateAsync(
      TemplateInfo template, DataStore store, AsyncCompletionCallback<TemplateApiResult> callback) {
    // persist template_store_ref entry
    TemplateObject templateOnStore = (TemplateObject) store.create(template);
    // update template_store_ref and template state
    try {
      templateOnStore.processEvent(ObjectInDataStoreStateMachine.Event.CreateOnlyRequested);
    } catch (Exception e) {
      TemplateApiResult result = new TemplateApiResult(templateOnStore);
      result.setResult(e.toString());
      result.setSuccess(false);
      if (callback != null) {
        callback.complete(result);
      }
      return;
    }

    try {
      TemplateOpContext<TemplateApiResult> context =
          new TemplateOpContext<TemplateApiResult>(callback, templateOnStore, null);

      AsyncCallbackDispatcher<TemplateServiceImpl, CreateCmdResult> caller =
          AsyncCallbackDispatcher.create(this);
      caller.setCallback(caller.getTarget().createTemplateCallback(null, null)).setContext(context);
      store.getDriver().createAsync(store, templateOnStore, caller);
    } catch (CloudRuntimeException ex) {
      // clean up already persisted template_store_ref entry in case of createTemplateCallback is
      // never called
      TemplateDataStoreVO templateStoreVO =
          _vmTemplateStoreDao.findByStoreTemplate(store.getId(), template.getId());
      if (templateStoreVO != null) {
        TemplateInfo tmplObj = _templateFactory.getTemplate(template, store);
        tmplObj.processEvent(ObjectInDataStoreStateMachine.Event.OperationFailed);
      }
      TemplateApiResult result = new TemplateApiResult(template);
      result.setResult(ex.getMessage());
      if (callback != null) {
        callback.complete(result);
      }
    }
  }
  private Map<String, TemplateProp> listTemplate(DataStore ssStore) {
    ListTemplateCommand cmd = new ListTemplateCommand(ssStore.getTO());
    EndPoint ep = _epSelector.select(ssStore);
    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(cmd, false, errMsg);
    } else {
      answer = ep.sendMessage(cmd);
    }
    if (answer != null && answer.getResult()) {
      ListTemplateAnswer tanswer = (ListTemplateAnswer) answer;
      return tanswer.getTemplateInfo();
    } else {
      if (s_logger.isDebugEnabled()) {
        s_logger.debug("can not list template for secondary storage host " + ssStore.getId());
      }
    }

    return null;
  }
 @Override
 public void downloadTemplateToStorage(
     DataObject template, AsyncCompletionCallback<DownloadAnswer> callback) {
   if (template != null) {
     long templateId = template.getId();
     DataStore store = template.getDataStore();
     if (isTemplateUpdateable(templateId, store.getId())) {
       if (template.getUri() != null) {
         initiateTemplateDownload(template, callback);
       } else {
         s_logger.info("Template url is null, cannot download");
         DownloadAnswer ans = new DownloadAnswer("Template url is null", Status.UNKNOWN);
         callback.complete(ans);
       }
     } else {
       s_logger.info("Template download is already in progress or already downloaded");
       DownloadAnswer ans =
           new DownloadAnswer(
               "Template download is already in progress or already downloaded", Status.UNKNOWN);
       callback.complete(ans);
     }
   }
 }
  @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);
        }
      }
    }
  }
  @DB
  @Override
  public boolean deleteDataStore(DataStore store) {
    List<StoragePoolHostVO> hostPoolRecords = _storagePoolHostDao.listByPoolId(store.getId());
    StoragePool pool = (StoragePool) store;
    boolean deleteFlag = false;
    // find the hypervisor where the storage is attached to.
    HypervisorType hType = null;
    if (hostPoolRecords.size() > 0) {
      hType = getHypervisorType(hostPoolRecords.get(0).getHostId());
    }

    // Remove the SR associated with the Xenserver
    for (StoragePoolHostVO host : hostPoolRecords) {
      DeleteStoragePoolCommand deleteCmd = new DeleteStoragePoolCommand(pool);
      final Answer answer = agentMgr.easySend(host.getHostId(), deleteCmd);

      if (answer != null && answer.getResult()) {
        deleteFlag = true;
        // if host is KVM hypervisor then send deleteStoragepoolcmd to all the kvm hosts.
        if (HypervisorType.KVM != hType) {
          break;
        }
      } else {
        if (answer != null) {
          s_logger.debug("Failed to delete storage pool: " + answer.getResult());
        }
      }
    }

    if (!deleteFlag) {
      throw new CloudRuntimeException("Failed to delete storage pool on host");
    }

    return dataStoreHelper.deletePrimaryDataStore(store);
  }
  @Override
  public AsyncCallFuture<TemplateApiResult> copyTemplate(
      TemplateInfo srcTemplate, DataStore destStore) {
    // for vmware template, we need to check if ova packing is needed, since template created from
    // snapshot does not have .ova file
    // we invoke createEntityExtractURL to trigger ova packing. Ideally, we can directly use
    // extractURL to pass to following createTemplate.
    // Need to understand what is the background to use two different urls for copy and extract.
    if (srcTemplate.getFormat() == ImageFormat.OVA) {
      ImageStoreEntity tmpltStore = (ImageStoreEntity) srcTemplate.getDataStore();
      tmpltStore.createEntityExtractUrl(
          srcTemplate.getInstallPath(), srcTemplate.getFormat(), srcTemplate);
    }
    // generate a URL from source template ssvm to download to destination data store
    String url = generateCopyUrl(srcTemplate);
    if (url == null) {
      s_logger.warn(
          "Unable to start/resume copy of template "
              + srcTemplate.getUniqueName()
              + " to "
              + destStore.getName()
              + ", no secondary storage vm in running state in source zone");
      throw new CloudRuntimeException("No secondary VM in running state in source template zone ");
    }

    TemplateObject tmplForCopy =
        (TemplateObject) _templateFactory.getTemplate(srcTemplate, destStore);
    if (s_logger.isDebugEnabled()) {
      s_logger.debug("Setting source template url to " + url);
    }
    tmplForCopy.setUrl(url);

    if (s_logger.isDebugEnabled()) {
      s_logger.debug("Mark template_store_ref entry as Creating");
    }
    AsyncCallFuture<TemplateApiResult> future = new AsyncCallFuture<TemplateApiResult>();
    DataObject templateOnStore = destStore.create(tmplForCopy);
    templateOnStore.processEvent(Event.CreateOnlyRequested);

    if (s_logger.isDebugEnabled()) {
      s_logger.debug("Invoke datastore driver createAsync to create template on destination store");
    }
    try {
      TemplateOpContext<TemplateApiResult> context =
          new TemplateOpContext<TemplateApiResult>(null, (TemplateObject) templateOnStore, future);
      AsyncCallbackDispatcher<TemplateServiceImpl, CreateCmdResult> caller =
          AsyncCallbackDispatcher.create(this);
      caller
          .setCallback(caller.getTarget().copyTemplateCrossZoneCallBack(null, null))
          .setContext(context);
      destStore.getDriver().createAsync(destStore, templateOnStore, caller);
    } catch (CloudRuntimeException ex) {
      // clean up already persisted template_store_ref entry in case of createTemplateCallback is
      // never called
      TemplateDataStoreVO templateStoreVO =
          _vmTemplateStoreDao.findByStoreTemplate(destStore.getId(), srcTemplate.getId());
      if (templateStoreVO != null) {
        TemplateInfo tmplObj = _templateFactory.getTemplate(srcTemplate, destStore);
        tmplObj.processEvent(ObjectInDataStoreStateMachine.Event.OperationFailed);
      }
      TemplateApiResult res = new TemplateApiResult((TemplateObject) templateOnStore);
      res.setResult(ex.getMessage());
      future.complete(res);
    }
    return future;
  }
  @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();
    }
  }
  @Override
  public void downloadVolumeToStorage(
      DataObject volume, AsyncCompletionCallback<DownloadAnswer> callback) {
    boolean downloadJobExists = false;
    VolumeDataStoreVO volumeHost = null;
    DataStore store = volume.getDataStore();
    VolumeInfo volInfo = (VolumeInfo) volume;
    RegisterVolumePayload payload = (RegisterVolumePayload) volInfo.getpayload();
    String url = payload.getUrl();
    String checkSum = payload.getChecksum();
    ImageFormat format = ImageFormat.valueOf(payload.getFormat());

    volumeHost = _volumeStoreDao.findByStoreVolume(store.getId(), volume.getId());
    if (volumeHost == null) {
      volumeHost =
          new VolumeDataStoreVO(
              store.getId(),
              volume.getId(),
              new Date(),
              0,
              Status.NOT_DOWNLOADED,
              null,
              null,
              "jobid0000",
              null,
              url,
              checkSum);
      _volumeStoreDao.persist(volumeHost);
    } else if ((volumeHost.getJobId() != null) && (volumeHost.getJobId().length() > 2)) {
      downloadJobExists = true;
    }

    Long maxVolumeSizeInBytes = getMaxVolumeSizeInBytes();
    if (volumeHost != null) {
      start();
      Volume vol = _volumeDao.findById(volume.getId());
      DownloadCommand dcmd =
          new DownloadCommand(
              (VolumeObjectTO) (volume.getTO()), maxVolumeSizeInBytes, checkSum, url, format);
      dcmd.setProxy(getHttpProxy());
      if (downloadJobExists) {
        dcmd = new DownloadProgressCommand(dcmd, volumeHost.getJobId(), RequestType.GET_OR_RESTART);
        dcmd.setResourceType(ResourceType.VOLUME);
      }

      EndPoint ep = _epSelector.select(volume);
      if (ep == null) {
        s_logger.warn("There is no secondary storage VM for image store " + store.getName());
        return;
      }
      DownloadListener dl = new DownloadListener(ep, store, volume, _timer, this, dcmd, callback);
      ComponentContext.inject(dl); // auto-wired those injected fields in DownloadListener

      if (downloadJobExists) {
        dl.setCurrState(volumeHost.getDownloadState());
      }

      try {
        ep.sendMessageAsync(dcmd, new UploadListener.Callback(ep.getId(), dl));
      } catch (Exception e) {
        s_logger.warn(
            "Unable to start /resume download of volume "
                + volume.getId()
                + " to "
                + store.getName(),
            e);
        dl.setDisconnected();
        dl.scheduleStatusCheck(RequestType.GET_OR_RESTART);
      }
    }
  }
  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);
      }
    }
  }