Example #1
0
        private bool WriteMetadataFile(string filename, VolumeCreateRequest volume)
        {
            try
            {
                using (StreamWriter writer = File.CreateText(filename))
                {
                    JsonSerializer serializer = new JsonSerializer();
                    serializer.Serialize(writer, volume);
                }
            }
            catch (Exception e)
            {
                TraceWriter.WriteErrorWithId(Constants.TraceSource, GetTraceId("WriteMetadataFile"), String.Format("Writing metadata file, {0}, failed with exception {1} for volume {2}.", filename, e.Message, volume.Name));
                return(false);
            }

            return(true);
        }
Example #2
0
        private bool WriteMetadataFile(string filename, VolumeCreateRequest volume)
        {
            try
            {
                using (StreamWriter writer = File.CreateText(filename))
                {
                    JsonSerializer serializer = new JsonSerializer();
                    serializer.Serialize(writer, volume);
                }
            }
            catch (Exception e)
            {
                TraceWriter.WriteErrorWithId(
                    TraceType,
                    this.serviceContext.TraceId,
                    $"Writing metadata file {filename} failed with exception {e}.");
                return(false);
            }

            return(true);
        }
Example #3
0
        private bool ReadMetadataFile(string filename, out VolumeCreateRequest volume, out string mountPoint)
        {
            mountPoint = null;
            volume     = null;

            try
            {
                using (StreamReader reader = File.OpenText(filename))
                {
                    JsonSerializer serializer = new JsonSerializer();
                    volume     = (VolumeCreateRequest)serializer.Deserialize(reader, typeof(VolumeCreateRequest));
                    mountPoint = GetMountpoint(volume.Name);
                }
            }
            catch (Exception e)
            {
                TraceWriter.WriteErrorWithId(Constants.TraceSource, GetTraceId("ReadMetadataFile"), String.Format("Reading metadata file, {0}, failed with exception {1}.", filename, e.Message));
                return(false);
            }

            return(true);
        }
Example #4
0
        private bool ReadMetadataFile(string filename, out VolumeCreateRequest volume)
        {
            volume = null;

            try
            {
                using (StreamReader reader = File.OpenText(filename))
                {
                    JsonSerializer serializer = new JsonSerializer();
                    volume = (VolumeCreateRequest)serializer.Deserialize(reader, typeof(VolumeCreateRequest));
                }
            }
            catch (Exception e)
            {
                TraceWriter.WriteErrorWithId(
                    TraceType,
                    this.serviceContext.TraceId,
                    $"Reading metadata file {filename} failed with exception {e}.");
                return(false);
            }

            return(true);
        }
Example #5
0
        public Response CreateVolume(VolumeCreateRequest request)
        {
            if (this.VolumeExists(request.Name))
            {
                TraceWriter.WriteInfoWithId(
                    TraceType,
                    this.serviceContext.TraceId,
                    $"volume ${request.Name} already exists");
                return(new Response($"volume ${request.Name} already exists"));
            }

            this.rwLock.EnterWriteLock();
            try
            {
                if (knownVolumeMappings.ContainsKey(request.Name))
                {
                    return(new Response("Already exists"));
                }

                if (!request.Opts.ContainsKey(Constants.ShareNameOption))
                {
                    return(new Response("Required argument shareName not present"));
                }

                if (!request.Opts.ContainsKey(Constants.StorageAccountNameOption))
                {
                    return(new Response("Required argument storageAccountName not present"));
                }


                if (!request.Opts.ContainsKey(Constants.StorageAccountFQDNOption))
                {
                    // TODO: Require storageAccountFQDN and fail the request at some timepoint
                    TraceWriter.WriteInfoWithId(
                        TraceType,
                        this.serviceContext.TraceId,
                        $"{Constants.StorageAccountFQDNOption} not present");
                }

                string mountMetadataDirectoryPath = Path.Combine(mountMetadataPath, request.Name);
                Utilities.EnsureFolder(mountMetadataDirectoryPath);

                string volumesMetadataFilename = Path.Combine(volumesMetadataPath, request.Name);
                if (!this.WriteMetadataFile(volumesMetadataFilename, request))
                {
                    return(new Response($"Unable to persist metadata for creating volume {request.Name}"));
                }

                this.knownVolumeMappings[request.Name] = new VolumeEntry()
                {
                    VolumeOptions = request.Opts
                };

                return(new Response());
            }
            catch (Exception e)
            {
                TraceWriter.WriteErrorWithId(
                    TraceType,
                    this.serviceContext.TraceId,
                    $"Create volume {request.Name} failed with exception {e}.");

                return(new Response($"Create volume {request.Name} failed with exception {e}."));
            }
            finally
            {
                this.rwLock.ExitWriteLock();
            }
        }
Example #6
0
        // Return true if request is invalid
        private bool InvalidCreateRequest(VolumeCreateRequest request, ref string errorMessage)
        {
            if (volumeMappings.ContainsKey(request.Name))
            {
                errorMessage = "Name already exists";
                return(true);
            }

            // Check if the LUID is exist and within the length limitation
            if (!request.Opts.ContainsKey(Constants.LUID))
            {
                errorMessage = $"Required argument {Constants.LUID} not present";
                return(true);
            }
            else
            {
                // +1 because '\0' will be appended later
                if (request.Opts[Constants.LUID].Length + 1 > Constants.maxWCharSizeLUID)
                {
                    errorMessage = $"{Constants.LUID} cannot be more than {Constants.maxWCharSizeLUID} in length";
                    return(true);
                }
            }

            // Check if ServicePartitionID is exist
            if (!request.Opts.ContainsKey(Constants.ServicePartitionID))
            {
                errorMessage = $"Required argument {Constants.ServicePartitionID} not present";
                return(true);
            }
            else
            {
                if (ServiceExists(request.Opts[Constants.ServicePartitionID]) == false)
                {
                    errorMessage = $"{Constants.ServicePartitionID}:{request.Opts[Constants.ServicePartitionID]} is not registered";
                    return(true);
                }
            }

            // Check if SizeDisk is exist and valid
            if (!request.Opts.ContainsKey(Constants.SizeDisk))
            {
                errorMessage = $"Required argument {Constants.SizeDisk} not present";
                return(true);
            }
            else
            {
                string size     = "";
                string sizeType = "";

                if (!ParseSizeDisk(request.Opts[Constants.SizeDisk], ref size, ref sizeType))
                {
                    errorMessage = $"Invalid {Constants.SizeDisk}:{request.Opts[Constants.SizeDisk]}";
                    return(true);
                }
            }

            // Check if FileSystem is exist and valid
            if (!request.Opts.ContainsKey(Constants.FileSystem))
            {
                errorMessage = $"Required argument {Constants.FileSystem} not present";
                return(true);
            }
            else
            {
                string fileSystem = request.Opts[Constants.FileSystem];

#if DotNetCoreClrLinux
                // For Linux we convert NTFS to EXT4, the correct fix will be in manifest generator.
                if (fileSystem != "NTFS" && fileSystem != "EXT4")
#else
                // Just support NTFS at this moment
                if (fileSystem != "NTFS")
#endif
                {
                    errorMessage = $"Invalid {Constants.FileSystem}:{request.Opts[Constants.FileSystem]}";
                    return(true);
                }
            }

            return(false);
        }
Example #7
0
        public Response CreateVolume(VolumeCreateRequest request, string traceId)
        {
            if (this.VolumeExists(request.Name))
            {
                string errorMesg = String.Format("Volume ${0} already exists", request.Name);
                TraceWriter.WriteErrorWithId(Constants.TraceSource, traceId, errorMesg);
                return(new Response(errorMesg));
            }

            this.volumeRWLock.EnterWriteLock();
            try
            {
                // Use volume name as LUID for now, the length limitation will be checked at InvalidCreateRequest
                // TODO: Create by using System.Guid.NewGuid().ToString() and save to globle reliable map to handle the failover case from Node1 to Node2
                request.Opts[Constants.LUID] = request.Name;

                string errorMessage = "";

                if (InvalidCreateRequest(request, ref errorMessage))
                {
                    TraceWriter.WriteErrorWithId(Constants.TraceSource, traceId, errorMessage);
                    return(new Response(errorMessage));
                }

                string metadataFilename = Path.Combine(this.serviceContext.CodePackageActivationContext.WorkDirectory, volumesMetadata, request.Name);
                if (!this.WriteMetadataFile(metadataFilename, request))
                {
                    errorMessage = String.Format("Unable to persist metadata for volume {0}", request.Name);
                    TraceWriter.WriteErrorWithId(Constants.TraceSource, traceId, errorMessage);
                    return(new Response(errorMessage));
                }

                this.volumeMappings[request.Name] = new VolumeEntry()
                {
                    VolumeOptions      = request.Opts,
                    ServicePartitionID = request.Opts[Constants.ServicePartitionID],
                    LUID     = request.Opts[Constants.LUID],
                    SizeDisk = request.Opts[Constants.SizeDisk],
#if DotNetCoreClrLinux
                    // This need to be fixed in application manifest generator.
                    // To pass EXT4 in case of Linux.
                    FileSystem = "EXT4",
#else
                    FileSystem = request.Opts[Constants.FileSystem],
#endif
                    Mountpoint = GetMountpoint(request.Name)
                };

                return(new Response());
            }
            catch (Exception ex)
            {
                string errorMessage = String.Format("Volume {0} could not be created due to an exception: {1}", request.Name, ex.Message);
                TraceWriter.WriteErrorWithId(Constants.TraceSource, traceId, errorMessage);
                return(new Response(errorMessage));
            }
            finally
            {
                this.volumeRWLock.ExitWriteLock();
            }
        }