コード例 #1
0
        private async Task ApplyContext(HostAssignmentContext assignmentContext)
        {
            _logger.LogInformation($"Applying {assignmentContext.Environment.Count} app setting(s)");
            assignmentContext.ApplyAppSettings(_environment);

            // We need to get the non-PlaceholderMode script Path so we can unzip to the correct location.
            // This asks the factory to skip the PlaceholderMode check when configuring options.
            var options = _optionsFactory.Create(ScriptApplicationHostOptionsSetup.SkipPlaceholder);
            RunFromPackageContext pkgContext = assignmentContext.GetRunFromPkgContext();

            if ((pkgContext.IsScmRunFromPackage() && await pkgContext.BlobExistsAsync(_logger)) ||
                (!pkgContext.IsScmRunFromPackage() && !string.IsNullOrEmpty(pkgContext.Url) && pkgContext.Url != "1"))
            {
                await ApplyBlobPackageContext(pkgContext, options.ScriptPath);
            }
            else if (!string.IsNullOrEmpty(assignmentContext.AzureFilesConnectionString))
            {
                await _meshInitServiceClient.MountCifs(assignmentContext.AzureFilesConnectionString, assignmentContext.AzureFilesContentShare, "/home");
            }

            // BYOS
            var storageVolumes = assignmentContext.GetBYOSEnvironmentVariables()
                                 .Select(AzureStorageInfoValue.FromEnvironmentVariable).ToList();

            var mountedVolumes =
                (await Task.WhenAll(storageVolumes.Where(v => v != null).Select(MountStorageAccount))).Where(
                    result => result).ToList();

            if (mountedVolumes.Count != storageVolumes.Count)
            {
                _logger.LogWarning(
                    $"Successfully mounted {mountedVolumes.Count} / {storageVolumes.Count} BYOS storage accounts");
            }
        }
コード例 #2
0
        private async Task ApplyContext(HostAssignmentContext assignmentContext)
        {
            _logger.LogInformation($"Applying {assignmentContext.Environment.Count} app setting(s)");
            assignmentContext.ApplyAppSettings(_environment);

            // We need to get the non-PlaceholderMode script Path so we can unzip to the correct location.
            // This asks the factory to skip the PlaceholderMode check when configuring options.
            var options = _optionsFactory.Create(ScriptApplicationHostOptionsSetup.SkipPlaceholder);
            RunFromPackageContext pkgContext = assignmentContext.GetRunFromPkgContext();

            if ((pkgContext.IsScmRunFromPackage() && await pkgContext.BlobExistsAsync(_logger)) ||
                (!pkgContext.IsScmRunFromPackage() && !string.IsNullOrEmpty(pkgContext.Url) && pkgContext.Url != "1"))
            {
                await ApplyBlobPackageContext(pkgContext, options.ScriptPath);
            }
            else if (!string.IsNullOrEmpty(assignmentContext.AzureFilesConnectionString))
            {
                await MountCifs(assignmentContext.AzureFilesConnectionString, assignmentContext.AzureFilesContentShare, "/home");
            }

            // Irrespective of deployment mechanism mount the share for user data files.
            if (assignmentContext.IsUserDataMountEnabled())
            {
                if (!string.IsNullOrEmpty(assignmentContext.AzureFilesConnectionString) &&
                    !string.IsNullOrEmpty(assignmentContext.AzureFilesContentShare))
                {
                    await MountUserData(assignmentContext);
                }
                else
                {
                    _logger.LogWarning(
                        $"{EnvironmentSettingNames.AzureFilesConnectionString} or {EnvironmentSettingNames.AzureFilesContentShare} is empty. User data share will not be mounted");
                }
            }
        }
コード例 #3
0
        public async Task <string> ValidateContext(HostAssignmentContext assignmentContext)
        {
            _logger.LogInformation($"Validating host assignment context (SiteId: {assignmentContext.SiteId}, SiteName: '{assignmentContext.SiteName}'. IsWarmup: '{assignmentContext.IsWarmupRequest}')");
            RunFromPackageContext pkgContext = assignmentContext.GetRunFromPkgContext();

            _logger.LogInformation($"Will be using {pkgContext.EnvironmentVariableName} app setting as zip url. IsWarmup: '{assignmentContext.IsWarmupRequest}')");

            if (pkgContext.IsScmRunFromPackage())
            {
                // Not user assigned so limit validation
                return(null);
            }
            else if (!string.IsNullOrEmpty(pkgContext.Url) && pkgContext.Url != "1")
            {
                // In AppService, ZipUrl == 1 means the package is hosted in azure files.
                // Otherwise we expect zipUrl to be a blobUri to a zip or a squashfs image
                (var error, var contentLength) = await ValidateBlobPackageContext(pkgContext);

                if (string.IsNullOrEmpty(error))
                {
                    assignmentContext.PackageContentLength = contentLength;
                }
                return(error);
            }
            else if (!string.IsNullOrEmpty(assignmentContext.AzureFilesConnectionString))
            {
                return(await ValidateAzureFilesContext(assignmentContext.AzureFilesConnectionString, assignmentContext.AzureFilesContentShare));
            }
            else
            {
                _logger.LogError($"Missing ZipUrl and AzureFiles config. Continue with empty root.");
                return(null);
            }
        }
コード例 #4
0
        private async Task ApplyContext(HostAssignmentContext assignmentContext)
        {
            _logger.LogInformation($"Applying {assignmentContext.Environment.Count} app setting(s)");
            assignmentContext.ApplyAppSettings(_environment);

            // We need to get the non-PlaceholderMode script Path so we can unzip to the correct location.
            // This asks the factory to skip the PlaceholderMode check when configuring options.
            var options = _optionsFactory.Create(ScriptApplicationHostOptionsSetup.SkipPlaceholder);
            RunFromPackageContext pkgContext = assignmentContext.GetRunFromPkgContext();

            if ((pkgContext.IsScmRunFromPackage() && await pkgContext.BlobExistsAsync(_logger)) ||
                (!pkgContext.IsScmRunFromPackage() && !string.IsNullOrEmpty(pkgContext.Url) && pkgContext.Url != "1"))
            {
                await ApplyBlobPackageContext(pkgContext, options.ScriptPath);
            }
            else if (!string.IsNullOrEmpty(assignmentContext.AzureFilesConnectionString))
            {
                ApplyAzureFilesContext(assignmentContext.AzureFilesConnectionString, assignmentContext.AzureFilesContentShare, "/home");
            }
        }
コード例 #5
0
        public async Task <string> ValidateContext(HostAssignmentContext assignmentContext)
        {
            _logger.LogInformation($"Validating host assignment context (SiteId: {assignmentContext.SiteId}, SiteName: '{assignmentContext.SiteName}'. IsWarmup: '{assignmentContext.IsWarmupRequest}')");
            RunFromPackageContext pkgContext = assignmentContext.GetRunFromPkgContext();

            _logger.LogInformation($"Will be using {pkgContext.EnvironmentVariableName} app setting as zip url. IsWarmup: '{assignmentContext.IsWarmupRequest}')");

            if (pkgContext.IsScmRunFromPackage())
            {
                // Not user assigned so limit validation
                return(null);
            }
            else if (!string.IsNullOrEmpty(pkgContext.Url) && pkgContext.Url != "1")
            {
                if (Uri.TryCreate(pkgContext.Url, UriKind.Absolute, out var uri))
                {
                    if (Utility.IsResourceAzureBlobWithoutSas(uri))
                    {
                        // Note: this also means we skip validation for publicly available blobs
                        _logger.LogDebug("Skipping validation for '{pkgContext.EnvironmentVariableName}' with no SAS token", pkgContext.EnvironmentVariableName);
                        return(null);
                    }
                    else
                    {
                        // In AppService, ZipUrl == 1 means the package is hosted in azure files.
                        // Otherwise we expect zipUrl to be a blobUri to a zip or a squashfs image
                        var(error, contentLength) = await ValidateBlobPackageContext(pkgContext);

                        if (string.IsNullOrEmpty(error))
                        {
                            assignmentContext.PackageContentLength = contentLength;
                        }
                        return(error);
                    }
                }
                else
                {
                    var invalidUrlError = $"Invalid url for specified for {pkgContext.EnvironmentVariableName}";
                    _logger.LogError(invalidUrlError);
                    // For now we return null here instead of the actual error since this validation is new.
                    // Eventually this could return the error message.
                    return(null);
                }
            }
            else if (!string.IsNullOrEmpty(assignmentContext.AzureFilesConnectionString))
            {
                return(await ValidateAzureFilesContext(assignmentContext.AzureFilesConnectionString, assignmentContext.AzureFilesContentShare));
            }
            else
            {
                _logger.LogError("Missing ZipUrl and AzureFiles config. Continue with empty root.");
                return(null);
            }
        }
コード例 #6
0
        public async Task <string> ValidateContext(HostAssignmentContext assignmentContext)
        {
            _logger.LogInformation($"Validating host assignment context (SiteId: {assignmentContext.SiteId}, SiteName: '{assignmentContext.SiteName}')");

            string error = null;
            HttpResponseMessage response = null;

            try
            {
                RunFromPackageContext pkgContext = assignmentContext.GetRunFromPkgContext();
                _logger.LogInformation($"Will be using {pkgContext.EnvironmentVariableName} app setting as zip url");

                if (pkgContext.IsScmRunFromPackage())
                {
                    // Not user assigned so limit validation
                    return(null);
                }

                var zipUrl = pkgContext.Url;
                if (!string.IsNullOrEmpty(zipUrl))
                {
                    // make sure the zip uri is valid and accessible
                    await Utility.InvokeWithRetriesAsync(async() =>
                    {
                        try
                        {
                            using (_metricsLogger.LatencyEvent(MetricEventNames.LinuxContainerSpecializationZipHead))
                            {
                                var request = new HttpRequestMessage(HttpMethod.Head, zipUrl);
                                response    = await _client.SendAsync(request);
                                response.EnsureSuccessStatusCode();
                            }
                        }
                        catch (Exception e)
                        {
                            _logger.LogError(e, $"{MetricEventNames.LinuxContainerSpecializationZipHead} failed");
                            throw;
                        }
                    }, maxRetries : 2, retryInterval : TimeSpan.FromSeconds(0.3)); // Keep this less than ~1s total
                }
            }
            catch (Exception e)
            {
                error = $"Invalid zip url specified (StatusCode: {response?.StatusCode})";
                _logger.LogError(e, "ValidateContext failed");
            }

            return(error);
        }
コード例 #7
0
        private async Task ApplyContext(HostAssignmentContext assignmentContext)
        {
            _logger.LogInformation($"Applying {assignmentContext.Environment.Count} app setting(s)");
            assignmentContext.ApplyAppSettings(_environment);

            // We need to get the non-PlaceholderMode script Path so we can unzip to the correct location.
            // This asks the factory to skip the PlaceholderMode check when configuring options.
            var options = _optionsFactory.Create(ScriptApplicationHostOptionsSetup.SkipPlaceholder);
            RunFromPackageContext pkgContext = assignmentContext.GetRunFromPkgContext();

            var zipPath = pkgContext.Url;

            if (!string.IsNullOrEmpty(zipPath))
            {
                // download zip and extract
                var    zipUri   = new Uri(zipPath);
                string filePath = null;

                if (pkgContext.IsScmRunFromPackage())
                {
                    bool blobExists = await pkgContext.BlobExistsAsync(_logger);

                    if (blobExists)
                    {
                        filePath = await DownloadAsync(zipUri);
                    }
                    else
                    {
                        return;
                    }
                }
                else
                {
                    filePath = await DownloadAsync(zipUri);
                }

                UnpackPackage(filePath, options.ScriptPath);

                string bundlePath = Path.Combine(options.ScriptPath, "worker-bundle");
                if (Directory.Exists(bundlePath))
                {
                    _logger.LogInformation($"Python worker bundle detected");
                }
            }
        }
コード例 #8
0
        private CodePackageType GetPackageType(string filePath, RunFromPackageContext pkgContext)
        {
            // cloud build always builds squashfs
            if (pkgContext.IsScmRunFromPackage())
            {
                return(CodePackageType.Squashfs);
            }

            var uri = new Uri(pkgContext.Url);

            // check file name since it'll be faster than running `file`
            if (FileIsAny(".squashfs", ".sfs", ".sqsh", ".img", ".fs"))
            {
                return(CodePackageType.Squashfs);
            }
            else if (FileIsAny(".zip"))
            {
                return(CodePackageType.Zip);
            }

            // Check file magic-number using `file` command.
            (var output, _, _) = RunBashCommand($"file -b {filePath}", MetricEventNames.LinuxContainerSpecializationFileCommand);
            if (output.StartsWith("Squashfs", StringComparison.OrdinalIgnoreCase))
            {
                return(CodePackageType.Squashfs);
            }
            else if (output.StartsWith("Zip", StringComparison.OrdinalIgnoreCase))
            {
                return(CodePackageType.Zip);
            }
            else
            {
                throw new InvalidOperationException($"Can't find CodePackageType to match {filePath}");
            }

            bool FileIsAny(params string[] options)
            => options.Any(o => uri.AbsolutePath.EndsWith(o, StringComparison.OrdinalIgnoreCase));
        }
コード例 #9
0
        public void Returns_ScmRunFromPackage(string environmentVariableName, bool isScmRunFromPackage)
        {
            var runFromPackageContext = new RunFromPackageContext(environmentVariableName, "", 0, false);

            Assert.Equal(isScmRunFromPackage, runFromPackageContext.IsScmRunFromPackage());
        }