public override async Task <ControllerPublishVolumeResponse> ControllerPublishVolume( ControllerPublishVolumeRequest request, ServerCallContext context) { var response = new ControllerPublishVolumeResponse(); var id = request.VolumeId; using (logger.BeginKeyValueScope("volume_id", id)) using (var _s = logger.StepInformation("{0}", nameof(ControllerPublishVolume))) { try { var ctx = new Helpers.Azure.DataProviderContext <ManagedDiskConfig>(); await contextConfig.Provide(ctx); var actx = new AzureAuthConfigProviderContext { Secrets = request.ControllerPublishSecrets }; var setupService = setupServiceFactory.Create(provider.Provide(actx), ctx.Result.SubscriptionId); var vmRid = ResourceId.FromString(request.NodeId); var diskId = ResourceId.FromString(id); var info = await setupService.AddAsync(vmRid, diskId); response.PublishInfo.Add("lun", info.Lun.ToString()); } catch (Exception ex) { logger.LogError(ex, "Exception in ControllerPublishVolume"); throw new RpcException(new Status(StatusCode.Internal, ex.Message)); } _s.Commit(); } return(response); }
public override async Task <ControllerPublishVolumeResponse> ControllerPublishVolume(ControllerPublishVolumeRequest request, ServerCallContext context) { var shared = false; if (request.Readonly) { throw new RpcException(new Status(StatusCode.InvalidArgument, string.Empty), "readonly attach no supported"); } switch (request.VolumeCapability.AccessMode.Mode) { case VolumneAccessMode.SingleNodeWriter: shared = false; break; default: throw new RpcException(new Status(StatusCode.InvalidArgument, string.Empty), "not supported volume access mode"); } switch (request.VolumeCapability.AccessTypeCase) { case VolumeCapability.AccessTypeOneofCase.Mount: //throw new RpcException(new Status(StatusCode.InvalidArgument, string.Empty), // "not supported volume access type"); //maybe SMB3 FileServer support //entry.Mount.MountFlags; //entry.Mount.FsType; break; case VolumeCapability.AccessTypeOneofCase.Block: break; //case VolumeCapability.AccessTypeOneofCase.None: default: throw new RpcException(new Status(StatusCode.InvalidArgument, string.Empty), "unknown volume access type"); } //request.VolumeId //request.VolumeContext var foundVolume = await _service.GetVolumesAsync(new HypervVolumeFilter { Name = request.VolumeId, Storage = request.VolumeContext["Storage"] }) .FirstOrDefaultAsync(context.CancellationToken); if (foundVolume is null) { throw new RpcException(new Status(StatusCode.NotFound, string.Empty), "volume not found"); } var vmId = Guid.Parse(request.NodeId); //var volumePath = request.VolumeContext["Path"]; HypervVirtualMachineVolumeInfo vmVolume; var flow = await _service.GetVolumeFlowsAsnyc(new HypervVolumeFlowFilter { VolumePath = foundVolume.Path }) .FirstOrDefaultAsync(context.CancellationToken); if (flow != null) { if (!shared && flow.VMId != vmId) { throw new RpcException(new Status(StatusCode.FailedPrecondition, string.Empty), $"volume published on node[{flow.VMId}]"); } //todo check shared volume_capability vmVolume = await _service.GetVirtualMachineVolumesAsync(flow.VMId, new HypervVirtualMachineVolumeFilter { VolumePath = flow.Path, Host = flow.Host }) .FirstAsync(context.CancellationToken); } else { var volume = await _service.GetVolumeAsync(foundVolume.Path, null, context.CancellationToken); if (shared != volume.Shared) { throw new RpcException(new Status(StatusCode.InvalidArgument, string.Empty), "volume sharing ambiguous"); } //maybe check volume.Attached=false var vm = await _service.GetVirtualMachinesAsync(new HypervVirtualMachineFilter { Id = vmId }) .FirstOrDefaultAsync(context.CancellationToken); if (vm is null) { throw new RpcException(new Status(StatusCode.NotFound, string.Empty), "node not found"); } vmVolume = await _service.AttachVolumeAsync(new HypervAttachVolumeRequest { VMId = vm.Id, VolumePath = volume.Path, Host = vm.Host }, context.CancellationToken); } //todo error: //Volume published but is incompatible, 6 ALREADY_EXISTS //Max volumes attached, 8 RESOURCE_EXHAUSTED var rsp = new ControllerPublishVolumeResponse { }; rsp.PublishContext.Add("ControllerNumber", vmVolume.ControllerNumber.ToString()); rsp.PublishContext.Add("ControllerLocation", vmVolume.ControllerLocation.ToString()); return(rsp); }