Skip to content

Commit

Permalink
Failing to set name of Volume we booted from is no longer fatal
Browse files Browse the repository at this point in the history
If we boot from a VolumeSnaphot, the Instance has a Volume attached to
it, but OpenStack doesn't automatically set its name and it sometimes
forgets to remove it with the Instance, so the plugin sets the name to
make it easier for humans to figure out who owns what Volume.
...however this doesn't always work with all versions of OpenStack, and
it's better that we live without this naming than fail to work at all.
  • Loading branch information
pjdarton committed Nov 28, 2019
1 parent 658def7 commit 2a33b75
Show file tree
Hide file tree
Showing 2 changed files with 37 additions and 1 deletion.
Original file line number Diff line number Diff line change
Expand Up @@ -430,7 +430,17 @@ public void afterProvisioning(@Nonnull Server server, @Nonnull Openstack opensta
+ name + (instanceVolumeSnapshotId == null ? "" : " (" + instanceVolumeSnapshotId + ")") + ".";
for (final String volumeId : volumeIds) {
final String newVolumeName = instanceName + '[' + (i++) + ']';
openstack.setVolumeNameAndDescription(volumeId, newVolumeName, newVolumeDescription);
try {
openstack.setVolumeNameAndDescription(volumeId, newVolumeName, newVolumeDescription);
} catch (Openstack.ActionFailed ex) {
/*
* Some versions of OpenStack work better than others. Not all will accept this
* operation. However, a failure to set the name and description is purely
* cosmetic and does not affect our ability to use the instance, so we log the
* problem and carry on.
*/
LOGGER.warning("Unable to set volume " + volumeId + " name and description: " + ex.getMessage());
}
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -177,6 +177,32 @@ public void bootFromVolumeSnapshot() {
final JCloudsSlaveTemplate instance = j.dummySlaveTemplate(opts, "a");
final JCloudsCloud cloud = j.configureSlaveProvisioningWithFloatingIP(j.dummyCloud(instance));
final Openstack mockOs = cloud.getOpenstack();
testBootFromVolumeSnapshot(volumeSnapshotName, volumeSnapshotId, instance, mockOs);
}

@Test
public void bootFromVolumeSnapshotStillPossibleEvenIfCantSetVolumeNameAndDescription() {
/*
* openstack4j can throw fail with the error:
* "ActionResponse{success=false, fault=Invalid input for field/attribute volume.
* Value: {u'description': u'...', u'display_name': u'...', u'name': u'...',
* u'os-vol-mig-status-attr:migstat': u'none', u'display_description': u'...'}.
* Additional properties are not allowed (u'os-vol-mig-status-attr:migstat' was
* unexpected), code=400}".
* We need our code to survive this and not treat it as a fatal error.
*/
final String volumeSnapshotName = "MyOtherVolumeSnapshot";
final String volumeSnapshotId = "vs-345-id";
final SlaveOptions opts = dummySlaveOptions().getBuilder().bootSource(new VolumeSnapshot(volumeSnapshotName)).build();
final JCloudsSlaveTemplate instance = j.dummySlaveTemplate(opts, "b");
final JCloudsCloud cloud = j.configureSlaveProvisioningWithFloatingIP(j.dummyCloud(instance));
final Openstack mockOs = cloud.getOpenstack();
doThrow(new Openstack.ActionFailed("Mock OpenStack error setting volume name and description")).when(mockOs).setVolumeNameAndDescription(anyString(), anyString(), anyString());
testBootFromVolumeSnapshot(volumeSnapshotName, volumeSnapshotId, instance, mockOs);
}

private void testBootFromVolumeSnapshot(final String volumeSnapshotName, final String volumeSnapshotId,
final JCloudsSlaveTemplate instance, final Openstack mockOs) {
when(mockOs.getVolumeSnapshotIdsFor(volumeSnapshotName)).thenReturn(Collections.singletonList(volumeSnapshotId));

final ArgumentCaptor<ServerCreateBuilder> scbCaptor = ArgumentCaptor.forClass(ServerCreateBuilder.class);
Expand Down

0 comments on commit 2a33b75

Please sign in to comment.