Skip to content

Commit

Permalink
mgmt, virtualmachine support ephemeral os disk (Azure#27541)
Browse files Browse the repository at this point in the history
* mgmt, virtualmachine support ephemeral os disk

* nit, javadoc return

* change test vm size

* Update sdk/resourcemanager/azure-resourcemanager-compute/CHANGELOG.md

Co-authored-by: Weidong Xu <weidxu@microsoft.com>

* nit, javadoc fix

Co-authored-by: Weidong Xu <weidxu@microsoft.com>
  • Loading branch information
XiaofeiCao and weidongxu-microsoft authored Mar 10, 2022
1 parent a5fd5cb commit 29173d1
Show file tree
Hide file tree
Showing 5 changed files with 793 additions and 15 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@

- Supported disk encryption set in `Disk` and `VirtualMachine`.
- Changed to use PATCH for `GalleryImage` update.
- Supported ephemeral OS disk in `VirtualMachine`.

### Other Changes

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,13 @@
import com.azure.core.util.logging.ClientLogger;
import com.azure.core.util.serializer.SerializerAdapter;
import com.azure.core.util.serializer.SerializerEncoding;
import com.azure.resourcemanager.authorization.AuthorizationManager;
import com.azure.resourcemanager.authorization.models.BuiltInRole;
import com.azure.resourcemanager.authorization.utils.RoleAssignmentHelper;
import com.azure.resourcemanager.compute.ComputeManager;
import com.azure.resourcemanager.compute.fluent.models.ProximityPlacementGroupInner;
import com.azure.resourcemanager.compute.fluent.models.VirtualMachineInner;
import com.azure.resourcemanager.compute.fluent.models.VirtualMachineUpdateInner;
import com.azure.resourcemanager.compute.models.AdditionalCapabilities;
import com.azure.resourcemanager.compute.models.AvailabilitySet;
import com.azure.resourcemanager.compute.models.AvailabilitySetSkuTypes;
Expand All @@ -22,6 +28,9 @@
import com.azure.resourcemanager.compute.models.DataDisk;
import com.azure.resourcemanager.compute.models.DeleteOptions;
import com.azure.resourcemanager.compute.models.DiagnosticsProfile;
import com.azure.resourcemanager.compute.models.DiffDiskOptions;
import com.azure.resourcemanager.compute.models.DiffDiskPlacement;
import com.azure.resourcemanager.compute.models.DiffDiskSettings;
import com.azure.resourcemanager.compute.models.Disk;
import com.azure.resourcemanager.compute.models.DiskCreateOptionTypes;
import com.azure.resourcemanager.compute.models.DiskDeleteOptionTypes;
Expand Down Expand Up @@ -54,32 +63,26 @@
import com.azure.resourcemanager.compute.models.VirtualHardDisk;
import com.azure.resourcemanager.compute.models.VirtualMachine;
import com.azure.resourcemanager.compute.models.VirtualMachineCaptureParameters;
import com.azure.resourcemanager.compute.models.VirtualMachineCustomImage;
import com.azure.resourcemanager.compute.models.VirtualMachineDataDisk;
import com.azure.resourcemanager.compute.models.VirtualMachineDiskOptions;
import com.azure.resourcemanager.compute.models.VirtualMachineEncryption;
import com.azure.resourcemanager.compute.models.VirtualMachineEvictionPolicyTypes;
import com.azure.resourcemanager.compute.models.VirtualMachineExtension;
import com.azure.resourcemanager.compute.models.VirtualMachineIdentity;
import com.azure.resourcemanager.compute.models.VirtualMachineInstanceView;
import com.azure.resourcemanager.compute.models.VirtualMachineCustomImage;
import com.azure.resourcemanager.compute.models.VirtualMachinePriorityTypes;
import com.azure.resourcemanager.compute.models.VirtualMachineSize;
import com.azure.resourcemanager.compute.models.VirtualMachineSizeTypes;
import com.azure.resourcemanager.compute.models.VirtualMachineUnmanagedDataDisk;
import com.azure.resourcemanager.compute.models.WinRMConfiguration;
import com.azure.resourcemanager.compute.models.WinRMListener;
import com.azure.resourcemanager.compute.models.WindowsConfiguration;
import com.azure.resourcemanager.compute.fluent.models.ProximityPlacementGroupInner;
import com.azure.resourcemanager.compute.fluent.models.VirtualMachineInner;
import com.azure.resourcemanager.compute.fluent.models.VirtualMachineUpdateInner;
import com.azure.resourcemanager.authorization.models.BuiltInRole;
import com.azure.resourcemanager.authorization.AuthorizationManager;
import com.azure.resourcemanager.authorization.utils.RoleAssignmentHelper;
import com.azure.resourcemanager.msi.models.Identity;
import com.azure.resourcemanager.network.NetworkManager;
import com.azure.resourcemanager.network.models.Network;
import com.azure.resourcemanager.network.models.NetworkInterface;
import com.azure.resourcemanager.network.models.PublicIpAddress;
import com.azure.resourcemanager.network.NetworkManager;
import com.azure.resourcemanager.resources.fluentcore.arm.AvailabilityZoneId;
import com.azure.resourcemanager.resources.fluentcore.arm.ResourceId;
import com.azure.resourcemanager.resources.fluentcore.arm.ResourceUtils;
Expand All @@ -88,9 +91,10 @@
import com.azure.resourcemanager.resources.fluentcore.model.Creatable;
import com.azure.resourcemanager.resources.fluentcore.model.Indexable;
import com.azure.resourcemanager.resources.fluentcore.model.implementation.AcceptedImpl;
import com.azure.resourcemanager.resources.fluentcore.utils.PagedConverter;
import com.azure.resourcemanager.resources.fluentcore.utils.ResourceManagerUtils;
import com.azure.resourcemanager.storage.models.StorageAccount;
import com.azure.resourcemanager.storage.StorageManager;
import com.azure.resourcemanager.storage.models.StorageAccount;
import com.fasterxml.jackson.core.JsonProcessingException;
import reactor.core.Exceptions;
import reactor.core.publisher.Flux;
Expand All @@ -108,7 +112,6 @@
import java.util.Set;
import java.util.UUID;
import java.util.concurrent.Callable;
import com.azure.resourcemanager.resources.fluentcore.utils.PagedConverter;

/** The implementation for VirtualMachine and its create and update interfaces. */
class VirtualMachineImpl
Expand Down Expand Up @@ -1002,6 +1005,17 @@ public VirtualMachineImpl withOSDiskDiskEncryptionSet(String diskEncryptionSetId
return this;
}

@Override
public VirtualMachineImpl withEphemeralOSDisk() {
if (this.innerModel().storageProfile().osDisk().diffDiskSettings() == null) {
this.innerModel().storageProfile().osDisk().withDiffDiskSettings(new DiffDiskSettings());
}
this.innerModel().storageProfile().osDisk().diffDiskSettings().withOption(DiffDiskOptions.LOCAL);
// For vm with ephemeral os disk, cache should be read-only
withOSDiskCaching(CachingTypes.READ_ONLY);
return this;
}

// Virtual machine optional native data disk fluent methods
@Override
public UnmanagedDataDiskImpl defineUnmanagedDataDisk(String name) {
Expand Down Expand Up @@ -1702,6 +1716,11 @@ public String osDiskDiskEncryptionSetId() {
return this.storageProfile().osDisk().managedDisk().diskEncryptionSet().id();
}

@Override
public boolean isOSDiskEphemeral() {
return this.storageProfile().osDisk().diffDiskSettings() != null && this.storageProfile().osDisk().diffDiskSettings().placement() != null;
}

@Override
public Map<Integer, VirtualMachineUnmanagedDataDisk> unmanagedDataDisks() {
Map<Integer, VirtualMachineUnmanagedDataDisk> dataDisks = new HashMap<>();
Expand Down Expand Up @@ -2654,6 +2673,14 @@ public String resourceId() {
};
}

@Override
public VirtualMachineImpl withPlacement(DiffDiskPlacement placement) {
if (placement != null) {
this.innerModel().storageProfile().osDisk().diffDiskSettings().withPlacement(placement);
}
return this;
}

/** Class to manage Data disk collection. */
private class ManagedDataDiskCollection {
private final Map<String, DataDisk> newDisksToAttach = new HashMap<>();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,14 @@

import com.azure.core.annotation.Fluent;
import com.azure.core.http.rest.PagedIterable;
import com.azure.resourcemanager.authorization.models.BuiltInRole;
import com.azure.resourcemanager.compute.ComputeManager;
import com.azure.resourcemanager.compute.fluent.models.VirtualMachineInner;
import com.azure.resourcemanager.authorization.models.BuiltInRole;
import com.azure.resourcemanager.msi.models.Identity;
import com.azure.resourcemanager.network.models.HasNetworkInterfaces;
import com.azure.resourcemanager.network.models.Network;
import com.azure.resourcemanager.network.models.NetworkInterface;
import com.azure.resourcemanager.network.models.PublicIpAddress;
import com.azure.resourcemanager.network.models.HasNetworkInterfaces;
import com.azure.resourcemanager.resources.fluentcore.arm.AvailabilityZoneId;
import com.azure.resourcemanager.resources.fluentcore.arm.models.GroupableResource;
import com.azure.resourcemanager.resources.fluentcore.arm.models.Resource;
Expand All @@ -22,10 +22,11 @@
import com.azure.resourcemanager.resources.fluentcore.model.Refreshable;
import com.azure.resourcemanager.resources.fluentcore.model.Updatable;
import com.azure.resourcemanager.storage.models.StorageAccount;
import reactor.core.publisher.Mono;

import java.util.List;
import java.util.Map;
import java.util.Set;
import reactor.core.publisher.Mono;

/** An immutable client-side representation of an Azure virtual machine. */
@Fluent
Expand Down Expand Up @@ -284,6 +285,9 @@ Mono<RunCommandResult> runShellScriptAsync(
/** @return resource ID of the disk encryption set of the OS disk */
String osDiskDiskEncryptionSetId();

/** @return whether the os disk is ephemeral*/
boolean isOSDiskEphemeral();

/** @return the unmanaged data disks associated with this virtual machine, indexed by LUN number */
Map<Integer, VirtualMachineUnmanagedDataDisk> unmanagedDataDisks();

Expand Down Expand Up @@ -1203,6 +1207,22 @@ interface WithOSDiskSettings {
* @return the next stage of the definition
*/
WithCreate withOSDiskDiskEncryptionSet(String diskEncryptionSetId);

/**
* Specifies the OS disk to be ephemeral.
* @return the next stage of the definition
*/
WithEphemeralOSDisk withEphemeralOSDisk();
}

/** The stage of a virtual machine definition allowing to select Ephemeral OS disk placement. */
interface WithEphemeralOSDisk {
/**
* Selects where you want to place the Ephemeral OS disk.
* @param placement placement of the Ephemeral OS disk
* @return the next stage of the definition
*/
WithManagedCreate withPlacement(DiffDiskPlacement placement);
}

/** The stage of a virtual machine definition allowing to select a VM size. */
Expand Down Expand Up @@ -1853,7 +1873,8 @@ interface WithCreate
DefinitionStages.WithUserAssignedManagedServiceIdentity,
DefinitionStages.WithLicenseType,
DefinitionStages.WithAdditionalCapacities,
DefinitionStages.WithNetworkInterfaceDeleteOptions {
DefinitionStages.WithNetworkInterfaceDeleteOptions,
DefinitionStages.WithEphemeralOSDisk {

/**
* Begins creating the virtual machine resource.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,17 @@

import com.azure.core.http.HttpPipeline;
import com.azure.core.http.rest.PagedIterable;
import com.azure.core.management.Region;
import com.azure.core.management.exception.ManagementException;
import com.azure.core.management.profile.AzureProfile;
import com.azure.core.test.annotation.DoNotRecord;
import com.azure.core.util.CoreUtils;
import com.azure.core.util.polling.LongRunningOperationStatus;
import com.azure.core.util.polling.PollResponse;
import com.azure.resourcemanager.compute.models.AvailabilitySet;
import com.azure.resourcemanager.compute.models.CachingTypes;
import com.azure.resourcemanager.compute.models.DeleteOptions;
import com.azure.resourcemanager.compute.models.DiffDiskPlacement;
import com.azure.resourcemanager.compute.models.Disk;
import com.azure.resourcemanager.compute.models.DiskState;
import com.azure.resourcemanager.compute.models.InstanceViewStatus;
Expand All @@ -35,7 +38,6 @@
import com.azure.resourcemanager.network.models.PublicIpAddress;
import com.azure.resourcemanager.network.models.SecurityRuleProtocol;
import com.azure.resourcemanager.network.models.Subnet;
import com.azure.core.management.Region;
import com.azure.resourcemanager.resources.fluentcore.arm.models.Resource;
import com.azure.resourcemanager.resources.fluentcore.model.Accepted;
import com.azure.resourcemanager.resources.fluentcore.model.Creatable;
Expand Down Expand Up @@ -1258,6 +1260,51 @@ public void canOperateVirtualMachine() {
Assertions.assertEquals(PowerState.DEALLOCATED, vm.powerState());
}

@Test
public void canCreateVirtualMachineWithEphemeralOSDisk() {
VirtualMachine vm = computeManager.virtualMachines()
.define(vmName)
.withRegion(Region.US_WEST3)
.withNewResourceGroup(rgName)
.withNewPrimaryNetwork("10.0.0.0/28")
.withPrimaryPrivateIPAddressDynamic()
.withoutPrimaryPublicIPAddress()
.withPopularLinuxImage(KnownLinuxVirtualMachineImage.UBUNTU_SERVER_18_04_LTS)
.withRootUsername("Foo12")
.withSsh(sshPublicKey())
.withSize(VirtualMachineSizeTypes.STANDARD_DS1_V2)
.withEphemeralOSDisk()
.withPlacement(DiffDiskPlacement.CACHE_DISK)
.withNewDataDisk(1, 1, CachingTypes.READ_WRITE)
.withPrimaryNetworkInterfaceDeleteOptions(DeleteOptions.DELETE)
.create();

Assertions.assertNull(vm.osDiskDiskEncryptionSetId());
Assertions.assertTrue(vm.osDiskSize() > 0);
Assertions.assertEquals(vm.osDiskDeleteOptions(), DeleteOptions.DELETE);
Assertions.assertEquals(vm.osDiskCachingType(), CachingTypes.READ_ONLY);
Assertions.assertFalse(CoreUtils.isNullOrEmpty(vm.dataDisks()));
Assertions.assertTrue(vm.isOSDiskEphemeral());
Assertions.assertNotNull(vm.osDiskId());

String osDiskId = vm.osDiskId();

vm.update()
.withoutDataDisk(1)
.withNewDataDisk(1, 2, CachingTypes.NONE)
.withNewDataDisk(1)
.apply();
Assertions.assertEquals(vm.dataDisks().size(), 2);

vm.powerOff();
vm.start();
vm.refresh();
Assertions.assertEquals(osDiskId, vm.osDiskId());

// deallocate not supported on vm with ephemeral os disk
Assertions.assertThrows(Exception.class, vm::deallocate);
}

private CreatablesInfo prepareCreatableVirtualMachines(
Region region, String vmNamePrefix, String networkNamePrefix, String publicIpNamePrefix, int vmCount) {

Expand Down
Loading

0 comments on commit 29173d1

Please sign in to comment.