private void generateDownloadManifests(final String imageId) { // lookup all reservations that reference the newly available image id final List<VmInstance> pendingInstances = VmInstances.list( new Predicate<VmInstance>() { @Override public boolean apply(VmInstance arg0) { return imageId.equals(arg0.getBootRecord().getMachineImageId()) && VmState.PENDING.equals(arg0.getState()); } }); for (final VmInstance instance : pendingInstances) { final String reservationId = instance.getReservationId(); final String partitionName = instance.getPartition(); final Partition partition = Partitions.lookupByName(partitionName); final MachineImageInfo machineImage = LookupMachine.INSTANCE.apply(imageId); try { final String manifestLocation = DownloadManifestFactory.generateDownloadManifest( new ImageManifestFile( machineImage.getRunManifestLocation(), BundleImageManifest.INSTANCE), partition.getNodeCertificate().getPublicKey(), reservationId); LOG.debug( String.format( "Generated download manifest for instance %s", instance.getDisplayName())); } catch (final Exception ex) { LOG.error( String.format( "Failed to generate download manifest for instance %s", instance.getDisplayName()), ex); } } }
private List<Cluster> doPrivilegedLookup(String partitionName, String vmTypeName) throws NotEnoughResourcesException { if (Partition.DEFAULT_NAME.equals(partitionName)) { Iterable<Cluster> authorizedClusters = Iterables.filter( Clusters.getInstance().listValues(), RestrictedTypes.filterPrivilegedWithoutOwner()); Multimap<VmTypeAvailability, Cluster> sorted = TreeMultimap.create(); for (Cluster c : authorizedClusters) { sorted.put(c.getNodeState().getAvailability(vmTypeName), c); } if (sorted.isEmpty()) { throw new NotEnoughResourcesException( "Not enough resources: no availability zone is available in which you have permissions to run instances."); } else { return Lists.newArrayList(sorted.values()); } } else { ServiceConfiguration ccConfig = Topology.lookup(ClusterController.class, Partitions.lookupByName(partitionName)); Cluster cluster = Clusters.lookup(ccConfig); if (cluster == null) { throw new NotEnoughResourcesException("Can't find cluster " + partitionName); } if (!RestrictedTypes.filterPrivilegedWithoutOwner().apply(cluster)) { throw new NotEnoughResourcesException("Not authorized to use cluster " + partitionName); } return Lists.newArrayList(cluster); } }
public CreateVolumeResponseType CreateVolume(final CreateVolumeType request) throws EucalyptusCloudException, AuthException { Context ctx = Contexts.lookup(); Long volSize = request.getSize() != null ? Long.parseLong(request.getSize()) : null; final String snapId = request.getSnapshotId(); String partition = request.getAvailabilityZone(); if ((request.getSnapshotId() == null && request.getSize() == null)) { throw new EucalyptusCloudException("One of size or snapshotId is required as a parameter."); } if (snapId != null) { try { Transactions.find(Snapshot.named(null, snapId)); } catch (ExecutionException ex) { throw new EucalyptusCloudException( "Failed to create volume because the referenced snapshot id is invalid: " + snapId); } } final Integer newSize = new Integer(request.getSize() != null ? request.getSize() : "-1"); Exception lastEx = null; for (int i = 0; i < VOL_CREATE_RETRIES; i++) { try { final ServiceConfiguration sc = Topology.lookup(Storage.class, Partitions.lookupByName(partition)); final UserFullName owner = ctx.getUserFullName(); Function<Long, Volume> allocator = new Function<Long, Volume>() { @Override public Volume apply(Long size) { try { return Volumes.createStorageVolume( sc, owner, snapId, Ints.checkedCast(size), request); } catch (ExecutionException ex) { throw Exceptions.toUndeclared(ex); } } }; Volume newVol = RestrictedTypes.allocateMeasurableResource(newSize.longValue(), allocator); CreateVolumeResponseType reply = request.getReply(); reply.setVolume(newVol.morph(new edu.ucsb.eucalyptus.msgs.Volume())); return reply; } catch (RuntimeException ex) { LOG.error(ex, ex); if (!(ex.getCause() instanceof ExecutionException)) { throw ex; } else { lastEx = ex; } } } throw new EucalyptusCloudException( "Failed to create volume after " + VOL_CREATE_RETRIES + " because of: " + lastEx, lastEx); }
@Override public boolean apply(Allocation allocInfo) throws MetadataException { RunInstancesType request = allocInfo.getRequest(); String zoneName = request.getAvailabilityZone(); if (Clusters.getInstance().listValues().isEmpty()) { LOG.debug("enabled values: " + Joiner.on("\n").join(Clusters.getInstance().listValues())); LOG.debug("disabled values: " + Joiner.on("\n").join(Clusters.getInstance().listValues())); throw new VerificationException( "Not enough resources: no cluster controller is currently available to run instances."); } else if (Partitions.exists(zoneName)) { Partition partition = Partitions.lookupByName(zoneName); allocInfo.setPartition(partition); } else if (Partition.DEFAULT_NAME.equals(zoneName)) { Partition partition = Partition.DEFAULT; allocInfo.setPartition(partition); } else { throw new VerificationException( "Not enough resources: no cluster controller is currently available to run instances."); } return true; }
public static Volume checkVolumeReady(final Volume vol) throws EucalyptusCloudException { if (vol.isReady()) { return vol; } else { // TODO:GRZE:REMOVE temporary workaround to update the volume state. final ServiceConfiguration sc = Topology.lookup(Storage.class, Partitions.lookupByName(vol.getPartition())); final DescribeStorageVolumesType descVols = new DescribeStorageVolumesType(Lists.newArrayList(vol.getDisplayName())); try { Transactions.one( Volume.named(null, vol.getDisplayName()), new Callback<Volume>() { @Override public void fire(final Volume t) { try { final DescribeStorageVolumesResponseType volState = AsyncRequests.sendSync(sc, descVols); if (!volState.getVolumeSet().isEmpty()) { final State newVolumeState = Volumes.transformStorageState( vol.getState(), volState.getVolumeSet().get(0).getStatus()); vol.setState(newVolumeState); } } catch (final Exception ex) { LOG.error(ex); Logs.extreme().error(ex, ex); throw Exceptions.toUndeclared( "Failed to update the volume state " + vol.getDisplayName() + " not yet ready", ex); } } }); } catch (final ExecutionException ex) { throw new EucalyptusCloudException(ex.getCause()); } if (!vol.isReady()) { throw new EucalyptusCloudException("Volume " + vol.getDisplayName() + " not yet ready"); } return vol; } }
static Map<String, StorageVolume> updateVolumesInPartition(final String partition) { final Map<String, StorageVolume> idStorageVolumeMap = Maps.newHashMap(); final ServiceConfiguration scConfig = Topology.lookup(Storage.class, Partitions.lookupByName(partition)); try { final DescribeStorageVolumesResponseType volState = AsyncRequests.sendSync(scConfig, new DescribeStorageVolumesType()); for (final StorageVolume vol : volState.getVolumeSet()) { LOG.trace( "Volume states: " + vol.getVolumeId() + " " + vol.getStatus() + " " + vol.getActualDeviceName()); idStorageVolumeMap.put(vol.getVolumeId(), vol); } } catch (final Exception ex) { LOG.error(ex); Logs.extreme().error(ex, ex); } return idStorageVolumeMap; }
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; }
public Partition lookupPartition() { return Partitions.lookupByName(this.partitionName); }