@Override
  public void preRecoverDataVolume(VolumeInventory vol) {
    if (vol.getPrimaryStorageUuid() == null) {
      return;
    }

    SimpleQuery<PrimaryStorageVO> q = dbf.createQuery(PrimaryStorageVO.class);
    q.select(PrimaryStorageVO_.type);
    q.add(PrimaryStorageVO_.uuid, Op.EQ, vol.getPrimaryStorageUuid());
    String type = q.findValue();
    if (!LocalStorageConstants.LOCAL_STORAGE_TYPE.equals(type)) {
      return;
    }

    SimpleQuery<LocalStorageResourceRefVO> rq = dbf.createQuery(LocalStorageResourceRefVO.class);
    rq.add(LocalStorageResourceRefVO_.resourceUuid, Op.EQ, vol.getUuid());
    rq.add(LocalStorageResourceRefVO_.resourceType, Op.EQ, VolumeVO.class.getSimpleName());
    if (!rq.isExists()) {
      throw new OperationFailureException(
          errf.stringToOperationError(
              String.format(
                  "the data volume[name:%s, uuid:%s] is on the local storage[uuid:%s]; however,"
                      + "the host on which the data volume is has been deleted. Unable to recover this volume",
                  vol.getName(), vol.getUuid(), vol.getPrimaryStorageUuid())));
    }
  }
  @Override
  public NetworkServiceProviderType getTypeOfNetworkServiceProviderForService(
      String l3NetworkUuid, NetworkServiceType serviceType) {
    L3NetworkVO l3vo = dbf.findByUuid(l3NetworkUuid, L3NetworkVO.class);
    L3NetworkInventory l3inv = L3NetworkInventory.valueOf(l3vo);
    NetworkServiceL3NetworkRefInventory targetRef = null;
    for (NetworkServiceL3NetworkRefInventory ref : l3inv.getNetworkServices()) {
      if (ref.getNetworkServiceType().equals(serviceType.toString())) {
        targetRef = ref;
        break;
      }
    }

    if (targetRef == null) {
      throw new OperationFailureException(
          errf.stringToOperationError(
              String.format(
                  "L3Network[uuid:%s] doesn't have network service[type:%s] enabled or no provider provides this network service",
                  l3NetworkUuid, serviceType)));
    }

    SimpleQuery<NetworkServiceProviderVO> q = dbf.createQuery(NetworkServiceProviderVO.class);
    q.select(NetworkServiceProviderVO_.type);
    q.add(NetworkServiceProviderVO_.uuid, Op.EQ, targetRef.getNetworkServiceProviderUuid());
    String providerType = q.findValue();
    return NetworkServiceProviderType.valueOf(providerType);
  }
Exemple #3
0
 public List<String> getTags(String resourceUuid, Class resourceClass) {
   SimpleQuery<SystemTagVO> q = dbf.createQuery(SystemTagVO.class);
   q.select(SystemTagVO_.tag);
   q.add(SystemTagVO_.resourceType, Op.EQ, resourceClass.getSimpleName());
   q.add(SystemTagVO_.resourceUuid, Op.EQ, resourceUuid);
   q.add(SystemTagVO_.tag, useOp(), useTagFormat());
   return q.listValue();
 }
  private void handle(APIDetachNetworkServiceProviderFromL2NetworkMsg msg) {
    NetworkServiceProviderVO vo =
        dbf.findByUuid(msg.getNetworkServiceProviderUuid(), NetworkServiceProviderVO.class);
    NetworkServiceProviderFactory factory = getProviderFactory(vo.getType());
    NetworkServiceProvider provider = factory.getNetworkServiceProvider(vo);
    L2NetworkVO l2vo = dbf.findByUuid(msg.getL2NetworkUuid(), L2NetworkVO.class);

    APIDetachNetworkServiceProviderFromL2NetworkEvent evt =
        new APIDetachNetworkServiceProviderFromL2NetworkEvent(msg.getId());
    try {
      provider.detachFromL2Network(L2NetworkInventory.valueOf(l2vo), msg);
    } catch (NetworkException e) {
      String err =
          String.format(
              "unable to detach network service provider[uuid:%s, name:%s, type:%s] to l2network[uuid:%s, name:%s, type:%s], %s",
              vo.getUuid(),
              vo.getName(),
              vo.getType(),
              l2vo.getUuid(),
              l2vo.getName(),
              l2vo.getType(),
              e.getMessage());
      logger.warn(err, e);
      evt.setErrorCode(
          errf.instantiateErrorCode(
              NetworkServiceErrors.DETACH_NETWORK_SERVICE_PROVIDER_ERROR, err));
      bus.publish(evt);
      return;
    }

    SimpleQuery<NetworkServiceProviderL2NetworkRefVO> query =
        dbf.createQuery(NetworkServiceProviderL2NetworkRefVO.class);
    query.select(NetworkServiceProviderL2NetworkRefVO_.id);
    query.add(NetworkServiceProviderL2NetworkRefVO_.l2NetworkUuid, Op.EQ, l2vo.getUuid());
    query.add(
        NetworkServiceProviderL2NetworkRefVO_.networkServiceProviderUuid, Op.EQ, vo.getUuid());
    Long id = query.findValue();
    if (id != null) {
      dbf.removeByPrimaryKey(id, NetworkServiceProviderL2NetworkRefVO.class);
    }

    vo = dbf.findByUuid(vo.getUuid(), NetworkServiceProviderVO.class);
    evt.setInventory(NetworkServiceProviderInventory.valueOf(vo));
    String info =
        String.format(
            "successfully detach network service provider[uuid:%s, name:%s, type:%s] to l2network[uuid:%s, name:%s, type:%s]",
            vo.getUuid(),
            vo.getName(),
            vo.getType(),
            l2vo.getUuid(),
            l2vo.getName(),
            l2vo.getType());
    logger.debug(info);
    bus.publish(evt);
  }
  @Override
  public void preAttachVolume(VmInstanceInventory vm, final VolumeInventory volume) {
    SimpleQuery<LocalStorageResourceRefVO> q = dbf.createQuery(LocalStorageResourceRefVO.class);
    q.add(
        LocalStorageResourceRefVO_.resourceUuid,
        Op.IN,
        list(vm.getRootVolumeUuid(), volume.getUuid()));
    q.groupBy(LocalStorageResourceRefVO_.hostUuid);
    long count = q.count();

    if (count < 2) {
      return;
    }

    q = dbf.createQuery(LocalStorageResourceRefVO.class);
    q.select(LocalStorageResourceRefVO_.hostUuid);
    q.add(LocalStorageResourceRefVO_.resourceUuid, Op.EQ, vm.getRootVolumeUuid());
    String rootHost = q.findValue();

    q = dbf.createQuery(LocalStorageResourceRefVO.class);
    q.select(LocalStorageResourceRefVO_.hostUuid);
    q.add(LocalStorageResourceRefVO_.resourceUuid, Op.EQ, volume.getUuid());
    String dataHost = q.findValue();

    if (!rootHost.equals(dataHost)) {
      throw new OperationFailureException(
          errf.stringToOperationError(
              String.format(
                  "cannot attach the data volume[uuid:%s] to the vm[uuid:%s]. Both vm's root volume and the data volume are"
                      + " on local primary storage, but they are on different hosts. The root volume[uuid:%s] is on the host[uuid:%s] but the data volume[uuid: %s]"
                      + " is on the host[uuid: %s]",
                  volume.getUuid(),
                  vm.getUuid(),
                  vm.getRootVolumeUuid(),
                  rootHost,
                  volume.getUuid(),
                  dataHost)));
    }
  }
  @Override
  public void run(final FlowTrigger trigger, final Map data) {
    final VmInstanceSpec spec =
        (VmInstanceSpec) data.get(VmInstanceConstant.Params.VmInstanceSpec.toString());
    VolumeInventory volume = spec.getDestDataVolumes().get(0);

    SimpleQuery<LocalStorageResourceRefVO> q = dbf.createQuery(LocalStorageResourceRefVO.class);
    q.select(LocalStorageResourceRefVO_.hostUuid, LocalStorageResourceRefVO_.primaryStorageUuid);
    q.add(
        LocalStorageResourceRefVO_.resourceUuid, Op.EQ, spec.getVmInventory().getRootVolumeUuid());
    Tuple t = q.findTuple();
    final String hostUuid = t.get(0, String.class);
    String priUuid = t.get(1, String.class);

    AllocatePrimaryStorageMsg msg = new AllocatePrimaryStorageMsg();
    if (isThereOtherStorageForTheHost(hostUuid, priUuid)) {
      // use network-shared primary storage
      msg.addExcludeAllocatorStrategy(LocalStorageConstants.LOCAL_STORAGE_ALLOCATOR_STRATEGY);
      msg.addExcludePrimaryStoratgeUuid(priUuid);
    } else {
      msg.setAllocationStrategy(LocalStorageConstants.LOCAL_STORAGE_ALLOCATOR_STRATEGY);
      msg.setRequiredPrimaryStorageUuid(
          spec.getVmInventory().getRootVolume().getPrimaryStorageUuid());
    }

    msg.setRequiredHostUuid(hostUuid);
    msg.setVmInstanceUuid(spec.getVmInventory().getUuid());
    msg.setSize(volume.getSize());
    msg.setPurpose(PrimaryStorageAllocationPurpose.CreateVolume.toString());
    bus.makeLocalServiceId(msg, PrimaryStorageConstant.SERVICE_ID);
    bus.send(
        msg,
        new CloudBusCallBack(trigger) {
          @Override
          public void run(MessageReply reply) {
            if (!reply.isSuccess()) {
              trigger.fail(reply.getError());
              return;
            }

            spec.setDestHost(HostInventory.valueOf(dbf.findByUuid(hostUuid, HostVO.class)));

            AllocatePrimaryStorageReply ar = (AllocatePrimaryStorageReply) reply;
            data.put(
                VmInstanceConstant.Params.DestPrimaryStorageInventoryForAttachingVolume.toString(),
                ar.getPrimaryStorageInventory());
            data.put(LocalStorageAllocateCapacityForAttachingVolumeFlow.class, ar.getSize());
            trigger.next();
          }
        });
  }
  private String steppingAllocate(long s, long e, int total, String rangeUuid) {
    int step = 254;
    int failureCount = 0;
    int failureCheckPoint = 5;

    while (s < e) {
      // if failing failureCheckPoint times, the range is probably full,
      // we check the range.
      // why don't we check before steppingAllocate()? because in that case we
      // have to count the used IP every time allocating a IP, and count operation
      // is a full scan in DB, which is very costly
      if (failureCheckPoint == failureCount++) {
        SimpleQuery<UsedIpVO> q = dbf.createQuery(UsedIpVO.class);
        q.add(UsedIpVO_.ipRangeUuid, Op.EQ, rangeUuid);
        long count = q.count();
        if (count == total) {
          logger.debug(
              String.format("ip range[uuid:%s] has no ip available, try next one", rangeUuid));
          return null;
        } else {
          failureCount = 0;
        }
      }

      long te = s + step;
      te = te > e ? e : te;
      SimpleQuery<UsedIpVO> q = dbf.createQuery(UsedIpVO.class);
      q.select(UsedIpVO_.ipInLong);
      q.add(UsedIpVO_.ipInLong, Op.GTE, s);
      q.add(UsedIpVO_.ipInLong, Op.LTE, te);
      q.add(UsedIpVO_.ipRangeUuid, Op.EQ, rangeUuid);
      List<Long> used = q.listValue();
      if (te - s + 1 == used.size()) {
        s += step;
        continue;
      }

      Collections.sort(used);

      return NetworkUtils.randomAllocateIpv4Address(s, te, used);
    }

    return null;
  }
Exemple #8
0
 public Map<String, List<String>> getTags(List<String> resourceUuids, Class resourceClass) {
   SimpleQuery<SystemTagVO> q = dbf.createQuery(SystemTagVO.class);
   q.select(SystemTagVO_.tag, SystemTagVO_.resourceUuid);
   q.add(SystemTagVO_.resourceType, Op.EQ, resourceClass.getSimpleName());
   q.add(SystemTagVO_.resourceUuid, Op.IN, resourceUuids);
   q.add(SystemTagVO_.tag, useOp(), useTagFormat());
   List<Tuple> ts = q.listTuple();
   Map<String, List<String>> ret = new HashMap<String, List<String>>();
   for (Tuple t : ts) {
     String uuid = t.get(1, String.class);
     List<String> tags = ret.get(uuid);
     if (tags == null) {
       tags = new ArrayList<String>();
       ret.put(uuid, tags);
     }
     tags.add(t.get(0, String.class));
   }
   return ret;
 }
  @Override
  public void run(final FlowTrigger chain, final Map data) {
    final VirtualRouterVmInventory vr =
        (VirtualRouterVmInventory) data.get(VirtualRouterConstant.Param.VR.toString());

    List<String> nwServed = vr.getGuestL3Networks();
    List<String> l3Uuids =
        vrMgr.selectL3NetworksNeedingSpecificNetworkService(nwServed, NetworkServiceType.DNS);
    if (l3Uuids.isEmpty()) {
      chain.next();
      return;
    }

    if (VirtualRouterSystemTags.DEDICATED_ROLE_VR.hasTag(vr.getUuid())
        && !VirtualRouterSystemTags.VR_DNS_ROLE.hasTag(vr.getUuid())) {
      chain.next();
      return;
    }

    new VirtualRouterRoleManager().makeDnsRole(vr.getUuid());

    SimpleQuery<L3NetworkDnsVO> query = dbf.createQuery(L3NetworkDnsVO.class);
    query.select(L3NetworkDnsVO_.dns);
    query.add(L3NetworkDnsVO_.l3NetworkUuid, Op.IN, l3Uuids);
    List<String> lst = query.listValue();
    if (lst.isEmpty()) {
      chain.next();
      return;
    }

    Set<String> dnsAddresses = new HashSet<String>(lst.size());
    dnsAddresses.addAll(lst);

    final List<DnsInfo> dns = new ArrayList<DnsInfo>(dnsAddresses.size());
    for (String d : dnsAddresses) {
      DnsInfo dinfo = new DnsInfo();
      dinfo.setDnsAddress(d);
      dns.add(dinfo);
    }

    SetDnsCmd cmd = new SetDnsCmd();
    cmd.setDns(dns);

    VirtualRouterAsyncHttpCallMsg msg = new VirtualRouterAsyncHttpCallMsg();
    msg.setVmInstanceUuid(vr.getUuid());
    msg.setPath(VirtualRouterConstant.VR_SET_DNS_PATH);
    msg.setCommand(cmd);
    msg.setCommandTimeout(apiTimeoutManager.getTimeout(cmd.getClass(), "5m"));
    bus.makeTargetServiceIdByResourceUuid(msg, VmInstanceConstant.SERVICE_ID, vr.getUuid());
    bus.send(
        msg,
        new CloudBusCallBack(chain) {
          @Override
          public void run(MessageReply reply) {
            if (!reply.isSuccess()) {
              chain.fail(reply.getError());
              return;
            }

            VirtualRouterAsyncHttpCallReply re = reply.castReply();
            SetDnsRsp ret = re.toResponse(SetDnsRsp.class);
            if (ret.isSuccess()) {
              chain.next();
            } else {
              String err =
                  String.format(
                      "virtual router[name: %s, uuid: %s] failed to configure dns%s, %s ",
                      vr.getName(), vr.getUuid(), JSONObjectUtil.toJsonString(dns), ret.getError());
              logger.warn(err);
              chain.fail(errf.stringToOperationError(err));
            }
          }
        });
  }
  @Override
  public void beforeDeleteHost(final HostInventory inventory) {
    SimpleQuery<LocalStorageHostRefVO> q = dbf.createQuery(LocalStorageHostRefVO.class);
    q.select(LocalStorageHostRefVO_.primaryStorageUuid);
    q.add(LocalStorageHostRefVO_.hostUuid, Op.EQ, inventory.getUuid());
    final String psUuid = q.findValue();
    if (psUuid == null) {
      return;
    }

    logger.debug(
        String.format(
            "the host[uuid:%s] belongs to the local storage[uuid:%s], starts to delete vms and"
                + " volumes on the host",
            inventory.getUuid(), psUuid));

    final List<String> vmUuids =
        new Callable<List<String>>() {
          @Override
          @Transactional(readOnly = true)
          public List<String> call() {
            String sql =
                "select vm.uuid from VolumeVO vol, LocalStorageResourceRefVO ref, VmInstanceVO vm where ref.primaryStorageUuid = :psUuid"
                    + " and vol.type = :vtype and ref.resourceUuid = vol.uuid and ref.resourceType = :rtype and ref.hostUuid = :huuid"
                    + " and vm.uuid = vol.vmInstanceUuid";
            TypedQuery<String> q = dbf.getEntityManager().createQuery(sql, String.class);
            q.setParameter("vtype", VolumeType.Root);
            q.setParameter("rtype", VolumeVO.class.getSimpleName());
            q.setParameter("huuid", inventory.getUuid());
            q.setParameter("psUuid", psUuid);
            return q.getResultList();
          }
        }.call();

    // destroy vms
    if (!vmUuids.isEmpty()) {
      List<DestroyVmInstanceMsg> msgs =
          CollectionUtils.transformToList(
              vmUuids,
              new Function<DestroyVmInstanceMsg, String>() {
                @Override
                public DestroyVmInstanceMsg call(String uuid) {
                  DestroyVmInstanceMsg msg = new DestroyVmInstanceMsg();
                  msg.setVmInstanceUuid(uuid);
                  bus.makeTargetServiceIdByResourceUuid(msg, VmInstanceConstant.SERVICE_ID, uuid);
                  return msg;
                }
              });

      final FutureCompletion completion = new FutureCompletion();
      bus.send(
          msgs,
          new CloudBusListCallBack(completion) {
            @Override
            public void run(List<MessageReply> replies) {
              for (MessageReply r : replies) {
                if (!r.isSuccess()) {
                  String vmUuid = vmUuids.get(replies.indexOf(r));
                  // TODO
                  logger.warn(
                      String.format("failed to destroy the vm[uuid:%s], %s", vmUuid, r.getError()));
                }
              }

              completion.success();
            }
          });

      completion.await(TimeUnit.MINUTES.toMillis(15));
    }

    final List<String> volUuids =
        new Callable<List<String>>() {
          @Override
          @Transactional(readOnly = true)
          public List<String> call() {
            String sql =
                "select vol.uuid from VolumeVO vol, LocalStorageResourceRefVO ref where ref.primaryStorageUuid = :psUuid"
                    + " and vol.type = :vtype and ref.resourceUuid = vol.uuid and ref.resourceType = :rtype and ref.hostUuid = :huuid";
            TypedQuery<String> q = dbf.getEntityManager().createQuery(sql, String.class);
            q.setParameter("psUuid", psUuid);
            q.setParameter("vtype", VolumeType.Data);
            q.setParameter("rtype", VolumeVO.class.getSimpleName());
            q.setParameter("huuid", inventory.getUuid());
            return q.getResultList();
          }
        }.call();

    // delete data volumes
    if (!volUuids.isEmpty()) {
      List<DeleteVolumeMsg> msgs =
          CollectionUtils.transformToList(
              volUuids,
              new Function<DeleteVolumeMsg, String>() {
                @Override
                public DeleteVolumeMsg call(String uuid) {
                  DeleteVolumeMsg msg = new DeleteVolumeMsg();
                  msg.setUuid(uuid);
                  msg.setDetachBeforeDeleting(true);
                  bus.makeTargetServiceIdByResourceUuid(msg, VolumeConstant.SERVICE_ID, uuid);
                  return msg;
                }
              });

      final FutureCompletion completion = new FutureCompletion();
      bus.send(
          msgs,
          new CloudBusListCallBack(completion) {
            @Override
            public void run(List<MessageReply> replies) {
              for (MessageReply r : replies) {
                if (!r.isSuccess()) {
                  String uuid = volUuids.get(replies.indexOf(r));
                  // TODO
                  logger.warn(
                      String.format(
                          "failed to delete the data volume[uuid:%s], %s", uuid, r.getError()));
                }
              }

              completion.success();
            }
          });

      completion.await(TimeUnit.MINUTES.toMillis(15));
    }
  }