private async Task <SiteExtensionInfo> ConvertRemotePackageToSiteExtensionInfo(UIPackageMetadata package, string feedUrl, UIMetadataResource metadataResource) { // convert uipackagemetadata structure to siteextensioninfo structure var siteExtensionInfo = new SiteExtensionInfo(package); siteExtensionInfo.FeedUrl = feedUrl; // check existing local site extension version and update the field "LocalIsLatestVersion" in siteextensioninfo return(await CheckRemotePackageLatestVersion(siteExtensionInfo, metadataResource)); }
public SiteExtensionInfo InstallExtension(SiteExtensionInfo info) { SiteExtensionInfo extension = _manager.InstallExtension(info); if (extension == null) { throw new HttpResponseException(Request.CreateErrorResponse(HttpStatusCode.NotFound, info.ToString())); } return(extension); }
public SiteExtensionInfo InstallExtension(string id, string version = null) { SiteExtensionInfo extension = _manager.InstallExtension(id, version); if (extension == null) { throw new HttpResponseException(Request.CreateErrorResponse(HttpStatusCode.NotFound, id)); } return(extension); }
public SiteExtensionInfo GetLocalExtension(string id, bool checkLatest = true) { SiteExtensionInfo extension = _manager.GetLocalExtension(id, checkLatest); if (extension == null) { throw new HttpResponseException(Request.CreateErrorResponse(HttpStatusCode.NotFound, id)); } return(extension); }
private async Task SetLocalInfo(SiteExtensionInfo info) { string localPath = GetInstallationDirectory(info.Id); if (FileSystemHelpers.DirectoryExists(localPath)) { info.LocalPath = localPath; info.InstalledDateTime = FileSystemHelpers.GetLastWriteTimeUtc(info.LocalPath); } if (ExtensionRequiresApplicationHost(info)) { info.ExtensionUrl = GetFullUrl(GetUrlFromApplicationHost(localPath)); } else { info.ExtensionUrl = string.IsNullOrEmpty(info.LocalPath) ? null : GetFullUrl(info.ExtensionUrl); } foreach (var setting in GetSettingManager(info.Id).GetValues()) { if (string.Equals(setting.Key, _feedUrlSetting, StringComparison.OrdinalIgnoreCase)) { info.FeedUrl = setting.Value.Value <string>(); } else if (string.Equals(setting.Key, _packageUriSetting, StringComparison.OrdinalIgnoreCase)) { info.PackageUri = setting.Value.Value <string>(); } else if (string.Equals(setting.Key, _installUtcTimestampSetting, StringComparison.OrdinalIgnoreCase)) { DateTime installedDateTime; if (DateTime.TryParse(setting.Value.Value <string>(), out installedDateTime)) { info.InstalledDateTime = installedDateTime.ToUniversalTime(); } } else if (string.Equals(setting.Key, _installationArgs, StringComparison.OrdinalIgnoreCase)) { info.InstallationArgs = setting.Value.Value <string>(); } } if (IsInstalledToWebRoot(info.Id)) { // override WebRoot type from setting // WebRoot is a special type that install package to wwwroot, when perform update we need to update new content to wwwroot even if type is not specified info.Type = SiteExtensionInfo.SiteExtensionType.WebRoot; } if (FileSystemHelpers.DirectoryExists(localPath) && string.IsNullOrEmpty(info.PackageUri)) { await TryCheckLocalPackageLatestVersionFromRemote(info); } }
public async Task SiteExtensionPreInstalledTests() { const string appName = "SiteExtensionBasicTests"; await ApplicationManager.RunAsync(appName, async appManager => { var manager = appManager.SiteExtensionManager; await CleanSiteExtensions(manager); // list List <SiteExtensionInfo> results = await(await manager.GetRemoteExtensions()).Content.ReadAsAsync <List <SiteExtensionInfo> >(); Assert.True(results.Any(), "GetRemoteExtensions expects results > 0"); // pick site extension var expectedId = _preInstalledExtensions.Keys.ToArray()[new Random().Next(_preInstalledExtensions.Count)]; var expected = results.Find(ext => String.Equals(ext.Id, expectedId, StringComparison.OrdinalIgnoreCase)); TestTracer.Trace("Testing Against Site Extension {0}", expectedId); // get SiteExtensionInfo result = await(await manager.GetRemoteExtension(expectedId)).Content.ReadAsAsync <SiteExtensionInfo>(); Assert.Equal(expected.Id, result.Id); Assert.Equal(expected.Version, result.Version); // clear local extensions results = await(await manager.GetLocalExtensions()).Content.ReadAsAsync <List <SiteExtensionInfo> >(); bool deleteResult = false; foreach (var ext in results) { deleteResult = await(await manager.UninstallExtension(ext.Id)).Content.ReadAsAsync <bool>(); Assert.True(deleteResult, "Delete must return true"); } // install/update result = await(await manager.InstallExtension(expected.Id)).Content.ReadAsAsync <SiteExtensionInfo>(); Assert.Equal(expected.Id, result.Id); Assert.Equal(expected.Version, result.Version); // list results = await(await manager.GetLocalExtensions()).Content.ReadAsAsync <List <SiteExtensionInfo> >(); Assert.True(results.Any(), "GetLocalExtensions expects results > 0"); // get result = await(await manager.GetLocalExtension(expected.Id)).Content.ReadAsAsync <SiteExtensionInfo>(); Assert.Equal(expected.Id, result.Id); // delete deleteResult = await(await manager.UninstallExtension(expected.Id)).Content.ReadAsAsync <bool>(); Assert.True(deleteResult, "Delete must return true"); // list installed results = await(await manager.GetLocalExtensions()).Content.ReadAsAsync <List <SiteExtensionInfo> >(); Assert.False(results.Exists(ext => ext.Id == expected.Id), "After deletion extension " + expected.Id + " should not exist."); }); }
public async Task <HttpResponseMessage> UninstallExtension(string id) { var startTime = DateTime.UtcNow; try { HttpResponseMessage response = null; bool isUninstalled = await _manager.UninstallExtension(id); if (ArmUtils.IsArmRequest(Request)) { if (isUninstalled) { response = Request.CreateResponse(HttpStatusCode.OK); } else { var extension = new SiteExtensionInfo { Id = id }; response = Request.CreateResponse(HttpStatusCode.BadRequest, ArmUtils.AddEnvelopeOnArmRequest <SiteExtensionInfo>(extension, Request)); } } else { response = Request.CreateResponse(HttpStatusCode.OK, isUninstalled); } LogEndEvent(id, (DateTime.UtcNow - startTime), _traceFactory.GetTracer(), defaultResult: Constants.SiteExtensionProvisioningStateSucceeded); return(response); } catch (DirectoryNotFoundException ex) { _analytics.UnexpectedException( ex, method: "DELETE", path: string.Format(CultureInfo.InvariantCulture, "/api/siteextensions/{0}", id), result: Constants.SiteExtensionProvisioningStateFailed, message: null, trace: false); throw new HttpResponseException(Request.CreateErrorResponse(HttpStatusCode.NotFound, ex)); } catch (Exception ex) { _analytics.UnexpectedException( ex, method: "DELETE", path: string.Format(CultureInfo.InvariantCulture, "/api/siteextensions/{0}", id), result: Constants.SiteExtensionProvisioningStateFailed, message: null, trace: false); throw ex; } }
public async Task <SiteExtensionInfo> GetRemoteExtension(string id, string version = null, string feedUrl = null) { SiteExtensionInfo extension = await _manager.GetRemoteExtension(id, version, feedUrl); if (extension == null) { throw new HttpResponseException(Request.CreateErrorResponse(HttpStatusCode.NotFound, id)); } return(extension); }
public Task <SiteExtensionInfo> InstallExtension(string id, SiteExtensionInfo requestInfo, ITracer tracer) { var installationTask = InstallExtensionCore(id, requestInfo, tracer); #pragma warning disable 4014 // Track pending task PostDeploymentHelper.TrackPendingOperation(installationTask, TimeSpan.Zero); #pragma warning restore 4014 return(installationTask); }
public void UpdateLocalInfo(SiteExtensionInfo info) { string localPath = GetInstallationDirectory(info.Id); if (FileSystemHelpers.DirectoryExists(localPath)) { info.ExtensionUrl = "/" + info.Id + "/"; info.LocalPath = localPath; info.InstalledDateTime = FileSystemHelpers.GetLastWriteTimeUtc(info.LocalPath); } }
private async Task <SiteExtensionInfo> CheckRemotePackageLatestVersion(SiteExtensionInfo info, UIMetadataResource metadataResource) { UIPackageMetadata localPackage = await metadataResource.GetLatestPackageByIdFromMetaRes(info.Id); if (localPackage != null) { SetLocalInfo(info); // Assume input package (from remote) is always the latest version. info.LocalIsLatestVersion = NuGetVersion.Parse(info.Version).Equals(localPackage.Identity.Version); } return(info); }
public async Task <HttpResponseMessage> GetRemoteExtension(string id, string version = null, string feedUrl = null) { SiteExtensionInfo extension = await _manager.GetRemoteExtension(id, version, feedUrl); if (extension == null) { throw new HttpResponseException(Request.CreateErrorResponse(HttpStatusCode.NotFound, id)); } return(Request.CreateResponse( HttpStatusCode.OK, ArmUtils.AddEnvelopeOnArmRequest <SiteExtensionInfo>(extension, Request))); }
private async Task <SiteExtensionInfo> ConvertLocalPackageToSiteExtensionInfo(UIPackageMetadata package, bool checkLatest) { if (package == null) { return(null); } var info = new SiteExtensionInfo(package); SetLocalInfo(info); await TryCheckLocalPackageLatestVersionFromRemote(info, checkLatest); return(info); }
private async Task <SiteExtensionInfo> CheckRemotePackageLatestVersion(SiteExtensionInfo info, string feedUrl) { info.FeedUrl = feedUrl; UIPackageMetadata localPackage = await _localRepository.GetLatestPackageById(info.Id); if (localPackage != null) { SetLocalInfo(info); // Assume input package (from remote) is always the latest version. info.LocalIsLatestVersion = NuGetVersion.Parse(info.Version).Equals(localPackage.Identity.Version); } return(info); }
/// <summary> /// Helper function to download package from given url, and place package (only 'content' folder from package) to given folder /// </summary> /// <param name="identity">Package identity</param> /// <param name="destinationFolder">Folder where we copy the package content (content folder only) to</param> /// <param name="pathToLocalCopyOfNupkg">File path where we copy the nudpk to</param> /// <returns></returns> public static async Task DownloadPackageToFolder(SiteExtensionInfo package, string destinationFolder, string pathToLocalCopyOfNupkg) { var packageId = package.Id; var packageVersion = package.Version; using (var client = new HttpClient { Timeout = HttpClientTimeout }) { var uri = new Uri(!string.IsNullOrEmpty(package.PackageUri) ? package.PackageUri : $"https://www.nuget.org/api/v2/package/{packageId}/{packageVersion}"); var response = await client.GetAsync(uri); using (Stream packageStream = await response.Content.ReadAsStreamAsync()) { using (ZipFile zipFile = ZipFile.Read(packageStream)) { // we only care about stuff under "content" folder int substringStartIndex = @"content/".Length; IEnumerable <ZipEntry> contentEntries = zipFile.Entries.Where(e => e.FileName.StartsWith(@"content/", StringComparison.InvariantCultureIgnoreCase)); foreach (var entry in contentEntries) { string entryFileName = Uri.UnescapeDataString(entry.FileName); string fullPath = Path.Combine(destinationFolder, entryFileName.Substring(substringStartIndex)); if (entry.IsDirectory) { FileSystemHelpers.EnsureDirectory(fullPath.Replace('/', '\\')); continue; } FileSystemHelpers.EnsureDirectory(Path.GetDirectoryName(fullPath)); using (Stream writeStream = FileSystemHelpers.OpenWrite(fullPath)) { // reset length of file stream writeStream.SetLength(0); // let the thread go with itself, so that once file finishes writing, doesn't need to request thread context from main thread await entry.OpenReader().CopyToAsync(writeStream).ConfigureAwait(false); } } } // set position back to the head of stream packageStream.Position = 0; // save a copy of the nupkg at last WriteStreamToFile(packageStream, pathToLocalCopyOfNupkg); } } }
public SiteExtensionInfo ConvertRemotePackageToSiteExtensionInfo(IPackage package) { var info = new SiteExtensionInfo(package); IPackage localPackage = _localRepository.FindPackage(info.Id); if (localPackage != null) { UpdateLocalInfo(info); // Assume input package (from remote) is always the latest version. info.LocalIsLatestVersion = package.Version == localPackage.Version; } return(info); }
private SiteExtensionInfo GetPreInstalledExtension(string id) { if (_preInstalledExtensionDictionary.ContainsKey(id)) { var info = new SiteExtensionInfo(_preInstalledExtensionDictionary[id]); SetLocalInfo(info); return(info); } else { return(null); } }
private async Task <SiteExtensionInfo> InitInstallSiteExtension(string id, SiteExtensionInfo.SiteExtensionType type) { SiteExtensionStatus settings = new SiteExtensionStatus(_environment.SiteExtensionSettingsPath, id, _traceFactory.GetTracer()); settings.ProvisioningState = Constants.SiteExtensionProvisioningStateCreated; settings.Operation = Constants.SiteExtensionOperationInstall; settings.Status = HttpStatusCode.Created; settings.Type = type; settings.Comment = null; SiteExtensionInfo info = new SiteExtensionInfo(); info.Id = id; settings.FillSiteExtensionInfo(info); return(await Task.FromResult(info)); }
public async Task <HttpResponseMessage> InstallExtension(string id, SiteExtensionInfo requestInfo) { var startTime = DateTime.UtcNow; if (requestInfo == null) { requestInfo = new SiteExtensionInfo(); } SiteExtensionInfo result; try { result = await _manager.InstallExtension(id, requestInfo.Version, requestInfo.FeedUrl); } catch (WebException e) { // This can happen for example if a bad feed URL is passed throw new HttpResponseException(Request.CreateErrorResponse(HttpStatusCode.BadRequest, "Site extension download failure", e)); } catch (Exception e) { // This can happen for example if the exception package is corrupted throw new HttpResponseException(Request.CreateErrorResponse(HttpStatusCode.BadRequest, "Site extension install exception. The package might be invalid.", e)); } if (result == null) { throw new HttpResponseException(Request.CreateErrorResponse(HttpStatusCode.NotFound, "Could not find " + id)); } // TODO: xiaowu, when update to real csm async, should return "Accepted" instead of "OK" var responseMessage = Request.CreateResponse(HttpStatusCode.OK, ArmUtils.AddEnvelopeOnArmRequest <SiteExtensionInfo>(result, Request)); if (result != null && // result not null indicate instalation success, when move to async operation, will relying on provisionState instead result.InstalledDateTime.HasValue && result.InstalledDateTime.Value > startTime && ArmUtils.IsArmRequest(Request)) { // Populate this header if // Request is from ARM // Installation action is performed responseMessage.Headers.Add("X-MS-SITE-OPERATION", Constants.SiteOperationRestart); } return(responseMessage); }
/// <summary> /// <para> Return false if the installation arguments are different. Otherwise,</para> /// <para> Return true if any of below cases is satisfied:</para> /// <para> 1) Package with same version and from same feed already exist in local repo</para> /// <para> 2) If given feedUrl is null</para> /// <para> Try to use feed from local package, if feed from local package also null, fallback to default feed</para> /// <para> Check if version from query is same as local package</para> /// <para> 3) If given version and feedUrl are null</para> /// <para> Try to use feed from local package, if feed from local package also null, fallback to default feed</para> /// <para> Check if version from query is same as local package</para> /// </summary> private async Task <bool> IsSiteExtensionInstalled(string id, SiteExtensionInfo requestInfo) { ITracer tracer = _traceFactory.GetTracer(); JsonSettings siteExtensionSettings = GetSettingManager(id); string localPackageVersion = siteExtensionSettings.GetValue(_versionSetting); string localPackageInstallationArgs = siteExtensionSettings.GetValue(_installationArgs); SemanticVersion localPkgVer = null; SemanticVersion lastFoundVer = null; SiteExtensionInfo latestRemotePackage; bool isInstalled = false; var installationArgs = requestInfo.InstallationArgs; // Shortcircuit check: if the installation arguments do not match, then we should return false here to avoid other checks which are now unnecessary. if (!string.Equals(localPackageInstallationArgs, installationArgs)) { return(false); } if (!string.IsNullOrEmpty(localPackageVersion)) { tracer.Trace(string.Format("Site Extension {0} local version is {1}", id, localPackageVersion)); SemanticVersion.TryParse(localPackageVersion, out localPkgVer); } if (!string.IsNullOrEmpty(requestInfo.PackageUri)) { SemanticVersion.TryParse(requestInfo.Version, out lastFoundVer); } else { latestRemotePackage = await GetSiteExtensionInfoFromRemote(id); if (latestRemotePackage != null) { tracer.Trace(string.Format("Site Extension {0} remote version is {1}", id, latestRemotePackage.Version)); SemanticVersion.TryParse(latestRemotePackage.Version, out lastFoundVer); } } if (lastFoundVer != null && localPkgVer != null && lastFoundVer <= localPkgVer) { tracer.Trace(string.Format("Site Extension with id {0} is already installed", id)); isInstalled = true; } return(isInstalled); }
private async Task TryCheckLocalPackageLatestVersionFromRemote(SiteExtensionInfo info, bool checkLatest) { if (checkLatest) { // FindPackage gets back the latest version. SourceRepository remoteRepo = GetRemoteRepository(info.FeedUrl); UIPackageMetadata latestPackage = await remoteRepo.GetLatestPackageById(info.Id); if (latestPackage != null) { NuGetVersion currentVersion = NuGetVersion.Parse(info.Version); info.LocalIsLatestVersion = NuGetVersion.Parse(info.Version).Equals(latestPackage.Identity.Version); info.DownloadCount = latestPackage.DownloadCount; info.PublishedDateTime = latestPackage.Published; } } }
private static string GetUrlFromApplicationHost(SiteExtensionInfo info) { try { var appHostDoc = new XmlDocument(); appHostDoc.Load(Path.Combine(info.LocalPath, Constants.ApplicationHostXdtFileName)); // Get the 'path' property of the first 'application' element, which is the relative url. XmlNode pathPropertyNode = appHostDoc.SelectSingleNode("//application[@path]/@path"); return(pathPropertyNode.Value); } catch (SystemException) { return(null); } }
private SiteExtensionInfo ConvertRemotePackageToSiteExtensionInfo(IPackage package, string feedUrl) { var info = new SiteExtensionInfo(package); info.FeedUrl = feedUrl; IPackage localPackage = _localRepository.FindPackage(info.Id); if (localPackage != null) { SetLocalInfo(info); // Assume input package (from remote) is always the latest version. info.LocalIsLatestVersion = package.Version == localPackage.Version; } return(info); }
private async Task <SiteExtensionInfo> InstallExtensionCore(string id, SiteExtensionInfo requestInfo, ITracer tracer) { var version = requestInfo.Version; var feedUrl = requestInfo.FeedUrl; var type = requestInfo.Type; var installationArgs = requestInfo.InstallationArgs; var packageUri = requestInfo.PackageUri; try { using (tracer.Step("Installing '{0}' version '{1}' from '{2}'", id, version, StringUtils.ObfuscatePath(!string.IsNullOrEmpty(packageUri) ? packageUri : feedUrl))) { var installationLock = SiteExtensionInstallationLock.CreateLock(_environment.SiteExtensionSettingsPath, id, enableAsync: true); // hold on to lock till action complete (success or fail) return(await installationLock.LockOperationAsync <SiteExtensionInfo>(async() => { return await TryInstallExtension(id, requestInfo, tracer); }, "Installing SiteExtension", TimeSpan.Zero)); } } catch (Exception ex) { _analytics.UnexpectedException( ex, method: "PUT", path: string.Format(CultureInfo.InvariantCulture, "/api/siteextensions/{0}", id), result: Constants.SiteExtensionProvisioningStateFailed, message: string.Format(CultureInfo.InvariantCulture, "{{\"version\": {0}, \"feed_url\": {1}}}", version, feedUrl), trace: false); // handle unexpected exception tracer.TraceError(ex); var info = new SiteExtensionInfo(); info.Id = id; SiteExtensionStatus armStatus = new SiteExtensionStatus(_environment.SiteExtensionSettingsPath, id, tracer); armStatus.Operation = Constants.SiteExtensionOperationInstall; armStatus.ProvisioningState = Constants.SiteExtensionProvisioningStateFailed; armStatus.Status = HttpStatusCode.BadRequest; armStatus.FillSiteExtensionInfo(info); tracer.Trace("Update arm settings for {0} installation. Status: {1}", id, armStatus.Status); return(info); } }
public async Task SiteExtensionInstallUpdateIdempotentTest(string feedEndpoint) { TestTracer.Trace("Testing against feed: '{0}'", feedEndpoint); const string appName = "SiteExtensionInstallIdempotentTest"; const string testPackageId = "bootstrap"; await ApplicationManager.RunAsync(appName, async appManager => { var manager = appManager.SiteExtensionManager; // Get the latest package, make sure that call will return right away when we try to update TestTracer.Trace("Get latest package '{0}' from '{1}'", testPackageId, feedEndpoint); SiteExtensionInfo latestPackage = await manager.GetRemoteExtension(testPackageId, feedUrl: feedEndpoint); TestTracer.Trace("Uninstall package '{0}'", latestPackage.Id); try { // uninstall package if it is there await manager.UninstallExtension(testPackageId); } catch { // ignore exception } // install from non-default endpoint TestTracer.Trace("Install package '{0}'-'{1}' fresh from '{2}'.", latestPackage.Id, latestPackage.Version, feedEndpoint); HttpResponseResult <ArmEntry <SiteExtensionInfo> > richResult = await manager.InstallExtension <ArmEntry <SiteExtensionInfo> >(id: testPackageId, version: latestPackage.Version, feedUrl: feedEndpoint); Assert.Equal(latestPackage.Id, richResult.Body.Properties.Id); Assert.Equal(latestPackage.Version, richResult.Body.Properties.Version); Assert.Equal(feedEndpoint, richResult.Body.Properties.FeedUrl); Assert.True(richResult.Headers[Constants.SiteOperationHeaderKey].Contains(Constants.SiteOperationRestart)); TestTracer.Trace("Try to update package '{0}' without given a feed.", testPackageId); // Not passing feed endpoint will default to feed endpoint from installed package // Update should return right away, expecting code to look up from feed that store in local package // since we had installed the latest package, there is nothing to update. // We shouldn`t see any site operation header value richResult = await manager.InstallExtension <ArmEntry <SiteExtensionInfo> >(testPackageId); Assert.Equal(latestPackage.Id, richResult.Body.Properties.Id); Assert.Equal(feedEndpoint, richResult.Body.Properties.FeedUrl); Assert.False(richResult.Headers.ContainsKey(Constants.SiteOperationHeaderKey)); }); }
public async Task <bool> UninstallExtension(string id) { ITracer tracer = _traceFactory.GetTracer(); string installationDirectory = GetInstallationDirectory(id); SiteExtensionInfo info = await GetLocalExtension(id, checkLatest : false); if (info == null || !FileSystemHelpers.DirectoryExists(info.LocalPath)) { tracer.TraceError("Site extension {0} not found.", id); throw new DirectoryNotFoundException(installationDirectory); } var externalCommandFactory = new ExternalCommandFactory(_environment, _settings, installationDirectory); string uninstallScript = Path.Combine(installationDirectory, _uninstallScriptName); if (FileSystemHelpers.FileExists(uninstallScript)) { using (tracer.Step("Execute uninstall.cmd")) { OperationManager.Attempt(() => { Executable exe = externalCommandFactory.BuildCommandExecutable(uninstallScript, installationDirectory, _settings.GetCommandIdleTimeout(), NullLogger.Instance); exe.ExecuteWithProgressWriter(NullLogger.Instance, _traceFactory.GetTracer(), String.Empty); }); } } using (tracer.Step("Remove site extension job")) { OperationManager.Attempt(() => CleanupSiteExtensionJobs(id)); } using (tracer.Step("Delete site extension package and directory")) { OperationManager.Attempt(() => FileSystemHelpers.DeleteFileSafe(GetNuGetPackageFile(info.Id, info.Version))); OperationManager.Attempt(() => FileSystemHelpers.DeleteDirectorySafe(installationDirectory)); } return(await GetLocalExtension(id, checkLatest : false) == null); }
/// <summary> /// Returns a remote site extension metadata for a particular id and version, null /// if this id and version doesn't exist in the report repo /// </summary> public async Task <SiteExtensionInfo> GetRemoteExtension(string id, string version, string feedUrl) { ITracer tracer = _traceFactory.GetTracer(); SiteExtensionInfo package = await GetSiteExtensionInfoFromRemote(id, version, tracer); if (package == null) { tracer.Trace("No package found with id: {0} and version: {1}", id, version); return(null); } if (package != null) { await SetLocalInfo(package); } return(package); }
public SiteExtensionInfo GetLocalExtension(string id, bool checkLatest = true) { SiteExtensionInfo info = GetPreInstalledExtension(id); if (info != null && info.ExtensionUrl != null) { return(info); } IPackage package = _localRepository.FindPackage(id); if (package == null) { return(null); } return(ConvertLocalPackageToSiteExtensionInfo(package, checkLatest)); }
public SiteExtensionInfo ConvertLocalPackageToSiteExtensionInfo(IPackage package, bool checkLatest = true) { var info = new SiteExtensionInfo(package); UpdateLocalInfo(info); if (checkLatest) { // FindPackage gets back the latest version. IPackage latestPackage = _remoteRepository.FindPackage(info.Id); if (latestPackage != null) { info.LocalIsLatestVersion = package.Version == latestPackage.Version; info.DownloadCount = package.DownloadCount; } } return(info); }
private async Task <SiteExtensionInfo> ConvertLocalPackageToSiteExtensionInfo(UIPackageMetadata package, bool checkLatest, ITracer tracer = null) { if (package == null) { return(null); } var info = new SiteExtensionInfo(package); if (IsInstalledToWebRoot(info.Id)) { info.Type = SiteExtensionInfo.SiteExtensionType.WebRoot; } SetLocalInfo(info); await TryCheckLocalPackageLatestVersionFromRemote(info, checkLatest, tracer); return(info); }