// <inheritdoc />
        public async Task <SiteExtensionInfo> GetLocalExtension(string id, bool checkLatest = true)
        {
            ITracer           tracer  = _traceFactory.GetTracer();
            UIPackageMetadata package = null;

            using (tracer.Step("Now querying from local repo for package '{0}'.", id))
            {
                package = await _localRepository.GetLatestPackageByIdFromSrcRepo(id);
            }

            if (package == null)
            {
                tracer.Trace("No package found from local repo with id: {0}.", id);
                return(null);
            }

            SiteExtensionInfo info;

            using (tracer.Step("Converting NuGet object to SiteExtensionInfo"))
            {
                info = await ConvertLocalPackageToSiteExtensionInfo(package, checkLatest, tracer : tracer);
            }

            SiteExtensionStatus armSettings = new SiteExtensionStatus(_environment.SiteExtensionSettingsPath, id, tracer);

            armSettings.FillSiteExtensionInfo(info);
            return(info);
        }
示例#2
0
        // can be called concurrently if metaDataResource is provided
        internal static async Task <UIPackageMetadata> GetLatestPackageByIdFromMetaRes(this UIMetadataResource metadataResource, string packageId, bool includePrerelease = true, bool includeUnlisted = false, bool explicitTag = false)
        {
            UIPackageMetadata latestPackage          = null;
            IEnumerable <UIPackageMetadata> packages = await metadataResource.GetMetadata(packageId, includePrerelease, includeUnlisted, token : CancellationToken.None);

            // When using nuget.org, we only look at packages that have our tag.
            if (explicitTag)
            {
                packages = packages.Where(item => item.Tags.IndexOf("azuresiteextension", StringComparison.OrdinalIgnoreCase) >= 0);
            }

            foreach (var p in packages)
            {
                if (latestPackage == null ||
                    latestPackage.Identity.Version < p.Identity.Version)
                {
                    latestPackage = p;
                }
            }

            // If we couldn't find any listed version, fall back to looking for unlisted versions, to avoid failing completely.
            // Reasoning is that if all the versions have been unlisted, it should still be possible to install it by
            // explicit id, even without specifying a version
            if (latestPackage == null && !includeUnlisted)
            {
                latestPackage = await GetLatestPackageByIdFromMetaRes(metadataResource, packageId, includePrerelease, includeUnlisted : true, explicitTag : explicitTag);
            }

            return(latestPackage);
        }
        private async Task TryCheckLocalPackageLatestVersionFromRemote(SiteExtensionInfo info, bool checkLatest, ITracer tracer = null)
        {
            if (checkLatest)
            {
                try
                {
                    // FindPackage gets back the latest version.
                    IEnumerable <SourceRepository> remoteRepos = GetRemoteRepositories(info.FeedUrl);
                    foreach (SourceRepository remoteRepo in remoteRepos)
                    {
                        UIPackageMetadata latestPackage = await remoteRepo.GetLatestPackageByIdFromSrcRepo(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;
                            break;
                        }
                    }
                }
                catch (Exception ex)
                {
                    if (tracer != null)
                    {
                        tracer.TraceError(ex);
                    }
                }
            }
        }
示例#4
0
        /// <summary>
        /// <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, string version, string feedUrl)
        {
            JsonSettings siteExtensionSettings = GetSettingManager(id);
            string       localPackageVersion   = siteExtensionSettings.GetValue(_versionSetting);
            string       localPackageFeedUrl   = siteExtensionSettings.GetValue(_feedUrlSetting);
            bool         isInstalled           = false;

            // Try to use given feed
            // If given feed is null, try with feed that from local package
            // And GetRemoteRepository will fallback to use default feed if pass in feed param is null
            SourceRepository remoteRepo = GetRemoteRepository(feedUrl ?? localPackageFeedUrl);

            // case 1 and 2
            if (!string.IsNullOrWhiteSpace(version) &&
                version.Equals(localPackageVersion, StringComparison.OrdinalIgnoreCase) &&
                remoteRepo.PackageSource.Source.Equals(localPackageFeedUrl, StringComparison.OrdinalIgnoreCase))
            {
                isInstalled = true;
            }
            else if (string.IsNullOrWhiteSpace(version) && string.IsNullOrWhiteSpace(feedUrl))
            {
                // case 3
                UIPackageMetadata remotePackage = await remoteRepo.GetLatestPackageByIdFromSrcRepo(id);

                if (remotePackage != null)
                {
                    isInstalled = remotePackage.Identity.Version.ToNormalizedString().Equals(localPackageVersion, StringComparison.OrdinalIgnoreCase);
                }
            }

            return(isInstalled);
        }
示例#5
0
        // <inheritdoc />
        public async Task <SiteExtensionInfo> GetLocalExtension(string id, bool checkLatest = true)
        {
            ITracer           tracer = _traceFactory.GetTracer();
            SiteExtensionInfo info   = GetPreInstalledExtension(id);

            if (info != null && info.ExtensionUrl != null)
            {
                tracer.Trace("Pre-installed site extension found: {0}", id);
            }
            else
            {
                UIPackageMetadata package = null;
                using (tracer.Step("{0} is not a pre-installed package. Now querying from local repo.", id))
                {
                    package = await _localRepository.GetLatestPackageById(id);
                }

                if (package == null)
                {
                    tracer.Trace("No package found from local repo with id: {0}.", id);
                    return(null);
                }

                using (tracer.Step("Converting NuGet object to SiteExtensionInfo"))
                {
                    info = await ConvertLocalPackageToSiteExtensionInfo(package, checkLatest, tracer : tracer);
                }
            }

            SiteExtensionStatus armSettings = new SiteExtensionStatus(_environment.SiteExtensionSettingsPath, id, tracer);

            armSettings.FillSiteExtensionInfo(info);
            return(info);
        }
示例#6
0
        public async Task <SiteExtensionInfo> GetRemoteExtension(string id, string version, string feedUrl)
        {
            ITracer tracer = _traceFactory.GetTracer();

            SourceRepository  remoteRepo = GetRemoteRepository(feedUrl);
            UIPackageMetadata package    = null;

            if (string.IsNullOrWhiteSpace(version))
            {
                using (tracer.Step("Version is null, search latest package by id: {0}", id))
                {
                    package = await remoteRepo.GetLatestPackageByIdFromSrcRepo(id);
                }
            }
            else
            {
                using (tracer.Step("Search package by id: {0} and version: {1}", id, version))
                {
                    package = await remoteRepo.GetPackageByIdentity(id, version);
                }
            }

            if (package == null)
            {
                tracer.Trace("No package found with id: {0} and version: {1}", id, version);
                return(null);
            }

            var metadataResource = await _localRepository.GetResourceAndValidateAsync <UIMetadataResource>();

            return(await ConvertRemotePackageToSiteExtensionInfo(package, feedUrl, metadataResource));
        }
示例#7
0
        /// <summary>
        /// <para>1. Download package</para>
        /// <para>2. Generate xdt file if not exist</para>
        /// <para>3. Deploy site extension job</para>
        /// <para>4. Execute install.cmd if exist</para>
        /// </summary>
        private async Task <UIPackageMetadata> InstallExtension(UIPackageMetadata package, string installationDirectory, string feedUrl)
        {
            ITracer tracer = _traceFactory.GetTracer();

            try
            {
                if (FileSystemHelpers.DirectoryExists(installationDirectory))
                {
                    FileSystemHelpers.DeleteDirectorySafe(installationDirectory);
                }

                SourceRepository remoteRepo = GetRemoteRepository(feedUrl);

                // Copy content folder
                // Copy nupkg file for package list/lookup
                FileSystemHelpers.CreateDirectory(installationDirectory);
                // package path from local repo
                string packageLocalFilePath = GetNuGetPackageFile(package.Identity.Id, package.Identity.Version.ToString());
                using (tracer.Step("Download site extension: {0}", package.Identity))
                {
                    await remoteRepo.DownloadPackageToFolder(package.Identity, installationDirectory, pathToLocalCopyOfNudpk : packageLocalFilePath);
                }

                // If there is no xdt file, generate default.
                using (tracer.Step("Check if applicationhost.xdt file existed."))
                {
                    GenerateApplicationHostXdt(installationDirectory, '/' + package.Identity.Id, isPreInstalled: false, tracer: tracer);
                }

                using (tracer.Step("Trigger site extension job"))
                {
                    OperationManager.Attempt(() => DeploySiteExtensionJobs(package.Identity.Id));
                }

                var    externalCommandFactory = new ExternalCommandFactory(_environment, _settings, installationDirectory);
                string installScript          = Path.Combine(installationDirectory, _installScriptName);
                if (FileSystemHelpers.FileExists(installScript))
                {
                    using (tracer.Step("Execute install.cmd"))
                    {
                        OperationManager.Attempt(() =>
                        {
                            Executable exe = externalCommandFactory.BuildCommandExecutable(installScript,
                                                                                           installationDirectory,
                                                                                           _settings.GetCommandIdleTimeout(), NullLogger.Instance);
                            exe.ExecuteWithProgressWriter(NullLogger.Instance, _traceFactory.GetTracer(), String.Empty);
                        });
                    }
                }
            }
            catch (Exception ex)
            {
                tracer.TraceError(ex);
                FileSystemHelpers.DeleteDirectorySafe(installationDirectory);
                throw;
            }

            return(await _localRepository.GetLatestPackageById(package.Identity.Id));
        }
示例#8
0
        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);
        }
示例#9
0
        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);
        }
示例#10
0
        // can be called concurrently if metaDataResource is provided
        internal static async Task<UIPackageMetadata> GetLatestPackageByIdFromMetaRes(this UIMetadataResource metadataResource, string packageId, bool includePrerelease = true, bool includeUnlisted = false)
        {
            UIPackageMetadata latestPackage = null;
            IEnumerable<UIPackageMetadata> packages = await metadataResource.GetMetadata(packageId, includePrerelease, includeUnlisted, token: CancellationToken.None);
            foreach (var p in packages)
            {
                if (latestPackage == null ||
                    latestPackage.Identity.Version < p.Identity.Version)
                {
                    latestPackage = p;
                }
            }

            return latestPackage;
        }
 public SiteExtensionInfo(UIPackageMetadata data)
 {
     Id = data.Identity.Id;
     Title = data.Identity.Id;
     Type = SiteExtensionType.Gallery;
     Summary = data.Summary;
     Description = data.Description;
     Version = data.Identity.Version.ToNormalizedString();
     ProjectUrl = data.ProjectUrl == null ? null : data.ProjectUrl.ToString();
     IconUrl = data.IconUrl == null ? "https://www.siteextensions.net/Content/Images/packageDefaultIcon-50x50.png" : data.IconUrl.ToString();
     LicenseUrl = data.LicenseUrl == null ? null : data.LicenseUrl.ToString();
     Authors = data.Authors.Split(new string[] { "  " }, StringSplitOptions.RemoveEmptyEntries);
     PublishedDateTime = data.Published;
     IsLatestVersion = true;
     DownloadCount = data.DownloadCount;
 }
 public SiteExtensionInfo(UIPackageMetadata data)
 {
     Id                = data.Identity.Id;
     Title             = data.Title;
     Type              = SiteExtensionType.Gallery;
     Summary           = data.Summary;
     Description       = data.Description;
     Version           = data.Identity.Version.ToNormalizedString();
     ProjectUrl        = data.ProjectUrl == null ? null : data.ProjectUrl.ToString();
     IconUrl           = data.IconUrl == null ? "https://www.siteextensions.net/Content/Images/packageDefaultIcon-50x50.png" : data.IconUrl.ToString();
     LicenseUrl        = data.LicenseUrl == null ? null : data.LicenseUrl.ToString();
     Authors           = data.Authors.Split(new string[] { "  " }, StringSplitOptions.RemoveEmptyEntries);
     PublishedDateTime = data.Published;
     IsLatestVersion   = true;
     DownloadCount     = data.DownloadCount;
 }
示例#13
0
        /// <summary>
        /// <para>Query source repository for a package base on given package id and version</para>
        /// <para>Will also query pre-release and unlisted packages</para>
        /// </summary>
        /// <param name="packageId">Package id, must not be null</param>
        /// <param name="version">Package version, must not be null</param>
        /// <returns>Package metadata</returns>
        public static async Task <UIPackageMetadata> GetPackageByIdentity(this SourceRepository srcRepo, string packageId, string version)
        {
            var metadataResource = await srcRepo.GetResourceAndValidateAsync <UIMetadataResource>();

            NuGetVersion      expectedVersion = NuGetVersion.Parse(version);
            var               identity        = new PackageIdentity(packageId, expectedVersion);
            UIPackageMetadata ret             = await metadataResource.GetMetadata(identity, CancellationToken.None);

            // When using nuget.org, we only look at packages that have our tag.
            if (ret != null &&
                IsNuGetRepo(srcRepo.PackageSource.Source) &&
                (ret.Tags.IndexOf("azuresiteextension", StringComparison.OrdinalIgnoreCase) < 0))
            {
                ret = null;
            }
            return(ret);
        }
示例#14
0
        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;
                }
            }
        }
示例#15
0
        /// <summary>
        /// Query source repository for latest package base given package id
        /// </summary>
        public static async Task <UIPackageMetadata> GetLatestPackageById(this SourceRepository srcRepo, string packageId)
        {
            UIPackageMetadata latestPackage = null;
            var metadataResource            = await srcRepo.GetResourceAsync <UIMetadataResource>();

            IEnumerable <UIPackageMetadata> packages = await metadataResource.GetMetadata(packageId, true, true, CancellationToken.None);

            foreach (var p in packages)
            {
                if (latestPackage == null ||
                    latestPackage.Identity.Version < p.Identity.Version)
                {
                    latestPackage = p;
                }
            }

            return(latestPackage);
        }
示例#16
0
        /// <summary>
        /// Query source repository for latest package base given package id
        /// </summary>
        public static async Task <UIPackageMetadata> GetLatestPackageById(this SourceRepository srcRepo, string packageId, bool includePrerelease = true, bool includeUnlisted = false)
        {
            UIPackageMetadata latestPackage = null;
            var metadataResource            = await srcRepo.GetResourceAndValidateAsync <UIMetadataResource>();

            IEnumerable <UIPackageMetadata> packages = await metadataResource.GetMetadata(packageId, includePrerelease, includeUnlisted, token : CancellationToken.None);

            foreach (var p in packages)
            {
                if (latestPackage == null ||
                    latestPackage.Identity.Version < p.Identity.Version)
                {
                    latestPackage = p;
                }
            }

            return(latestPackage);
        }
 public DetailedPackageMetadata(UIPackageMetadata serverData, int downloadCount)
 {
     Version         = serverData.Identity.Version;
     Summary         = serverData.Summary;
     Description     = serverData.Description;
     Authors         = serverData.Authors;
     Owners          = serverData.Owners;
     IconUrl         = serverData.IconUrl;
     LicenseUrl      = serverData.LicenseUrl;
     ProjectUrl      = serverData.ProjectUrl;
     ReportAbuseUrl  = serverData.ReportAbuseUrl;
     Tags            = serverData.Tags;
     DownloadCount   = downloadCount;
     Published       = serverData.Published;
     DependencySets  = serverData.DependencySets.Select(e => new PackageDependencySetMetadata(e));
     HasDependencies = DependencySets.Any(
         dependencySet => dependencySet.Dependencies != null && dependencySet.Dependencies.Count > 0);
 }
示例#18
0
        public async Task TestVisualStudioUIMetadataResource(string SourceUrl)
        {
            SourceRepository   repo     = GetSourceRepository(SourceUrl);
            UIMetadataResource resource = repo.GetResource <UIMetadataResource>();

            Assert.True(resource != null);
            var result = await resource.GetMetadata("Microsoft.AspNet.Razor", true, true, CancellationToken.None);

            UIPackageMetadata packageMetadata = result.FirstOrDefault(
                p => p.Identity.Version == new NuGetVersion("4.0.0-beta1"));

            Assert.True(packageMetadata.DependencySets.Count() == 1);
            Assert.True(packageMetadata.DependencySets.First().Packages.Count().Equals(12));

            IEnumerable <UIPackageMetadata> packageMetadataList = resource.GetMetadata("Nuget.core", true, true, CancellationToken.None).Result;

            Assert.True(packageMetadataList != null);
            Assert.Equal(47, packageMetadataList.Count());
        }
示例#19
0
        public async Task <SiteExtensionInfo> GetLocalExtension(string id, bool checkLatest = true)
        {
            ITracer           tracer = _traceFactory.GetTracer();
            SiteExtensionInfo info   = GetPreInstalledExtension(id);

            if (info != null && info.ExtensionUrl != null)
            {
                tracer.Trace("Pre-installed site extension found: {0}", id);
                return(info);
            }

            UIPackageMetadata package = await _localRepository.GetLatestPackageById(id);

            if (package == null)
            {
                tracer.Trace("No package found from local repo with id: {0}.", id);
                return(null);
            }

            return(await ConvertLocalPackageToSiteExtensionInfo(package, checkLatest));
        }
示例#20
0
        private async Task <SiteExtensionInfo> CheckRemotePackageLatestVersion(SiteExtensionInfo info, UIMetadataResource metadataResource)
        {
            bool isNuGetPackage = false;

            if (!string.IsNullOrEmpty(info.FeedUrl))
            {
                isNuGetPackage = FeedExtensions.IsNuGetRepo(info.FeedUrl);
            }

            UIPackageMetadata localPackage = await metadataResource.GetLatestPackageByIdFromMetaRes(info.Id,
                                                                                                    explicitTag : isNuGetPackage);

            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);
        }
示例#21
0
        /// <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, string version, string feedUrl, string installationArgs)
        {
            JsonSettings siteExtensionSettings        = GetSettingManager(id);
            string       localPackageVersion          = siteExtensionSettings.GetValue(_versionSetting);
            string       localPackageFeedUrl          = siteExtensionSettings.GetValue(_feedUrlSetting);
            string       localPackageInstallationArgs = siteExtensionSettings.GetValue(_installationArgs);
            bool         isInstalled = false;

            // 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);
            }

            // Try to use given feed
            // If given feed is null, try with feed that from local package
            // And GetRemoteRepository will fallback to use default feed if pass in feed param is null
            SourceRepository remoteRepo = GetRemoteRepository(feedUrl ?? localPackageFeedUrl);

            // case 1 and 2
            if (!string.IsNullOrWhiteSpace(version) &&
                version.Equals(localPackageVersion, StringComparison.OrdinalIgnoreCase) &&
                remoteRepo.PackageSource.Source.Equals(localPackageFeedUrl, StringComparison.OrdinalIgnoreCase))
            {
                isInstalled = true;
            }
            else if (string.IsNullOrWhiteSpace(version) && string.IsNullOrWhiteSpace(feedUrl))
            {
                // case 3
                UIPackageMetadata remotePackage = await remoteRepo.GetLatestPackageByIdFromSrcRepo(id);

                if (remotePackage != null)
                {
                    isInstalled = remotePackage.Identity.Version.ToNormalizedString().Equals(localPackageVersion, StringComparison.OrdinalIgnoreCase) && string.Equals(localPackageInstallationArgs, installationArgs);
                }
            }

            return(isInstalled);
        }
示例#22
0
        public async Task <SiteExtensionInfo> GetRemoteExtension(string id, string version, string feedUrl)
        {
            ITracer tracer = _traceFactory.GetTracer();

            SiteExtensionInfo info = GetPreInstalledExtension(id);

            if (info != null)
            {
                return(info);
            }

            SourceRepository  remoteRepo = GetRemoteRepository(feedUrl);
            UIPackageMetadata package    = null;

            if (string.IsNullOrWhiteSpace(version))
            {
                using (tracer.Step("Version is null, search latest package by id: {0}", id))
                {
                    package = await remoteRepo.GetLatestPackageById(id);
                }
            }
            else
            {
                using (tracer.Step("Search package by id: {0} and version: {1}", id, version))
                {
                    package = await remoteRepo.GetPackageByIdentity(id, version);
                }
            }

            if (package == null)
            {
                tracer.Trace("No package found with id: {0} and version: {1}", id, version);
                return(null);
            }

            return(await ConvertRemotePackageToSiteExtensionInfo(package, feedUrl));
        }
示例#23
0
        // can be called concurrently if metaDataResource is provided
        internal static async Task <UIPackageMetadata> GetLatestPackageByIdFromMetaRes(this UIMetadataResource metadataResource, string packageId, bool includePrerelease = true, bool includeUnlisted = false)
        {
            UIPackageMetadata latestPackage          = null;
            IEnumerable <UIPackageMetadata> packages = await metadataResource.GetMetadata(packageId, includePrerelease, includeUnlisted, token : CancellationToken.None);

            foreach (var p in packages)
            {
                if (latestPackage == null ||
                    latestPackage.Identity.Version < p.Identity.Version)
                {
                    latestPackage = p;
                }
            }

            // If we couldn't find any listed version, fall back to looking for unlisted versions, to avoid failing completely.
            // Reasoning is that if all the versions have been unlisted, it should still be possible to install it by
            // explicit id, even without specifying a version
            if (latestPackage == null && !includeUnlisted)
            {
                latestPackage = await GetLatestPackageByIdFromMetaRes(metadataResource, packageId, includePrerelease, includeUnlisted : true);
            }

            return(latestPackage);
        }
 private async Task<SiteExtensionInfo> ConvertRemotePackageToSiteExtensionInfo(UIPackageMetadata package, string feedUrl)
 {
     return await CheckRemotePackageLatestVersion(new SiteExtensionInfo(package), feedUrl);
 }
        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;
        }
        /// <summary>
        /// <para>1. Download package</para>
        /// <para>2. Generate xdt file if not exist</para>
        /// <para>3. Deploy site extension job</para>
        /// <para>4. Execute install.cmd if exist</para>
        /// </summary>
        private async Task<UIPackageMetadata> InstallExtension(UIPackageMetadata package, string installationDirectory, string feedUrl)
        {
            ITracer tracer = _traceFactory.GetTracer();

            try
            {
                if (FileSystemHelpers.DirectoryExists(installationDirectory))
                {
                    FileSystemHelpers.DeleteDirectorySafe(installationDirectory);
                }

                SourceRepository remoteRepo = GetRemoteRepository(feedUrl);

                // Copy content folder
                // Copy nupkg file for package list/lookup
                FileSystemHelpers.CreateDirectory(installationDirectory);
                // package path from local repo
                string packageLocalFilePath = GetNuGetPackageFile(package.Identity.Id, package.Identity.Version.ToString());
                using (tracer.Step("Download site extension: {0}", package.Identity))
                {
                    await remoteRepo.DownloadPackageToFolder(package.Identity, installationDirectory, pathToLocalCopyOfNudpk: packageLocalFilePath);
                }

                // If there is no xdt file, generate default.
                using (tracer.Step("Check if applicationhost.xdt file existed."))
                {
                    GenerateApplicationHostXdt(installationDirectory, '/' + package.Identity.Id, isPreInstalled: false, tracer: tracer);
                }

                using (tracer.Step("Trigger site extension job"))
                {
                    OperationManager.Attempt(() => DeploySiteExtensionJobs(package.Identity.Id));
                }

                var externalCommandFactory = new ExternalCommandFactory(_environment, _settings, installationDirectory);
                string installScript = Path.Combine(installationDirectory, _installScriptName);
                if (FileSystemHelpers.FileExists(installScript))
                {
                    using (tracer.Step("Execute install.cmd"))
                    {
                        OperationManager.Attempt(() =>
                        {
                            Executable exe = externalCommandFactory.BuildCommandExecutable(installScript,
                                installationDirectory,
                                _settings.GetCommandIdleTimeout(), NullLogger.Instance);
                            exe.ExecuteWithProgressWriter(NullLogger.Instance, _traceFactory.GetTracer(), String.Empty);
                        });
                    }
                }
            }
            catch (Exception ex)
            {
                tracer.TraceError(ex);
                FileSystemHelpers.DeleteDirectorySafe(installationDirectory);
                throw;
            }

            return await _localRepository.GetLatestPackageById(package.Identity.Id);
        }
        /// <summary>
        /// <para>1. Download package</para>
        /// <para>2. Generate xdt file if not exist</para>
        /// <para>3. Deploy site extension job</para>
        /// <para>4. Execute install.cmd if exist</para>
        /// </summary>
        private async Task<UIPackageMetadata> InstallExtension(UIPackageMetadata package, string installationDirectory, string feedUrl, SiteExtensionInfo.SiteExtensionType type, ITracer tracer)
        {
            try
            {
                EnsureInstallationEnviroment(installationDirectory, tracer);

                string packageLocalFilePath = GetNuGetPackageFile(package.Identity.Id, package.Identity.Version.ToNormalizedString());
                bool packageExisted = FileSystemHelpers.DirectoryExists(installationDirectory);
                SourceRepository remoteRepo = GetRemoteRepository(feedUrl);

                using (tracer.Step("Download site extension: {0}", package.Identity))
                {
                    string extractPath = installationDirectory;
                    if (SiteExtensionInfo.SiteExtensionType.WebRoot == type)
                    {
                        extractPath = _environment.WebRootPath;
                        FileSystemHelpers.EnsureDirectory(extractPath);
                    }

                    // Copy/update content folder
                    // Copy/update nupkg file for package list/lookup
                    if (packageExisted)
                    {
                        await remoteRepo.UpdateLocalPackage(_localRepository, package.Identity, extractPath, packageLocalFilePath, tracer);
                    }
                    else
                    {
                        FileSystemHelpers.EnsureDirectory(installationDirectory);
                        await remoteRepo.DownloadPackageToFolder(package.Identity, extractPath, packageLocalFilePath);
                    }

                    if (SiteExtensionInfo.SiteExtensionType.WebRoot == type)
                    {
                        // if install to WebRoot, check if there is any xdt file come with package
                        // if there is one, move it to site extension folder
                        string xdtFile = Path.Combine(extractPath, Constants.ApplicationHostXdtFileName);
                        if (File.Exists(xdtFile))
                        {
                            tracer.Trace("Use xdt file from package.");
                            string newXdtFile = Path.Combine(installationDirectory, Constants.ApplicationHostXdtFileName);

                            tracer.Trace("Moving {0} to {1}", xdtFile, newXdtFile);
                            FileSystemHelpers.MoveFile(xdtFile, newXdtFile);
                        }
                        else
                        {
                            tracer.Trace("No xdt file come with package.");
                        }
                    }
                }

                // ignore below action if we install packge to wwwroot
                if (SiteExtensionInfo.SiteExtensionType.WebRoot != type)
                {
                    // If there is no xdt file, generate default.
                    using (tracer.Step("Check if applicationhost.xdt file existed."))
                    {
                        GenerateApplicationHostXdt(installationDirectory, '/' + package.Identity.Id, isPreInstalled: false, tracer: tracer);
                    }

                    using (tracer.Step("Trigger site extension job"))
                    {
                        OperationManager.Attempt(() => DeploySiteExtensionJobs(package.Identity.Id));
                    }

                    var externalCommandFactory = new ExternalCommandFactory(_environment, _settings, installationDirectory);
                    string installScript = Path.Combine(installationDirectory, _installScriptName);
                    if (FileSystemHelpers.FileExists(installScript))
                    {
                        using (tracer.Step("Execute install.cmd"))
                        {
                            OperationManager.Attempt(() =>
                            {
                                Executable exe = externalCommandFactory.BuildCommandExecutable(installScript,
                                    installationDirectory,
                                    _settings.GetCommandIdleTimeout(), NullLogger.Instance);
                                exe.ExecuteWithProgressWriter(NullLogger.Instance, _traceFactory.GetTracer(), String.Empty);
                            });
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                tracer.TraceError(ex);
                FileSystemHelpers.DeleteDirectorySafe(installationDirectory);
                throw;
            }

            return await _localRepository.GetLatestPackageById(package.Identity.Id);
        }
示例#28
0
        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);
        }
        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;
        }
示例#30
0
        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));
        }
示例#31
0
        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);
        }
示例#32
0
        /// <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, string version, string feedUrl, string installationArgs)
        {
            ITracer      tracer = _traceFactory.GetTracer();
            JsonSettings siteExtensionSettings        = GetSettingManager(id);
            string       localPackageVersion          = siteExtensionSettings.GetValue(_versionSetting);
            string       localPackageFeedUrl          = siteExtensionSettings.GetValue(_feedUrlSetting);
            string       localPackageInstallationArgs = siteExtensionSettings.GetValue(_installationArgs);
            NuGetVersion localPkgVer  = null;
            NuGetVersion lastFoundVer = null;
            bool         isInstalled  = false;

            // 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))
            {
                localPkgVer = NuGetVersion.Parse(localPackageVersion);
            }

            // Try to use given feed
            // If given feed is null, try with feed that from local package
            // And GetRemoteRepositories will fallback to use default feed if pass in feed param is null
            IEnumerable <SourceRepository> remoteRepos = GetRemoteRepositories(feedUrl ?? localPackageFeedUrl);

            foreach (SourceRepository rr in remoteRepos)
            {
                // case 1 and 2
                if (!string.IsNullOrWhiteSpace(version) &&
                    version.Equals(localPackageVersion, StringComparison.OrdinalIgnoreCase) &&
                    rr.PackageSource.Source.Equals(localPackageFeedUrl, StringComparison.OrdinalIgnoreCase))
                {
                    isInstalled = true;
                }
                else if (string.IsNullOrWhiteSpace(version) &&
                         string.IsNullOrWhiteSpace(feedUrl) &&
                         string.Equals(localPackageInstallationArgs, installationArgs))
                {
                    // case 3
                    UIPackageMetadata remotePackage = await rr.GetLatestPackageByIdFromSrcRepo(id);

                    if (remotePackage != null)
                    {
                        tracer.Trace("Found version: {0} on feed: {1}",
                                     remotePackage.Identity.Version.ToNormalizedString(),
                                     rr.PackageSource.Source);
                        if (lastFoundVer == null || lastFoundVer < remotePackage.Identity.Version)
                        {
                            lastFoundVer = remotePackage.Identity.Version;
                        }
                    }
                }
            }

            if (lastFoundVer != null && localPkgVer != null && lastFoundVer <= localPkgVer)
            {
                isInstalled = true;
            }

            return(isInstalled);
        }
示例#33
0
        /// <summary>
        /// <para>1. Download package</para>
        /// <para>2. Generate xdt file if not exist</para>
        /// <para>3. Deploy site extension job</para>
        /// <para>4. Execute install.cmd if exist</para>
        /// </summary>
        private async Task <UIPackageMetadata> InstallExtension(UIPackageMetadata package, string installationDirectory, SourceRepository remoteRepo, SiteExtensionInfo.SiteExtensionType type, ITracer tracer, string installationArgs)
        {
            try
            {
                EnsureInstallationEnviroment(installationDirectory, tracer);

                string packageLocalFilePath = GetNuGetPackageFile(package.Identity.Id, package.Identity.Version.ToNormalizedString());
                bool   packageExisted       = FileSystemHelpers.DirectoryExists(installationDirectory);

                using (tracer.Step("Download site extension: {0}", package.Identity))
                {
                    string extractPath = installationDirectory;
                    if (SiteExtensionInfo.SiteExtensionType.WebRoot == type)
                    {
                        extractPath = _environment.WebRootPath;
                        FileSystemHelpers.EnsureDirectory(extractPath);
                    }

                    // Copy/update content folder
                    // Copy/update nupkg file for package list/lookup
                    if (packageExisted)
                    {
                        await remoteRepo.UpdateLocalPackage(_localRepository, package.Identity, extractPath, packageLocalFilePath, tracer);
                    }
                    else
                    {
                        FileSystemHelpers.EnsureDirectory(installationDirectory);
                        await remoteRepo.DownloadPackageToFolder(package.Identity, extractPath, packageLocalFilePath);
                    }

                    if (SiteExtensionInfo.SiteExtensionType.WebRoot == type)
                    {
                        // if install to WebRoot, check if there is any xdt or scmXdt file come with package
                        // if there is, move it to site extension folder
                        string xdtFile    = Path.Combine(extractPath, Constants.ApplicationHostXdtFileName);
                        string scmXdtFile = Path.Combine(extractPath, Constants.ScmApplicationHostXdtFileName);
                        bool   findXdts   = false;

                        if (FileSystemHelpers.FileExists(xdtFile))
                        {
                            tracer.Trace("Use xdt file from package.");
                            string newXdtFile = Path.Combine(installationDirectory, Constants.ApplicationHostXdtFileName);

                            tracer.Trace("Moving {0} to {1}", xdtFile, newXdtFile);
                            FileSystemHelpers.MoveFile(xdtFile, newXdtFile);
                            findXdts = true;
                        }
                        // if the siteextension applies to both main site and the scm site
                        if (FileSystemHelpers.FileExists(scmXdtFile))
                        {
                            tracer.Trace("Use scmXdt file from package.");
                            string newScmXdtFile = Path.Combine(installationDirectory, Constants.ScmApplicationHostXdtFileName);

                            tracer.Trace("Moving {0} to {1}", scmXdtFile, newScmXdtFile);
                            FileSystemHelpers.MoveFile(scmXdtFile, newScmXdtFile);
                            findXdts = true;
                        }

                        if (!findXdts)
                        {
                            tracer.Trace("No xdt file come with package.");
                        }
                    }
                }

                // ignore below action if we install packge to wwwroot
                if (SiteExtensionInfo.SiteExtensionType.WebRoot != type)
                {
                    using (tracer.Step("Check if applicationHost.xdt or scmApplicationHost.xdt file existed."))
                    {
                        GenerateDefaultScmApplicationHostXdt(installationDirectory, '/' + package.Identity.Id, tracer: tracer);
                    }

                    using (tracer.Step("Trigger site extension job"))
                    {
                        OperationManager.Attempt(() => DeploySiteExtensionJobs(package.Identity.Id));
                    }

                    var    externalCommandFactory = new ExternalCommandFactory(_environment, _settings, installationDirectory);
                    string installScript          = Path.Combine(installationDirectory, _installScriptName);
                    if (FileSystemHelpers.FileExists(installScript))
                    {
                        using (tracer.Step("Execute install.cmd"))
                        {
                            OperationManager.Attempt(() =>
                            {
                                Executable exe = externalCommandFactory.BuildCommandExecutable(installScript,
                                                                                               installationDirectory,
                                                                                               _settings.GetCommandIdleTimeout(), NullLogger.Instance);
                                exe.ExecuteWithProgressWriter(NullLogger.Instance, _traceFactory.GetTracer(), installationArgs ?? String.Empty);
                            });
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                tracer.TraceError(ex);
                FileSystemHelpers.DeleteDirectorySafe(installationDirectory);
                throw;
            }

            return(await _localRepository.GetLatestPackageByIdFromSrcRepo(package.Identity.Id));
        }
示例#34
0
        private async Task <SiteExtensionInfo> TryInstallExtension(string id, string version, string feedUrl, SiteExtensionInfo.SiteExtensionType type, ITracer tracer, string installationArgs)
        {
            SiteExtensionInfo info   = null;
            HttpStatusCode    status = HttpStatusCode.OK; // final status when success
            bool alreadyInstalled    = false;

            try
            {
                // Check if site extension already installed (id, version, feedUrl), if already install with correct installation arguments then return right away
                if (await this.IsSiteExtensionInstalled(id, version, feedUrl, installationArgs))
                {
                    // package already installed, return package from local repo.
                    tracer.Trace("Package {0} with version {1} from {2} with installation arguments '{3}' already installed.", id, version, feedUrl, installationArgs);
                    info = await GetLocalExtension(id);

                    alreadyInstalled = true;
                }
                else
                {
                    JsonSettings siteExtensionSettings = GetSettingManager(id);
                    feedUrl = (string.IsNullOrEmpty(feedUrl) ? siteExtensionSettings.GetValue(_feedUrlSetting) : feedUrl);
                    IEnumerable <SourceRepository> remoteRepos = GetRemoteRepositories(feedUrl);
                    UIPackageMetadata localPackage             = null;
                    UIPackageMetadata repoPackage = null;
                    SourceRepository  remoteRepo  = null;

                    if (this.IsInstalledToWebRoot(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
                        type = SiteExtensionInfo.SiteExtensionType.WebRoot;
                    }

                    if (string.IsNullOrWhiteSpace(version))
                    {
                        using (tracer.Step("Version is null, search latest package by id: {0}, will not search for unlisted package.", id))
                        {
                            foreach (SourceRepository rr in remoteRepos)
                            {
                                repoPackage = await rr.GetLatestPackageByIdFromSrcRepo(id);

                                if (repoPackage != null)
                                {
                                    remoteRepo = rr;
                                    break;
                                }
                            }
                        }
                    }
                    else
                    {
                        using (tracer.Step("Search package by id: {0} and version: {1}, will also search for unlisted package.", id, version))
                        {
                            foreach (SourceRepository rr in remoteRepos)
                            {
                                repoPackage = await rr.GetPackageByIdentity(id, version);

                                if (repoPackage != null)
                                {
                                    remoteRepo = rr;
                                    break;
                                }
                            }
                        }
                    }

                    if (repoPackage != null)
                    {
                        Debug.Assert(remoteRepo != null, "remote SourceRepository should not be null!");
                        using (tracer.Step("Install package: {0}.", id))
                        {
                            string installationDirectory = GetInstallationDirectory(id);
                            localPackage = await InstallExtension(repoPackage, installationDirectory, remoteRepo, type, tracer, installationArgs);

                            siteExtensionSettings.SetValues(new KeyValuePair <string, JToken>[] {
                                new KeyValuePair <string, JToken>(_versionSetting, localPackage.Identity.Version.ToNormalizedString()),
                                new KeyValuePair <string, JToken>(_feedUrlSetting, feedUrl),
                                new KeyValuePair <string, JToken>(_installUtcTimestampSetting, DateTime.UtcNow.ToString("u")),
                                new KeyValuePair <string, JToken>(_packageType, Enum.GetName(typeof(SiteExtensionInfo.SiteExtensionType), type)),
                                new KeyValuePair <string, JToken>(_installationArgs, installationArgs)
                            });
                        }
                    }

                    info = await ConvertLocalPackageToSiteExtensionInfo(localPackage, checkLatest : true, tracer : tracer);
                }
            }
            catch (FileNotFoundException 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);

                tracer.TraceError(ex);
                info    = new SiteExtensionInfo();
                info.Id = id;
                info.ProvisioningState = Constants.SiteExtensionProvisioningStateFailed;
                info.Comment           = ex.ToString();
                status = HttpStatusCode.NotFound;
            }
            catch (WebException 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);

                tracer.TraceError(ex);
                info    = new SiteExtensionInfo();
                info.Id = id;
                info.ProvisioningState = Constants.SiteExtensionProvisioningStateFailed;
                info.Comment           = ex.ToString();
                status = HttpStatusCode.BadRequest;
            }
            catch (InvalidEndpointException ex)
            {
                _analytics.UnexpectedException(ex, trace: false);

                tracer.TraceError(ex);
                info    = new SiteExtensionInfo();
                info.Id = id;
                info.ProvisioningState = Constants.SiteExtensionProvisioningStateFailed;
                info.Comment           = ex.ToString();
                status = HttpStatusCode.BadRequest;
            }
            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);

                tracer.TraceError(ex);
                info    = new SiteExtensionInfo();
                info.Id = id;
                info.ProvisioningState = Constants.SiteExtensionProvisioningStateFailed;
                info.Comment           = ex.ToString();
                status = HttpStatusCode.BadRequest;
            }

            if (info == null)
            {
                // treat this as an error case since no result return from repo
                _analytics.UnexpectedException(
                    new FileNotFoundException(id),
                    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);

                info = new SiteExtensionInfo();
                info.ProvisioningState = Constants.SiteExtensionProvisioningStateFailed;
                info.Comment           = string.Format(Constants.SiteExtensionProvisioningStateNotFoundMessageFormat, id);
                status = HttpStatusCode.NotFound;
            }
            else if (!string.Equals(Constants.SiteExtensionProvisioningStateFailed, info.ProvisioningState, StringComparison.OrdinalIgnoreCase))
            {
                info.ProvisioningState = Constants.SiteExtensionProvisioningStateSucceeded;
                info.Comment           = null;
            }

            using (tracer.Step("Update arm settings for {0} installation. Status: {1}", id, status))
            {
                SiteExtensionStatus armSettings = new SiteExtensionStatus(_environment.SiteExtensionSettingsPath, id, tracer);
                armSettings.ReadSiteExtensionInfo(info);
                armSettings.Status    = status;
                armSettings.Operation = alreadyInstalled ? null : Constants.SiteExtensionOperationInstall;
            }

            return(info);
        }
示例#35
0
        private async Task <SiteExtensionInfo> TryInstallExtension(string id, string version, string feedUrl, SiteExtensionInfo.SiteExtensionType type, ITracer tracer)
        {
            SiteExtensionInfo info   = null;
            HttpStatusCode    status = HttpStatusCode.OK; // final status when success
            bool alreadyInstalled    = false;

            if (_preInstalledExtensionDictionary.ContainsKey(id))
            {
                tracer.Trace("Pre-installed site extension found: {0}, not going to perform new installation.", id);
                info             = EnablePreInstalledExtension(_preInstalledExtensionDictionary[id], tracer);
                alreadyInstalled = true;
            }
            else
            {
                try
                {
                    // Check if site extension already installed (id, version, feedUrl), if already install return right away
                    if (await this.IsSiteExtensionInstalled(id, version, feedUrl))
                    {
                        // package already installed, return package from local repo.
                        tracer.Trace("Package {0} with version {1} from {2} already installed.", id, version, feedUrl);
                        info = await GetLocalExtension(id);

                        alreadyInstalled = true;
                    }
                    else
                    {
                        JsonSettings siteExtensionSettings = GetSettingManager(id);
                        feedUrl = (string.IsNullOrEmpty(feedUrl) ? siteExtensionSettings.GetValue(_feedUrlSetting) : feedUrl);
                        SourceRepository  remoteRepo   = GetRemoteRepository(feedUrl);
                        UIPackageMetadata localPackage = null;
                        UIPackageMetadata repoPackage  = null;

                        if (string.IsNullOrWhiteSpace(version))
                        {
                            using (tracer.Step("Version is null, search latest package by id: {0}, will not search for unlisted package.", id))
                            {
                                repoPackage = await remoteRepo.GetLatestPackageById(id);
                            }
                        }
                        else
                        {
                            using (tracer.Step("Search package by id: {0} and version: {1}, will also search for unlisted package.", id, version))
                            {
                                repoPackage = await remoteRepo.GetPackageByIdentity(id, version);
                            }
                        }

                        if (repoPackage != null)
                        {
                            using (tracer.Step("Install package: {0}.", id))
                            {
                                string installationDirectory = GetInstallationDirectory(id);
                                localPackage = await InstallExtension(repoPackage, installationDirectory, feedUrl, type, tracer);

                                siteExtensionSettings.SetValues(new KeyValuePair <string, JToken>[] {
                                    new KeyValuePair <string, JToken>(_versionSetting, localPackage.Identity.Version.ToNormalizedString()),
                                    new KeyValuePair <string, JToken>(_feedUrlSetting, feedUrl),
                                    new KeyValuePair <string, JToken>(_installUtcTimestampSetting, DateTime.UtcNow.ToString("u")),
                                    new KeyValuePair <string, JToken>(_packageType, Enum.GetName(typeof(SiteExtensionInfo.SiteExtensionType), type))
                                });
                            }
                        }

                        info = await ConvertLocalPackageToSiteExtensionInfo(localPackage, checkLatest : true, tracer : tracer);
                    }
                }
                catch (FileNotFoundException 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);

                    tracer.TraceError(ex);
                    info    = new SiteExtensionInfo();
                    info.Id = id;
                    info.ProvisioningState = Constants.SiteExtensionProvisioningStateFailed;
                    info.Comment           = string.Format(Constants.SiteExtensionProvisioningStateNotFoundMessageFormat, id);
                    status = HttpStatusCode.NotFound;
                }
                catch (WebException 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);

                    tracer.TraceError(ex);
                    info    = new SiteExtensionInfo();
                    info.Id = id;
                    info.ProvisioningState = Constants.SiteExtensionProvisioningStateFailed;
                    info.Comment           = string.Format(Constants.SiteExtensionProvisioningStateDownloadFailureMessageFormat, id);
                    status = HttpStatusCode.BadRequest;
                }
                catch (InvalidEndpointException ex)
                {
                    _analytics.UnexpectedException(ex, trace: false);

                    tracer.TraceError(ex);
                    info    = new SiteExtensionInfo();
                    info.Id = id;
                    info.ProvisioningState = Constants.SiteExtensionProvisioningStateFailed;
                    info.Comment           = ex.Message;
                    status = HttpStatusCode.BadRequest;
                }
                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);

                    tracer.TraceError(ex);
                    info    = new SiteExtensionInfo();
                    info.Id = id;
                    info.ProvisioningState = Constants.SiteExtensionProvisioningStateFailed;
                    info.Comment           = string.Format(Constants.SiteExtensionProvisioningStateInvalidPackageMessageFormat, id);
                    status = HttpStatusCode.BadRequest;
                }
            }

            if (info == null)
            {
                // treat this as an error case since no result return from repo
                _analytics.UnexpectedException(
                    new FileNotFoundException(id),
                    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);

                info = new SiteExtensionInfo();
                info.ProvisioningState = Constants.SiteExtensionProvisioningStateFailed;
                info.Comment           = string.Format(Constants.SiteExtensionProvisioningStateNotFoundMessageFormat, id);
                status = HttpStatusCode.NotFound;
            }
            else if (!string.Equals(Constants.SiteExtensionProvisioningStateFailed, info.ProvisioningState, StringComparison.OrdinalIgnoreCase))
            {
                info.ProvisioningState = Constants.SiteExtensionProvisioningStateSucceeded;
                info.Comment           = null;
            }

            using (tracer.Step("Update arm settings for {0} installation. Status: {1}", id, status))
            {
                SiteExtensionStatus armSettings = new SiteExtensionStatus(_environment.SiteExtensionSettingsPath, id, tracer);
                armSettings.ReadSiteExtensionInfo(info);
                armSettings.Status    = status;
                armSettings.Operation = alreadyInstalled ? null : Constants.SiteExtensionOperationInstall;
            }

            return(info);
        }
示例#36
0
 private async Task <SiteExtensionInfo> ConvertRemotePackageToSiteExtensionInfo(UIPackageMetadata package, string feedUrl)
 {
     return(await CheckRemotePackageLatestVersion(new SiteExtensionInfo(package), feedUrl));
 }