예제 #1
0
 /**
  * Update the {@link #partitionActiveNetworkTags} map by removing any {@code key} values which
  * no longer have a corresponding service registration.
  *
  * @throws PersistenceException
  */
 private void removeStalePartitions() throws PersistenceException {
   Set<String> partitions = Sets.newHashSet();
   for (ServiceConfiguration cc : ServiceConfigurations.list(ClusterController.class)) {
     partitions.add(cc.getPartition());
   }
   for (String stalePartition :
       Sets.difference(this.activeTagsByPartition.keySet(), partitions)) {
     this.activeTagsByPartition.removeAll(stalePartition);
   }
 }
 @Override
 public void fireDisable(final ServiceConfiguration config) {
   if (config.isVmLocal() && noOtherEnabled(config))
     try {
       WorkflowClientManager.stop();
     } catch (Exception e) {
       logger.error("Error stopping workflow client", e);
     }
 }
 @Override
 public void fireEnable(final ServiceConfiguration config) throws ServiceRegistrationException {
   if (config.isVmLocal() && noOtherEnabled(config))
     try {
       WorkflowClientManager.start();
     } catch (Exception e) {
       throw new ServiceRegistrationException("Error creating workflow client", e);
     }
 }
예제 #4
0
 @Override
 public void fireEnable(ServiceConfiguration config) throws ServiceRegistrationException {
   if (!config.isVmLocal()) {
     for (Host h : Hosts.list()) {
       if (h.getHostAddresses().contains(config.getInetAddress())) {
         EventRecord.here(
                 EucalyptusBuilder.class, EventType.COMPONENT_SERVICE_ENABLED, config.toString())
             .info();
         return;
       }
     }
     throw Faults.failure(
         config,
         Exceptions.error(
             "There is no host in the system (yet) for the given cloud controller configuration: "
                 + config.getFullName()
                 + ".\nHosts are: "
                 + Hosts.list()));
   } else if (config.isVmLocal() && !Hosts.isCoordinator()) {
     throw Faults.failure(
         config,
         Exceptions.error(
             "This cloud controller "
                 + config.getFullName()
                 + " is not currently the coordinator "
                 + Hosts.list()));
   }
 }
예제 #5
0
 @Override
 public boolean apply(ServiceConfiguration config) {
   if (config.isVmLocal()) {
     if (!Databases.isSynchronized()) {
       throw Faults.failure(
           config,
           Exceptions.error(
               config.getFullName()
                   + ":fireCheck(): eucalyptus service "
                   + config.getFullName()
                   + " is currently synchronizing: "
                   + Hosts.getCoordinator()));
     } else if (Topology.isEnabledLocally(Eucalyptus.class)) {
       throw Faults.failure(
           config,
           Exceptions.error(
               config.getFullName()
                   + ":fireCheck(): eucalyptus service "
                   + config.getFullName()
                   + " cant be enabled when it is not the coordinator: "
                   + Hosts.getCoordinator()));
     } else {
       LOG.debug(
           config.getFullName()
               + ":fireCheck() completed with coordinator currently: "
               + Hosts.getCoordinator());
     }
   }
   return true;
 }
 public static DestroyServiceResponseType destroyService(final DestroyServiceType request)
     throws Exception {
   DestroyServiceResponseType reply = request.getReply();
   for (final ServiceId serviceInfo : request.getServices()) {
     try {
       final ServiceConfiguration service =
           TypeMappers.transform(serviceInfo, ServiceConfiguration.class);
       if (service.isVmLocal()) {
         try {
           Topology.destroy(service).get();
         } catch (final IllegalStateException ex) {
           LOG.error(ex, ex);
         }
       }
       reply.getServices().add(serviceInfo);
     } catch (final Exception ex) {
       LOG.error(ex);
       Logs.extreme().debug(ex, ex);
     }
   }
   return reply;
 }
 public static DisableServiceResponseType disableService(final DisableServiceType request)
     throws Exception {
   final DisableServiceResponseType reply = request.getReply();
   for (final ServiceId serviceInfo : request.getServices()) {
     try {
       final Component comp = Components.lookup(serviceInfo.getType());
       final ServiceConfiguration service =
           TypeMappers.transform(serviceInfo, ServiceConfiguration.class);
       if (service.isVmLocal()) {
         try {
           Topology.disable(service).get();
           reply.getServices().add(serviceInfo);
         } catch (final IllegalStateException ex) {
           LOG.error(ex, ex);
           throw ex;
         }
       }
     } catch (final NoSuchElementException ex) {
       LOG.error(ex, ex);
       throw ex;
     }
   }
   return reply;
 }
예제 #8
0
 @Override
 public void fireCheck(ServiceConfiguration config) throws ServiceRegistrationException {
   Host coordinator = Hosts.getCoordinator();
   if (coordinator == null) {
     throw Faults.failure(
         config,
         Exceptions.error(
             config.getFullName()
                 + ":fireCheck(): failed to lookup coordinator ("
                 + coordinator
                 + ")."));
   } else if (coordinator.isLocalHost()) {
     Check.COORDINATOR.apply(config);
   } else if (!coordinator.isLocalHost()) {
     Check.SECONDARY.apply(config);
   }
 }
  private void convertImages(final List<ImageInfo> images) {
    for (final ImageInfo image : images) {
      if (!(image instanceof MachineImageInfo)) continue;
      try {
        final MachineImageInfo machineImage = (MachineImageInfo) image;
        final String kernelId = machineImage.getKernelId();
        final String ramdiskId = machineImage.getRamdiskId();
        if (kernelId == null || ramdiskId == null) {
          LOG.warn(
              String.format(
                  "Kernel and ramdisk are not found for the image %s", image.getDisplayName()));
          continue;
        }

        final KernelImageInfo kernel = Images.lookupKernel(kernelId);
        final RamdiskImageInfo ramdisk = Images.lookupRamdisk(ramdiskId);
        final ServiceConfiguration osg = Topology.lookup(ObjectStorage.class);
        final URI osgUri = osg.getUri();
        final String osgPrefix =
            String.format(
                "%s://%s:%d%s",
                osgUri.getScheme(), osgUri.getHost(), osgUri.getPort(), osgUri.getPath());

        final String kernelManifest =
            String.format("%s/%s", osgPrefix, kernel.getManifestLocation());
        final String ramdiskManifest =
            String.format("%s/%s", osgPrefix, ramdisk.getManifestLocation());
        final String machineManifest =
            String.format("%s/%s", osgPrefix, machineImage.getManifestLocation());
        final String[] tokens = machineImage.getRunManifestLocation().split("/");
        final String bucket = tokens[0];
        final String prefix = tokens[1].replace(".manifest.xml", "");

        String taskId = null;
        try {
          final ImportImageBuilder builder = new ImportImageBuilder();
          final ImportImageTask task =
              new ImportImageTask(
                  builder
                      .withArchitecture(machineImage.getArchitecture().name())
                      .withBucket(bucket)
                      .withPrefix(prefix)
                      .withKernel(
                          kernel.getDisplayName(), kernelManifest, kernel.getImageSizeBytes())
                      .withRamdisk(
                          ramdisk.getDisplayName(), ramdiskManifest, ramdisk.getImageSizeBytes())
                      .withMachineImage(
                          machineImage.getDisplayName(),
                          machineManifest,
                          machineImage.getImageSizeBytes())
                      .withBucketUploadPolicy(bucket, prefix));
          final CheckedListenableFuture<Boolean> result = task.dispatch();
          if (result.get()) {
            taskId = task.getTaskId();
          }
        } catch (final Exception ex) {
          throw ex;
        }
        if (taskId == null) throw new Exception("ImportImage Task id is null");
        Images.setConversionTaskId(machineImage.getDisplayName(), taskId);
      } catch (final Exception ex) {
        LOG.error("Failed to convert the image: " + image.getDisplayName(), ex);
        try {
          this.cleanupBuckets(Lists.newArrayList(image), false);
          resetImagePendingAvailable(image.getDisplayName(), "Failed to request conversion");
        } catch (final Exception ex2) {
          LOG.error(
              "Failed to cleanup the image's system bucket; setting image state failed: "
                  + image.getDisplayName());
          try {
            Images.setImageState(image.getDisplayName(), ImageMetadata.State.failed);
          } catch (final Exception ex3) {;
          }
        }
      }
    }
  }
  @Override
  public void fireEvent(final Hertz event) {
    final long defaultPollIntervalSeconds = TimeUnit.MINUTES.toSeconds(DEFAULT_POLL_INTERVAL_MINS);
    if (!Bootstrap.isOperational()
        || !BootstrapArgs.isCloudController()
        || !event.isAsserted(defaultPollIntervalSeconds)) {
      return;
    } else {
      if (DEFAULT_POLL_INTERVAL_MINS >= 1) {
        COLLECTION_INTERVAL_TIME_MS =
            ((int) TimeUnit.MINUTES.toMillis(DEFAULT_POLL_INTERVAL_MINS) / 2);
      } else {
        COLLECTION_INTERVAL_TIME_MS = 0;
      }

      if (COLLECTION_INTERVAL_TIME_MS == 0 || HISTORY_SIZE > 15 || HISTORY_SIZE < 1) {
        LOG.debug("The instance usage report is disabled");
      } else if (COLLECTION_INTERVAL_TIME_MS <= MAX_WRITE_INTERVAL_MS) {

        try {
          if (event.isAsserted(defaultPollIntervalSeconds)) {
            if (Bootstrap.isFinished() && Hosts.isCoordinator()) {
              CloudWatchHelper.DefaultInstanceInfoProvider.refresh();
              for (final ServiceConfiguration ccConfig :
                  Topology.enabledServices(ClusterController.class)) {
                final String ccHost = ccConfig.getHostName();
                if (busyHosts.replace(ccHost, false, true)
                    || busyHosts.putIfAbsent(ccHost, true) == null) {
                  Threads.lookup(Reporting.class, DescribeSensorsListener.class)
                      .submit(
                          new Callable<Object>() {

                            @Override
                            public Object call() throws Exception {
                              final ExecutorService executorService =
                                  Threads.lookup(
                                          Reporting.class,
                                          DescribeSensorsListener.class,
                                          "response-processing")
                                      .limitTo(4);
                              final long startTime = System.currentTimeMillis();
                              try {
                                final List<String> allInstanceIds =
                                    VmInstances.listWithProjection(
                                        VmInstances.instanceIdProjection(),
                                        VmInstance.criterion(VmState.RUNNING),
                                        VmInstance.zoneCriterion(ccConfig.getPartition()),
                                        VmInstance.nonNullNodeCriterion());
                                final Iterable<List<String>> processInts =
                                    Iterables.partition(allInstanceIds, SENSOR_QUERY_BATCH_SIZE);
                                for (final List<String> instIds : processInts) {
                                  final ArrayList<String> instanceIds = Lists.newArrayList(instIds);
                                  /**
                                   * Here this is hijacking the sensor callback in order to control
                                   * the thread of execution used when firing
                                   */
                                  final DescribeSensorCallback msgCallback =
                                      new DescribeSensorCallback(
                                          HISTORY_SIZE, COLLECTION_INTERVAL_TIME_MS, instanceIds) {
                                        @Override
                                        public void fireException(Throwable e) {}

                                        @Override
                                        public void fire(DescribeSensorsResponse msg) {}
                                      };
                                  /**
                                   * Here we actually get the future reference to the result and on
                                   * a response processing thread, invoke .fire().
                                   */
                                  final DescribeSensorsResponse response =
                                      AsyncRequests.newRequest(msgCallback)
                                          .dispatch(ccConfig)
                                          .get();
                                  executorService.submit(
                                      new Runnable() {
                                        @Override
                                        public void run() {
                                          try {
                                            new DescribeSensorCallback(
                                                    HISTORY_SIZE,
                                                    COLLECTION_INTERVAL_TIME_MS,
                                                    instanceIds)
                                                .fire(response);
                                          } catch (Exception e) {
                                            Exceptions.maybeInterrupted(e);
                                          }
                                        }
                                      });
                                }
                              } finally {
                                /** Only and finally set the busy bit back to false. */
                                busyHosts.put(ccHost, false);
                                LOG.debug(
                                    "Sensor polling for "
                                        + ccHost
                                        + " took "
                                        + (System.currentTimeMillis() - startTime)
                                        + "ms");
                              }
                              return null;
                            }
                          });
                } else {
                  LOG.warn(
                      "Skipping sensors polling for " + ccHost + ", previous poll not complete.");
                }
              }
            }
          }
        } catch (Exception ex) {
          LOG.error("Unable to listen for describe sensors events", ex);
        }

      } else {
        LOG.error(
            "DEFAULT_POLL_INTERVAL_MINS : "
                + DEFAULT_POLL_INTERVAL_MINS
                + " must be less than 1440 minutes");
      }
    }
  }
예제 #11
0
  public DetachVolumeResponseType detach(DetachVolumeType request) throws EucalyptusCloudException {
    DetachVolumeResponseType reply = (DetachVolumeResponseType) request.getReply();
    Context ctx = Contexts.lookup();

    Volume vol;
    try {
      vol = Volumes.lookup(ctx.getUserFullName().asAccountFullName(), request.getVolumeId());
    } catch (Exception ex1) {
      throw new EucalyptusCloudException("Volume does not exist: " + request.getVolumeId());
    }
    if (!RestrictedTypes.filterPrivileged().apply(vol)) {
      throw new EucalyptusCloudException(
          "Not authorized to detach volume "
              + request.getVolumeId()
              + " by "
              + ctx.getUser().getName());
    }

    VmInstance vm = null;
    AttachedVolume volume = null;
    try {
      VmVolumeAttachment vmVolAttach = VmInstances.lookupVolumeAttachment(request.getVolumeId());
      volume = VmVolumeAttachment.asAttachedVolume(vmVolAttach.getVmInstance()).apply(vmVolAttach);
      vm = vmVolAttach.getVmInstance();
    } catch (NoSuchElementException ex) {
      /** no such attachment * */
    }
    if (volume == null) {
      throw new EucalyptusCloudException("Volume is not attached: " + request.getVolumeId());
    }
    if (!RestrictedTypes.filterPrivileged().apply(vm)) {
      throw new EucalyptusCloudException(
          "Not authorized to detach volume from instance "
              + request.getInstanceId()
              + " by "
              + ctx.getUser().getName());
    }
    if (!vm.getInstanceId().equals(request.getInstanceId())
        && request.getInstanceId() != null
        && !request.getInstanceId().equals("")) {
      throw new EucalyptusCloudException(
          "Volume is not attached to instance: " + request.getInstanceId());
    }
    if (request.getDevice() != null
        && !request.getDevice().equals("")
        && !volume.getDevice().equals(request.getDevice())) {
      throw new EucalyptusCloudException(
          "Volume is not attached to device: " + request.getDevice());
    }

    Cluster cluster = null;
    ServiceConfiguration ccConfig = null;
    try {
      ccConfig = Topology.lookup(ClusterController.class, vm.lookupPartition());
      cluster = Clusters.lookup(ccConfig);
    } catch (NoSuchElementException e) {
      LOG.debug(e, e);
      throw new EucalyptusCloudException(
          "Cluster does not exist in partition: " + vm.getPartition());
    }
    ServiceConfiguration scVm;
    try {
      scVm = Topology.lookup(Storage.class, vm.lookupPartition());
    } catch (Exception ex) {
      LOG.error(ex, ex);
      throw new EucalyptusCloudException(
          "Failed to lookup SC for partition: " + vm.getPartition(), ex);
    }
    request.setVolumeId(volume.getVolumeId());
    request.setRemoteDevice(volume.getRemoteDevice());
    request.setDevice(volume.getDevice().replaceAll("unknown,requested:", ""));
    request.setInstanceId(vm.getInstanceId());
    VolumeDetachCallback ncDetach = new VolumeDetachCallback(request);
    try {
      AsyncRequests.sendSync(scVm, new DetachStorageVolumeType(volume.getVolumeId()));
    } catch (Exception e) {
      LOG.debug(e);
      Logs.extreme().debug(e, e);
      // GRZE: attach is idempotent, failure here is ok.      throw new EucalyptusCloudException(
      // e.getMessage( ) );
    }
    AsyncRequests.newRequest(ncDetach).dispatch(cluster.getConfiguration());
    EventRecord.here(VolumeManager.class, EventClass.VOLUME, EventType.VOLUME_DETACH)
        .withDetails(vm.getOwner().toString(), volume.getVolumeId(), "instance", vm.getInstanceId())
        .withDetails("cluster", ccConfig.getFullName().toString())
        .info();
    volume.setStatus("detaching");
    reply.setDetachedVolume(volume);
    return reply;
  }
예제 #12
0
  public AttachVolumeResponseType AttachVolume(AttachVolumeType request)
      throws EucalyptusCloudException {
    AttachVolumeResponseType reply = (AttachVolumeResponseType) request.getReply();
    final String deviceName = request.getDevice();
    final String volumeId = request.getVolumeId();
    final Context ctx = Contexts.lookup();

    if (request.getDevice() == null
        || request.getDevice().endsWith("sda")
        || request.getDevice().endsWith("sdb")) {
      throw new EucalyptusCloudException("Invalid device name specified: " + request.getDevice());
    }
    VmInstance vm = null;
    try {
      vm = RestrictedTypes.doPrivileged(request.getInstanceId(), VmInstance.class);
    } catch (NoSuchElementException ex) {
      LOG.debug(ex, ex);
      throw new EucalyptusCloudException("Instance does not exist: " + request.getInstanceId(), ex);
    } catch (Exception ex) {
      LOG.debug(ex, ex);
      throw new EucalyptusCloudException(ex.getMessage(), ex);
    }
    AccountFullName ownerFullName = ctx.getUserFullName().asAccountFullName();
    Volume volume = Volumes.lookup(ownerFullName, volumeId);
    if (!RestrictedTypes.filterPrivileged().apply(volume)) {
      throw new EucalyptusCloudException(
          "Not authorized to attach volume "
              + request.getVolumeId()
              + " by "
              + ctx.getUser().getName());
    }
    try {
      vm.lookupVolumeAttachmentByDevice(deviceName);
      throw new EucalyptusCloudException(
          "Already have a device attached to: " + request.getDevice());
    } catch (NoSuchElementException ex1) {
      /** no attachment * */
    }
    try {
      VmInstances.lookupVolumeAttachment(volumeId);
      throw new EucalyptusCloudException("Volume already attached: " + request.getVolumeId());
    } catch (NoSuchElementException ex1) {
      /** no attachment * */
    }

    Partition volPartition = Partitions.lookupByName(volume.getPartition());
    ServiceConfiguration sc = Topology.lookup(Storage.class, volPartition);
    ServiceConfiguration scVm = Topology.lookup(Storage.class, vm.lookupPartition());
    if (!sc.equals(scVm)) {
      throw new EucalyptusCloudException(
          "Can only attach volumes in the same zone: " + request.getVolumeId());
    }
    ServiceConfiguration ccConfig = Topology.lookup(ClusterController.class, vm.lookupPartition());
    AttachStorageVolumeResponseType scAttachResponse;
    try {
      AttachStorageVolumeType req =
          new AttachStorageVolumeType(Nodes.lookupIqn(vm), volume.getDisplayName());
      scAttachResponse = AsyncRequests.sendSync(sc, req);
    } catch (Exception e) {
      LOG.debug(e, e);
      throw new EucalyptusCloudException(e.getMessage(), e);
    }
    request.setRemoteDevice(scAttachResponse.getRemoteDeviceString());

    AttachedVolume attachVol =
        new AttachedVolume(
            volume.getDisplayName(),
            vm.getInstanceId(),
            request.getDevice(),
            request.getRemoteDevice());
    vm.addTransientVolume(deviceName, scAttachResponse.getRemoteDeviceString(), volume);
    AsyncRequests.newRequest(new VolumeAttachCallback(request)).dispatch(ccConfig);

    EventRecord.here(VolumeManager.class, EventClass.VOLUME, EventType.VOLUME_ATTACH)
        .withDetails(
            volume.getOwner().toString(), volume.getDisplayName(), "instance", vm.getInstanceId())
        .withDetails("partition", vm.getPartition().toString())
        .info();
    reply.setAttachedVolume(attachVol);
    return reply;
  }
예제 #13
0
 /**
  * Update the cache of currently active network tags based on the most recent reported value.
  *
  * @param cluster
  * @param activeNetworks
  */
 private void update(ServiceConfiguration cluster, List<NetworkInfoType> activeNetworks) {
   removeStalePartitions();
   Set<Integer> activeTags =
       Sets.newHashSet(Lists.transform(activeNetworks, ActiveTags.INSTANCE));
   this.activeTagsByPartition.replaceValues(cluster.getPartition(), activeTags);
 }