Skip to content

Commit

Permalink
Merge pull request #1216 from anuchandy/master
Browse files Browse the repository at this point in the history
Virtual machine - specialized VHD and generalized image
  • Loading branch information
Martin Sawicki authored Oct 20, 2016
2 parents b5a7bf5 + 65acd9b commit 8e09054
Show file tree
Hide file tree
Showing 11 changed files with 361 additions and 49 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,12 @@ public enum PowerState {
/**
* Enum value PowerState/starting.
*/
STARTING("PowerState/starting");
STARTING("PowerState/starting"),

/**
* Enum value PowerState/stopped.
*/
STOPPED("PowerState/stopped");

private String value;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -80,10 +80,11 @@ public interface VirtualMachine extends
* string that can be used to create similar VMs.
*
* @param containerName destination container name to store the captured Vhd
* @param vhdPrefix the prefix for the vhd holding captured image
* @param overwriteVhd whether to overwrites destination vhd if it exists
* @return the template as json string
*/
String capture(String containerName, boolean overwriteVhd);
String capture(String containerName, String vhdPrefix, boolean overwriteVhd);

/**
* Refreshes the virtual machine instance view to sync with Azure.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -166,14 +166,14 @@ interface WithAutoUpgradeMinorVersion<ParentT> {
*
* @return the next stage of the definition
*/
WithAttach<ParentT> withAutoUpgradeMinorVersionEnabled();
WithAttach<ParentT> withMinorVersionAutoUpgrade();

/**
* disables auto upgrade of the extension.
*
* @return the next stage of the definition
*/
WithAttach<ParentT> withAutoUpgradeMinorVersionDisabled();
WithAttach<ParentT> withoutMinorVersionAutoUpgrade();
}

/**
Expand Down Expand Up @@ -357,14 +357,14 @@ interface WithAutoUpgradeMinorVersion<ParentT> {
*
* @return the next stage of the definition
*/
WithAttach<ParentT> withAutoUpgradeMinorVersionEnabled();
WithAttach<ParentT> withMinorVersionAutoUpgrade();

/**
* disables auto upgrade of the extension.
*
* @return the next stage of the definition
*/
WithAttach<ParentT> withAutoUpgradeMinorVersionDisabled();
WithAttach<ParentT> withoutMinorVersionAutoUpgrade();
}

/**
Expand Down Expand Up @@ -458,14 +458,14 @@ interface WithAutoUpgradeMinorVersion {
*
* @return the next stage of the update
*/
Update withAutoUpgradeMinorVersionEnabled();
Update withMinorVersionAutoUpgrade();

/**
* enables auto upgrade of the extension.
*
* @return the next stage of the update
*/
Update withAutoUpgradeMinorVersionDisabled();
Update withoutMinorVersionAutoUpgrade();
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -84,8 +84,9 @@ public interface VirtualMachines extends
* @param groupName the resource group name
* @param name the virtual machine name
* @param containerName destination container name to store the captured VHD
* @param vhdPrefix the prefix for the vhd holding captured image
* @param overwriteVhd whether to overwrites destination VHD if it exists
* @return the template as JSON string
*/
String capture(String groupName, String name, String containerName, boolean overwriteVhd);
String capture(String groupName, String name, String containerName, String vhdPrefix, boolean overwriteVhd);
}
Original file line number Diff line number Diff line change
Expand Up @@ -109,13 +109,13 @@ public String provisioningState() {
}

@Override
public VirtualMachineExtensionImpl withAutoUpgradeMinorVersionEnabled() {
public VirtualMachineExtensionImpl withMinorVersionAutoUpgrade() {
this.inner().withAutoUpgradeMinorVersion(true);
return this;
}

@Override
public VirtualMachineExtensionImpl withAutoUpgradeMinorVersionDisabled() {
public VirtualMachineExtensionImpl withoutMinorVersionAutoUpgrade() {
this.inner().withAutoUpgradeMinorVersion(false);
return this;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,8 @@
import rx.Observable;
import rx.exceptions.Exceptions;
import rx.functions.Func1;

import java.net.MalformedURLException;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
Expand Down Expand Up @@ -196,10 +197,11 @@ public Page<VirtualMachineSizeInner> nextPage(String nextPageLink) {
}

@Override
public String capture(String containerName, boolean overwriteVhd) {
public String capture(String containerName, String vhdPrefix, boolean overwriteVhd) {
VirtualMachineCaptureParametersInner parameters = new VirtualMachineCaptureParametersInner();
parameters.withDestinationContainerName(containerName);
parameters.withOverwriteVhds(overwriteVhd);
parameters.withVhdPrefix(vhdPrefix);
VirtualMachineCaptureResultInner captureResult = this.client.capture(this.resourceGroupName(), this.name(), parameters);
ObjectMapper mapper = new ObjectMapper();
//Object to JSON string
Expand Down Expand Up @@ -507,9 +509,29 @@ public VirtualMachineImpl withOsDiskCaching(CachingTypes cachingType) {

@Override
public VirtualMachineImpl withOsDiskVhdLocation(String containerName, String vhdName) {
VirtualHardDisk osVhd = new VirtualHardDisk();
osVhd.withUri(temporaryBlobUrl(containerName, vhdName));
this.inner().storageProfile().osDisk().withVhd(osVhd);
StorageProfile storageProfile = this.inner().storageProfile();
OSDisk osDisk = storageProfile.osDisk();
if (this.isOSDiskFromImage(osDisk)) {
VirtualHardDisk osVhd = new VirtualHardDisk();
if (this.isOSDiskFromPlatformImage(storageProfile)) {
// OS Disk from 'Platform image' requires explicit storage account to be specified.
osVhd.withUri(temporaryBlobUrl(containerName, vhdName));
} else if (this.isOSDiskFromCustomImage(osDisk)) {
// 'Captured image' and 'Bring your own feature image' has a restriction that the
// OS disk based on these images should reside in the same storage account as the
// image.
try {
URL sourceCustomImageUrl = new URL(osDisk.image().uri());
URL destinationVhdUrl = new URL(sourceCustomImageUrl.getProtocol(),
sourceCustomImageUrl.getHost(),
"/" + containerName + "/" + vhdName);
osVhd.withUri(destinationVhdUrl.toString());
} catch (MalformedURLException ex) {
throw new RuntimeException(ex);
}
}
this.inner().storageProfile().osDisk().withVhd(osVhd);
}
return this;
}

Expand Down Expand Up @@ -930,8 +952,10 @@ private void setOSDiskAndOSProfileDefaults() {
OSDisk osDisk = this.inner().storageProfile().osDisk();
if (isOSDiskFromImage(osDisk)) {
if (osDisk.vhd() == null) {
// Sets the OS disk VHD for "UserImage" and "VM(Platform)Image"
withOsDiskVhdLocation("vhds", this.vmName + "-os-disk-" + UUID.randomUUID().toString() + ".vhd");
// Sets the OS disk container and VHD for "CustomImage (Captured BringYourOwn)" or "PlatformImage"
String osDiskVhdContainerName = "vhds";
String osDiskVhdName = this.vmName + "-os-disk-" + UUID.randomUUID().toString() + ".vhd";
withOsDiskVhdLocation(osDiskVhdContainerName, osDiskVhdName);
}
OSProfile osProfile = this.inner().osProfile();
if (osDisk.osType() == OperatingSystemTypes.LINUX || this.isMarketplaceLinuxImage) {
Expand All @@ -941,6 +965,21 @@ private void setOSDiskAndOSProfileDefaults() {
}
this.inner().osProfile().linuxConfiguration().withDisablePasswordAuthentication(osProfile.adminPassword() == null);
}

if (this.inner().osProfile().computerName() == null) {
// VM name cannot contain only numeric values and cannot exceed 15 chars
if (vmName.matches("[0-9]+")) {
this.inner().osProfile().withComputerName(ResourceNamer.randomResourceName("vm", 15));
} else if (vmName.length() <= 15) {
this.inner().osProfile().withComputerName(vmName);
} else {
this.inner().osProfile().withComputerName(ResourceNamer.randomResourceName("vm", 15));
}
}
} else {
// Compute has a new restriction that OS Profile property need to set null
// when an VM's OS disk is ATTACH-ed to a Specialized VHD
this.inner().withOsProfile(null);
}

if (osDisk.caching() == null) {
Expand All @@ -950,17 +989,6 @@ private void setOSDiskAndOSProfileDefaults() {
if (osDisk.name() == null) {
withOsDiskName(this.vmName + "-os-disk");
}

if (this.inner().osProfile().computerName() == null) {
// VM name cannot contain only numeric values and cannot exceed 15 chars
if (vmName.matches("[0-9]+")) {
this.inner().osProfile().withComputerName(ResourceNamer.randomResourceName("vm", 15));
} else if (vmName.length() <= 15) {
this.inner().osProfile().withComputerName(vmName);
} else {
this.inner().osProfile().withComputerName(ResourceNamer.randomResourceName("vm", 15));
}
}
}

private void setHardwareProfileDefaults() {
Expand All @@ -979,7 +1007,7 @@ private Observable<StorageAccount> handleStorageSettingsAsync() {
@Override
public StorageAccount call(StorageAccount storageAccount) {
if (isInCreateMode()) {
if (isOSDiskFromImage(inner().storageProfile().osDisk())) {
if (isOSDiskFromPlatformImage(inner().storageProfile())) {
String uri = inner()
.storageProfile()
.osDisk().vhd().uri()
Expand Down Expand Up @@ -1079,7 +1107,7 @@ private boolean osDiskRequiresImplicitStorageAccountCreation() {
return false;
}

return isOSDiskFromImage(this.inner().storageProfile().osDisk());
return isOSDiskFromPlatformImage(this.inner().storageProfile());
}

private boolean dataDisksRequiresImplicitStorageAccountCreation() {
Expand Down Expand Up @@ -1117,12 +1145,44 @@ private boolean dataDisksRequiresImplicitStorageAccountCreation() {
return false;
}

/**
* Checks whether the OS disk is directly attached to a VHD.
*
* @param osDisk the osDisk value in the storage profile
* @return true if the OS disk is attached to a VHD, false otherwise
*/
private boolean isOSDiskAttached(OSDisk osDisk) {
return osDisk.createOption() == DiskCreateOptionTypes.ATTACH;
}

/**
* Checks whether the OS disk is based on an image (image from PIR or custom image [captured, bringYourOwnFeature]).
*
* @param osDisk the osDisk value in the storage profile
* @return true if the OS disk is configured to use image from PIR or custom image
*/
private boolean isOSDiskFromImage(OSDisk osDisk) {
return !isOSDiskAttached(osDisk);
return osDisk.createOption() == DiskCreateOptionTypes.FROM_IMAGE;
}

/**
* Checks whether the OS disk is based on an platform image (image in PIR).
*
* @param storageProfile the storage profile
* @return true if the OS disk is configured to be based on platform image.
*/
private boolean isOSDiskFromPlatformImage(StorageProfile storageProfile) {
return isOSDiskFromImage(storageProfile.osDisk()) && storageProfile.imageReference() != null;
}

/**
* Checks whether the OS disk is based on an custom image ('captured' or 'bring your own feature').
*
* @param osDisk the osDisk value in the storage profile
* @return true if the OS disk is configured to use custom image ('captured' or 'bring your own feature')
*/
private boolean isOSDiskFromCustomImage(OSDisk osDisk) {
return isOSDiskFromImage(osDisk) && osDisk.image() != null && osDisk.image().uri() != null;
}

private String temporaryBlobUrl(String containerName, String blobName) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -116,10 +116,12 @@ public void redeploy(String groupName, String name) {
@Override
public String capture(String groupName, String name,
String containerName,
String vhdPrefix,
boolean overwriteVhd) {
VirtualMachineCaptureParametersInner parameters = new VirtualMachineCaptureParametersInner();
parameters.withDestinationContainerName(containerName);
parameters.withOverwriteVhds(overwriteVhd);
parameters.withVhdPrefix(vhdPrefix);
VirtualMachineCaptureResultInner captureResult = this.innerCollection.capture(groupName, name, parameters);
ObjectMapper mapper = new ObjectMapper();
//Object to JSON string
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -149,7 +149,7 @@ public void canInstallUninstallCustomExtension() throws Exception {
.withPublisher("Microsoft.OSTCExtensions")
.withType("CustomScriptForLinux")
.withVersion("1.4")
.withAutoUpgradeMinorVersionEnabled()
.withMinorVersionAutoUpgrade()
.withPublicSetting("fileUris",fileUris)
.withPublicSetting("commandToExecute", installCommand)
.attach()
Expand Down
Loading

0 comments on commit 8e09054

Please sign in to comment.