private void removeTags(final String imageId) throws Exception { final ImageInfo image = Images.lookupImage(imageId); final String imageOwnerId = image.getOwnerUserId(); DeleteTagsTask task = new DeleteTagsTask( imageOwnerId, Lists.newArrayList(image.getDisplayName()), Lists.newArrayList(TAG_KEY_STATE, TAG_KEY_MESSAGE)); CheckedListenableFuture<Boolean> result = task.dispatch(); if (result.get()) {; } final List<VmInstance> instances = this.lookupInstances(imageId); for (final VmInstance instance : instances) { final String instanceId = instance.getInstanceId(); final String instanceOwnerId = instance.getOwnerUserId(); try { task = new DeleteTagsTask( instanceOwnerId, Lists.newArrayList(instanceId), Lists.newArrayList(TAG_KEY_STATE, TAG_KEY_MESSAGE)); result = task.dispatch(); if (result.get()) {; } } catch (final Exception ex) {; } } }
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 static void clearVmState(final ClusterAddressInfo addrInfo) { try { final VmInstance vm = VmInstances.lookupByPublicIp(addrInfo.getAddress()); vm.updatePublicAddress(vm.getPrivateAddress()); } catch (final NoSuchElementException e) { } }
private static void markAsAllocated( final Cluster cluster, final ClusterAddressInfo addrInfo, final Address address) { try { if (!address.isPending()) { for (final VmInstance vm : VmInstances.list(VmState.RUNNING)) { if (addrInfo.getInstanceIp().equals(vm.getPrivateAddress()) && VmState.RUNNING.equals(vm.getState())) { LOG.warn( "Out of band address state change: " + LogUtil.dumpObject(addrInfo) + " address=" + address + " vm=" + vm); // if ( !address.isAllocated( ) ) { // address.pendingAssignment( ).assign( vm ).clearPending( ); // } else { // address.assign( vm ).clearPending( ); // } // clearOrphan( addrInfo ); return; } } } } catch (final IllegalStateException e) { LOG.error(e); } }
@Override public void fireException(Throwable e) { LOG.debug(e); Logs.extreme().error(e, e); LOG.debug( "Trying to remove invalid volume attachment " + this.getRequest().getVolumeId() + " from instance " + this.getRequest().getInstanceId()); try { VmInstance vm = VmInstances.lookup(this.getRequest().getInstanceId()); Partition partition = vm.lookupPartition(); ServiceConfiguration sc = Topology.lookup(Storage.class, partition); /** clean up SC session state * */ try { LOG.debug( "Sending detach after async failure in attach volume: " + this.getRequest().getVolumeId() + " sc=" + sc); AsyncRequests.sendSync(sc, new DetachStorageVolumeType(this.getRequest().getVolumeId())); } catch (Exception ex) { LOG.error(ex); Logs.extreme().error(ex, ex); } /** clean up internal attachment state * */ final Function<String, VmInstance> removeVolAttachment = new Function<String, VmInstance>() { public VmInstance apply(final String input) { VmInstance vm = VmInstances.lookup(input); vm.removeVolumeAttachment(VolumeAttachCallback.this.getRequest().getVolumeId()); return vm; } }; Entities.asTransaction(VmInstance.class, removeVolAttachment) .apply(this.getRequest().getInstanceId()); LOG.debug( "Removed failed attachment: " + this.getRequest().getVolumeId() + " -> " + vm.getInstanceId()); } catch (Exception e1) { LOG.error(e1); Logs.extreme().error(e1, e1); } }
private static VmInstance maybeFindVm( final String instanceId, final String publicIp, final String privateIp) { VmInstance vm = null; if (instanceId != null) { try { vm = VmInstances.lookup(instanceId); } catch (NoSuchElementException ex) { Logs.extreme().error(ex); } } if (vm == null && privateIp != null) { try { vm = VmInstances.lookupByPrivateIp(privateIp); } catch (NoSuchElementException ex) { Logs.extreme().error(ex); } } if (vm == null && publicIp != null) { try { vm = VmInstances.lookupByPublicIp(publicIp); } catch (NoSuchElementException ex) { Logs.extreme().error(ex); } } if (vm != null && VmState.RUNNING.equals(vm.getState()) && publicIp.equals(vm.getPublicAddress())) { Logs.extreme() .debug( "Candidate vm which claims this address: " + vm.getInstanceId() + " " + vm.getState() + " " + publicIp); if (publicIp.equals(vm.getPublicAddress())) { Logs.extreme() .debug( "Found vm which claims this address: " + vm.getInstanceId() + " " + vm.getState() + " " + publicIp); } return vm; } else { return null; } }
private void clearState() { EventRecord.here( AssignAddressCallback.class, EventType.ADDRESS_ASSIGNING, Transition.assigning.toString(), "FAILED", this.address.toString()) .debug(); if (this.address.isPending()) { try { this.address.clearPending(); } catch (Exception ex) { } } if (this.address.isSystemOwned()) { Addresses.release(this.address); } else if (this.address.isAssigned() && this.vm != null) { AddressingDispatcher.dispatch( AsyncRequests.newRequest(this.address.unassign().getCallback()), vm.getPartition()); } else if (this.address.isAssigned() && this.vm == null) { this.address.unassign().clearPending(); } }
private void tagResources(final String imageId, final String state, String statusMessage) throws Exception { final ImageInfo image = Images.lookupImage(imageId); final String imageOwnerId = image.getOwnerUserId(); final List<VmInstance> instances = this.lookupInstances(imageId); if (tagState.containsKey(imageId) && state.equals(tagState.get(imageId))) {; } else { resetTag(imageOwnerId, imageId, TAG_KEY_STATE, state); tagState.put(imageId, state); } for (final VmInstance instance : instances) { final String instanceId = instance.getInstanceId(); final String instanceOwnerId = instance.getOwnerUserId(); if (tagState.containsKey(instanceId) && state.equals(tagState.get(instanceId))) {; } else { resetTag(instanceOwnerId, instanceId, TAG_KEY_STATE, state); tagState.put(instanceId, state); } } if (statusMessage == null) statusMessage = ""; if (tagMessage.containsKey(imageId) && statusMessage.equals(tagMessage.get(imageId))) {; } else { resetTag(imageOwnerId, imageId, TAG_KEY_MESSAGE, statusMessage); tagMessage.put(imageId, statusMessage); } for (final VmInstance instance : instances) { final String instanceId = instance.getInstanceId(); final String instanceOwnerId = instance.getOwnerUserId(); if (tagMessage.containsKey(instanceId) && statusMessage.equals(tagMessage.get(instanceId))) {; } else { resetTag(instanceOwnerId, instanceId, TAG_KEY_MESSAGE, statusMessage); tagMessage.put(instanceId, statusMessage); } } }
/* (non-Javadoc) * @see com.eucalyptus.dns.Zone#findRecords(org.xbill.DNS.Name, int) */ @Override public SetResponse findRecords(Name name, int type) { if (type == Type.AAAA) return (SetResponse.ofType(SetResponse.SUCCESSFUL)); if (StackConfiguration.USE_INSTANCE_DNS && name.toString().matches("euca-.+{3}-.+{3}-.+{3}-.+{3}\\..*")) { try { String[] tryIp = name.toString() .replaceAll("euca-", "") .replaceAll(VmInstances.INSTANCE_SUBDOMAIN + ".*", "") .split("-"); if (tryIp.length < 4) return super.findRecords(name, type); String ipCandidate = new StringBuffer() .append(tryIp[0]) .append(".") .append(tryIp[1]) .append(".") .append(tryIp[2]) .append(".") .append(tryIp[3]) .toString(); try { VmInstances.lookupByPublicIp(ipCandidate); } catch (Exception e) { try { VmInstances.lookupByPrivateIp(ipCandidate); } catch (Exception e1) { return super.findRecords(name, type); } } InetAddress ip = InetAddress.getByName(ipCandidate); SetResponse resp = new SetResponse(SetResponse.SUCCESSFUL); resp.addRRset(new RRset(new ARecord(name, 1, ttl, ip))); return resp; } catch (Exception e) { return super.findRecords(name, type); } } else if (StackConfiguration.USE_INSTANCE_DNS && name.toString().endsWith(".in-addr.arpa.")) { int index = name.toString().indexOf(".in-addr.arpa."); Name target; if (index > 0) { String ipString = name.toString().substring(0, index); String[] parts = ipString.split("\\."); String ipCandidate; if (parts.length == 4) { ipCandidate = new StringBuffer() .append(parts[3]) .append(".") .append(parts[2]) .append(".") .append(parts[1]) .append(".") .append(parts[0]) .toString(); } else { return super.findRecords(name, type); } try { VmInstance instance = VmInstances.lookupByPublicIp(ipCandidate); target = new Name(instance.getPublicDnsName() + "."); } catch (Exception e) { try { VmInstance instance = VmInstances.lookupByPrivateIp(ipCandidate); target = new Name(instance.getPrivateDnsName() + "."); } catch (Exception e1) { return super.findRecords(name, type); } } SetResponse resp = new SetResponse(SetResponse.SUCCESSFUL); resp.addRRset(new RRset(new PTRRecord(name, DClass.IN, ttl, target))); return resp; } else { return super.findRecords(name, type); } } else { return super.findRecords(name, type); } }
protected static Address lookupOrCreate( final Cluster cluster, final ClusterAddressInfo addrInfo) { Address addr = null; VmInstance vm = null; try { addr = Addresses.getInstance().lookupDisabled(addrInfo.getAddress()); LOG.trace("Found address in the inactive set cache: " + addr); } catch (final NoSuchElementException e1) { try { addr = Addresses.getInstance().lookup(addrInfo.getAddress()); LOG.trace("Found address in the active set cache: " + addr); } catch (final NoSuchElementException e) { } } if (addrInfo.hasMapping()) { vm = Helper.maybeFindVm( addr != null ? addr.getInstanceId() : null, addrInfo.getAddress(), addrInfo.getInstanceIp()); if ((addr != null) && (vm != null)) { Helper.ensureAllocated(addr, vm); clearOrphan(addrInfo); } else if (addr != null && !addr.isPending() && vm != null && VmStateSet.DONE.apply(vm)) { handleOrphan(cluster, addrInfo); } else if ((addr != null && addr.isAssigned() && !addr.isPending()) && (vm == null)) { handleOrphan(cluster, addrInfo); } else if ((addr == null) && (vm != null)) { addr = new Address( Principals.systemFullName(), addrInfo.getAddress(), vm.getInstanceUuid(), vm.getInstanceId(), vm.getPrivateAddress()); clearOrphan(addrInfo); } else if ((addr == null) && (vm == null)) { addr = new Address(addrInfo.getAddress(), cluster.getPartition()); handleOrphan(cluster, addrInfo); } } else { if ((addr != null) && addr.isAssigned() && !addr.isPending()) { handleOrphan(cluster, addrInfo); } else if ((addr != null) && !addr.isAssigned() && !addr.isPending() && addr.isSystemOwned()) { try { addr.release(); } catch (final Exception ex) { LOG.error(ex); } } else if ((addr != null) && Address.Transition.system.equals(addr.getTransition())) { handleOrphan(cluster, addrInfo); } else if (addr == null) { addr = new Address(addrInfo.getAddress(), cluster.getPartition()); Helper.clearVmState(addrInfo); } } return addr; }
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; }
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; }