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"); } }
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"); } } }
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); } }
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"); } }
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); } }
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); }
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"); } } }
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)); }
public void Returns_ScmRunFromPackage(string environmentVariableName, bool isScmRunFromPackage) { var runFromPackageContext = new RunFromPackageContext(environmentVariableName, "", 0, false); Assert.Equal(isScmRunFromPackage, runFromPackageContext.IsScmRunFromPackage()); }