Exemple #1
0
        /// <summary>
        /// Get's a shared directory that will be used to store the ACME challenge responses
        /// </summary>
        /// <returns></returns>
        public string GetWellKnownSharedPathForApplication()
        {
            var result = Path.Combine(this.GetAcmeTemporarySiteRootForApplication(), ".well-known");

            UtilsSystem.DirectoryCreateIfNotExists(result);
            return(result);
        }
Exemple #2
0
        /// <summary>
        /// Execute the opreation...
        /// </summary>
        public void execute(IniFileManager manager, Deployment deployment)
        {
            var val = deployment.ExpandPaths(this.value);

            switch (this.ensureDir)
            {
            case "dir":
                UtilsSystem.EnsureDirectoryExists(val, true);
                break;

            case "file":
                UtilsSystem.EnsureDirectoryExists(val, false);
                break;
            }

            // If this is a directory or file, make sure we properly quote when
            // writting the PHP.ini, because whitespaces in a path will break
            // most settings
            if (this.ensureDir == "dir" || this.ensureDir == "file")
            {
                if (!val.StartsWith("\""))
                {
                    val = "\"" + val + "\"";
                }
            }

            if (this.multivalue)
            {
                manager.UpdateOrCreateMultivalueDirective(this.key, val, this.section ?? "AUTODEPLOY", this.comment, this.host);
            }
            else
            {
                manager.UpdateOrCreateDirective(this.key, val, this.section ?? "AUTODEPLOY", this.comment, this.host);
            }
        }
Exemple #3
0
        /// <summary>
        /// Grab from a settings file.
        /// </summary>
        /// <param name="path"></param>
        /// <param name="logger"></param>
        public void PopulateFromSettingsFile(string path, ILoggerInterface logger)
        {
            string file = UtilsSystem.CombinePaths(path, "artifact-settings.yml");

            if (!File.Exists(file))
            {
                return;
            }

            var configfile = new Configuration.YamlConfigurationFile();

            try
            {
                // This file might be malformed, do not crash and let other
                // environment information sources have their chance
                configfile.ParseFromFile(file);
            }
            catch (Exception e)
            {
                logger.LogException(new Exception("Error parsing file: " + file, e));
                return;
            }

            // Parse the artifact settings...
            this.branch     = configfile.GetStringValue("repo-branch", null);
            this.commit_sha = configfile.GetStringValue("repo-commit", null);
            this.version    = configfile.GetStringValue("build-id", null);
        }
        public void undeploy(bool isUninstall = false)
        {
            // Not that we want to accidentally delete contents and files
            // for an application...
            if (!isUninstall)
            {
                return;
            }

            var diskSettings = this.DeployerSettings.castTo <DiskServiceSettings>();
            var mounts       = this.Deployment.GetSettingCollection <DiskStore>($"service.{diskSettings.id}");

            foreach (var m in mounts.Values)
            {
                // Most of the time this directory will not exist, as the base storage deployer will already have
                // deleted the application folder. But for "local" installed applications, this removes
                // the symlinks.
                if (!string.IsNullOrWhiteSpace(m.junctionRealPath) && Directory.Exists(m.junctionRealPath))
                {
                    UtilsJunction.RemoveJunction(m.junctionRealPath);
                }

                if (Directory.Exists(m.path))
                {
                    UtilsSystem.DeleteDirectory(m.path, this.Logger);
                }
            }

            var baseStoragePath = this.GetStoragePath(diskSettings);

            if (!string.IsNullOrWhiteSpace(baseStoragePath) && Directory.Exists(baseStoragePath))
            {
                UtilsSystem.DeleteDirectory(baseStoragePath, this.Logger);
            }
        }
Exemple #5
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="dir"></param>
        public void CleanUpDir(string dir)
        {
            if (!Directory.Exists(dir))
            {
                return;
            }

            foreach (var difo in new DirectoryInfo(dir).EnumerateDirectories())
            {
                foreach (var appDifo in difo.EnumerateDirectories())
                {
                    try
                    {
                        // Delete folders older than 1 month
                        if ((DateTime.Now - appDifo.LastWriteTime).TotalDays > 30)
                        {
                            UtilsSystem.DeleteDirectory(appDifo.FullName, this.Logger);
                            this.Logger.LogInfo(true, "Deleted temp dir: {0}", appDifo.FullName);
                        }
                    }
                    catch (Exception e)
                    {
                        this.Logger.LogException(e);
                    }
                }
            }
        }
        /// <summary>
        /// Get a deployer for the installed application.
        /// </summary>
        /// <param name="globalSettings">The global settings.</param>
        /// <param name="installedApplicationSettings">The installed application settings.</param>
        /// <param name="logger">The logger.</param>
        public ApplicationDeployer(
            EnvironmentSettings globalSettings,
            InstalledApplication installedApplicationSettings,
            ILoggerInterface logger)
        {
            this.GlobalSettings       = globalSettings;
            this.installedAppSettings = installedApplicationSettings;
            this.Logger = logger;

            if (this.GlobalSettings == null)
            {
                throw new InvalidDataException("settings argument cannot be null.");
            }

            if (this.installedAppSettings == null)
            {
                throw new Exception("installedApplicationSettings argument cannot be null.");
            }

            // Try to grab previous deployment...
            this.activeDeploymentPathStorage = UtilsSystem.CombinePaths(globalSettings.activeDeploymentDir, "active." + this.installedAppSettings.GetId() + ".json");

            if (File.Exists(this.activeDeploymentPathStorage))
            {
                this.DeploymentActive = Deployment.InstanceFromPath(this.activeDeploymentPathStorage, globalSettings);
            }
        }
Exemple #7
0
        /// <summary>
        /// Get an instance of SslCertificateProviderService
        /// </summary>
        public SslCertificateProviderService(
            ILoggerInterface logger,
            string appId,
            EnvironmentSettings globalSettings,
            Deployment deployment)
        {
            this.AppPoolUtils    = new UtilsAppPool(logger);
            this.UtilsHosts      = new UtilsHosts(logger);
            this.MockEnvironment = UtilsSystem.RunningInContinuousIntegration() || UnitTestDetector.IsRunningInTests || Debugger.IsAttached;

            // Everything performed against the staging API needs to be kept apart, including signer, etc...
            this.StoragePath = Path.Combine(globalSettings.GetDefaultContentStorage().path, "letsencrypt" + (this.MockEnvironment ? "_mock" : null));
            UtilsSystem.EnsureDirectoryExists(this.StoragePath, true);

            // If CCS is available, use that, otherwise use the central content storage
            string sslRenewalStateStorePath = UtilsIis.CentralStoreEnabled()
                ? UtilsIis.CentralStorePath(logger)
                : globalSettings.GetDefaultContentStorage().path;

            this.SimpleStoreRenewalStatus = new SimpleStore(Path.Combine(sslRenewalStateStorePath, "_ssl_renewal_state_store"), true);

            this.Logger         = logger;
            this.AppId          = appId;
            this.Deployment     = deployment;
            this.GlobalSettings = globalSettings;
        }
Exemple #8
0
        /// <summary>
        /// Waits for a task to stop running (must be in disabled state)
        /// </summary>
        /// <param name="t"></param>
        /// <param name="maxWaitMilliseconds"></param>
        protected void DisableAndStopTask(Task t, int maxWaitMilliseconds = 30000)
        {
            this.Logger.LogInfo(true, "Stopping scheduler task {0} with state {1}", t.Name, t.State);

            t.Enabled = false;

            bool hasStopped = UtilsSystem.WaitWhile(
                () => t.State == TaskState.Running,
                maxWaitMilliseconds,
                $"Waiting for task {t.Name} to stop running...",
                this.Logger);

            // The task did not stop by itself, so we need to forcefully close it.
            if (!hasStopped)
            {
                this.Logger.LogInfo(true, "Forcefully stopping task {0} ", t.Name);
                t.Stop();
            }

            // Wait again
            hasStopped = UtilsSystem.WaitWhile(
                () => t.State == TaskState.Running,
                maxWaitMilliseconds,
                $"Waiting for task {t.Name} to stop...",
                this.Logger);

            if (!hasStopped)
            {
                this.Logger.LogWarning(false, "Could not stop scheduled task {0}", t.Name);
            }
        }
        /// <summary>
        /// All disk storage for this application is pointed to this directory.
        /// </summary>
        /// <param name="settings"></param>
        /// <returns></returns>
        protected string GetStoragePath(DiskServiceSettings settings)
        {
            var storage = this.GlobalSettings.GetDefaultContentStorage();

            // We can have an app_setting configuration
            // to route a whole application to a specific sql server
            string diskTarget;

            if (this.Deployment.installedApplicationSettings.configuration["disktarget"] != null)
            {
                diskTarget = Convert.ToString(this.Deployment.installedApplicationSettings.configuration["disktarget"]);
                this.Logger.LogInfo(true, "Custom disk target: " + diskTarget);

                if (!Directory.Exists(diskTarget))
                {
                    throw new Exception("Invalid custom disk target: " + diskTarget);
                }
            }
            else
            {
                // Generate a unique "virtual disk" (directory) for this application
                diskTarget = UtilsSystem.EnsureDirectoryExists(UtilsSystem.CombinePaths(
                                                                   storage.path,
                                                                   "store_" + this.Deployment.installedApplicationSettings.GetId()));
            }

            return(diskTarget);
        }
        public override void _sync(object input)
        {
            DiskService other        = (DiskService)input;
            var         diskSettings = this.DeployerSettings.castTo <DiskServiceSettings>();
            var         storage      = this.GlobalSettings.GetDefaultContentStorage();

            // Generate a unique virtual disk for this application
            DiskServiceSettings otherSettings = other.DeployerSettings.castTo <DiskServiceSettings>();

            foreach (var mount in diskSettings.mounts)
            {
                string           pathOri  = UtilsSystem.EnsureDirectoryExists(other.Deployment.GetRuntimeSettingsToDeploy()["services." + otherSettings.id + ".mount.files.path"]);
                string           pathDest = UtilsSystem.EnsureDirectoryExists(this.Deployment.GetRuntimeSettingsToDeploy()["services." + diskSettings.id + ".mount.files.path"]);
                FileSyncProvider ori      = new FileSyncProvider(pathOri);
                FileSyncProvider dest     = new FileSyncProvider(pathDest);

                SyncOrchestrator agent = new SyncOrchestrator();
                agent.LocalProvider  = ori;
                agent.RemoteProvider = dest;
                agent.Direction      = SyncDirectionOrder.Upload;

                SyncOperationStatistics syncStats = agent.Synchronize();
                this.Logger.LogInfo(
                    true,
                    "Synchronization stats \n\n local provider {0} to remote {1}\n upload changes applied {2}\n {3} upload changes failed",
                    pathOri,
                    pathDest,
                    syncStats.UploadChangesApplied,
                    syncStats.UploadChangesFailed);
                ori.Dispose();
                dest.Dispose();
            }
        }
        public void TestCdnReplacements()
        {
            var sampleHtml = File.ReadAllText(UtilsSystem.GetResourceFileAsPath("samples/samplecdn.html"));

            var replacer = new CdnHtmlRedirectHelper();

            replacer.PrependCdnToUri(sampleHtml, "https://cdnprefix/directory/");
        }
Exemple #12
0
        /// <summary>
        /// Delete the artifact's source if it is remote
        /// </summary>
        /// <param name="artifact"></param>
        /// <param name="logger"></param>
        public static void DeleteIfRemote(this Artifact artifact, ILoggerInterface logger)
        {
            if (!artifact.isRemote)
            {
                return;
            }

            UtilsSystem.DeleteDirectory(artifact.localPath, logger);
        }
        public override void beforeDone()
        {
            // We also have a canonical access to the deployed app through a symlink
            string basePath      = this.Deployment.GetSetting("appstorage.base", (string)null, this.Logger);
            string canonicalPath = UtilsSystem.CombinePaths(this.GlobalSettings.GetDefaultApplicationStorage().path, "_" + this.Deployment.installedApplicationSettings.GetId());

            UtilsJunction.EnsureLink(canonicalPath, basePath, this.Logger, false, true);
            this.Deployment.SetSetting("appstorage.canonical", canonicalPath);
        }
Exemple #14
0
        /// <summary>
        /// Run an API call and output results directly to a file
        /// mostly used to download artifacts...
        /// </summary>
        /// <param name="uri"></param>
        /// <param name="localPath"></param>
        protected void ExecuteApiCallToFile(string uri, string localPath)
        {
            UtilsSystem.EnsureDirectoryExists(localPath);

            var       url    = this.BaseUri + uri;
            WebClient client = this.PrepareWebClient(null);

            client.DownloadFile(url, localPath);
        }
        protected override void ProcessRecord()
        {
            ConsoleUtils.RunCode(() =>
            {
                var logger = new logger.ConsoleLogger();
                logger.SetVerbose(true);

                UtilsSystem.DeleteDirectory(this.Directory, logger, 30);
            });
        }
        /// <summary>
        ///
        /// </summary>
        /// <param name="settings"></param>
        protected void DeployFonts(AppBaseStorageDeployerSettings settings)
        {
            // Nada que desplegar
            if (settings.fonts?.Any() != true)
            {
                return;
            }

            // TODO: Newer windows versions allow for per-user font registration, we should implement that
            // because with this approach fonts are installed first come first-served, and cannot be updated
            // if necessary. Plus we don't know who owns a font, se we can't delete them on cleanup

            var utilsFont = new UtilsFont();

            foreach (var font in settings.fonts.AsIterable())
            {
                // Check that the provided path is a zip with the font
                var fontSourceZip = Path.Combine(this.Deployment.appPath, font.Path);

                if (Path.GetExtension(fontSourceZip) != ".zip")
                {
                    throw new Exception($"Unable to install the font '{font.Path}' because fonts have to be in a .zip file.");
                }

                if (!File.Exists(fontSourceZip))
                {
                    throw new Exception($"Font file not found '{font.Path}'.");
                }

                // We use a know directory
                var fontTempPath          = UtilsSystem.GetTempPath("font-" + Guid.NewGuid());
                var fontPersitentTempPath = UtilsSystem.GetTempPath("font-chef");

                try
                {
                    ZipFile.ExtractToDirectory(fontSourceZip, fontTempPath);
                    UtilsSystem.CopyFilesRecursively(new DirectoryInfo(fontTempPath), new DirectoryInfo(fontPersitentTempPath), true, true);
                    utilsFont.InstallFont(fontPersitentTempPath);
                }
                finally
                {
                    UtilsSystem.DeleteDirectory(fontTempPath, this.Logger, 8);

                    // This will some fonts get locked by the native API without explanation
                    try
                    {
                        UtilsSystem.DeleteDirectory(fontPersitentTempPath, this.Logger, 4);
                    }
                    catch
                    {
                        // ignored
                    }
                }
            }
        }
        /// <summary>
        /// Do not deploy applications if we are short on disk space.
        ///
        /// Throws an exception if size is below minSize
        /// </summary>
        /// <param name="minSize">Defaults to 500Mb</param>
        protected void CheckDiskSpace(long minSize = 524288000)
        {
            var applicationPath = this.GlobalSettings.GetDefaultApplicationStorage().path;

            long freeSpaceBytes = UtilsSystem.GetTotalFreeSpace(applicationPath);

            if (freeSpaceBytes < minSize)
            {
                throw new Exception($"Insuficient storage [{UtilsSystem.BytesToString(freeSpaceBytes)}] to run deployments in: {applicationPath}");
            }
        }
        public void TestSymlinksAreNotRemoved()
        {
            var logger = new TestLogsLogger(this, nameof(this.TestSymlinksAreNotRemoved));

            string testPath = UtilsSystem.GetTempPath("symlink_test" + Guid.NewGuid());

            var pathWebsite            = Path.Combine(testPath, "website");
            var pathContentsPersistent = Path.Combine(testPath, "content_store_persistent");

            Directory.CreateDirectory(pathWebsite);
            Directory.CreateDirectory(pathContentsPersistent);
            Directory.CreateDirectory(Path.Combine(pathContentsPersistent, "empty_directory"));

            string linkedDir  = Path.Combine(pathWebsite, "contents");
            string linkedDir2 = Path.Combine(pathWebsite, "contents2", "contents");

            UtilsSystem.EnsureDirectoryExists(linkedDir);
            UtilsSystem.EnsureDirectoryExists(linkedDir2);

            UtilsJunction.EnsureLink(linkedDir, pathContentsPersistent, logger, true, linkType: UtilsJunction.LinkTypeRequest.Junction);
            UtilsJunction.EnsureLink(linkedDir2, pathContentsPersistent, logger, true, linkType: UtilsJunction.LinkTypeRequest.Symlink);

            Assert.True(UtilsJunction.IsJunctionOrSymlink(linkedDir));
            Assert.True(UtilsJunction.IsJunctionOrSymlink(linkedDir2));

            string fileInContentsPeristent = Path.Combine(pathContentsPersistent, "test.txt");
            string fileInSymlinkDir        = Path.Combine(linkedDir, "test.txt");

            Assert.Equal(fileInContentsPeristent, UtilsJunction.ResolvePath(fileInSymlinkDir));

            string fileInContentsPeristent2 = Path.Combine(pathContentsPersistent, "test2.txt");
            string fileInSymlinkDir2        = Path.Combine(linkedDir2, "test2.txt");

            Assert.Equal(fileInContentsPeristent2, UtilsJunction.ResolvePath(fileInSymlinkDir2));

            File.WriteAllText(fileInSymlinkDir, "testfile");
            File.WriteAllText(fileInSymlinkDir2, "testfile");

            Assert.True(File.Exists(fileInSymlinkDir), $"File exists {fileInSymlinkDir}");
            Assert.True(File.Exists(fileInSymlinkDir2), $"File exists {fileInSymlinkDir2}");
            Assert.True(File.Exists(fileInContentsPeristent), $"File exists {fileInContentsPeristent}");
            Assert.True(File.Exists(fileInContentsPeristent2), $"File exists {fileInContentsPeristent2}");

            // If we delete the directory containing the symlink, the file still exists
            UtilsSystem.DeleteDirectory(pathWebsite, logger);
            Assert.False(Directory.Exists(pathWebsite), "Directory exists " + pathWebsite);

            Assert.False(File.Exists(fileInSymlinkDir), $"File exists {fileInSymlinkDir}");
            Assert.True(File.Exists(fileInContentsPeristent), $"File exists {fileInContentsPeristent}");
            Assert.False(File.Exists(fileInSymlinkDir2), $"File exists {fileInSymlinkDir2}");
            Assert.True(File.Exists(fileInContentsPeristent2), $"File exists {fileInContentsPeristent2}");

            Directory.Delete(testPath, true);
        }
Exemple #19
0
        /// <summary>
        /// Cause initialization of Certes
        /// </summary>
        /// <param name="signerPath"></param>
        /// <param name="registrationPath"></param>
        /// <param name="email"></param>
        public void InitRegistration(string signerPath, string registrationPath, string email)
        {
            // Signer path y registrationpath son específicos de la librería vieja, pero usamos el directorio que indican
            // para guardar la configuración del registro de cuenta de certes. Como el registration depende del entorno, ponemos la AcmeUri en el hash del propio
            // nombre del fichero.
            string settingsFilePath = Path.Combine(Path.GetDirectoryName(signerPath), UtilsEncryption.GetMD5(email + "::" + this.AcmeUri), "certes.json");

            UtilsSystem.EnsureDirectoryExists(settingsFilePath);

            // Initialization and renewal/revocation handling
            // We get the CertesWrapper object, that will do most of the job.
            // RS256 Let's generate a new key (RSA is good enough IMHO)
            var serviceUri = new Uri(this.AcmeUri);

            this.Logger.LogInfo(true, "Using Acme URI: " + serviceUri);

            CertesSettings settings;

            this.HttpClient     = new HttpClient();
            this.AcmeHttpClient = new AcmeHttpClient(serviceUri, this.HttpClient);

            if (File.Exists(settingsFilePath))
            {
                // Si ya teníamos unos settings, siginifica que la cuenta ya está registrada
                settings =
                    JsonConvert.DeserializeObject <CertesSettings>(File.ReadAllText(settingsFilePath));

                this.AcmeContext = new AcmeContext(serviceUri, KeyFactory.FromDer(settings.Key), this.AcmeHttpClient);
            }
            else
            {
                // Hay que crear una nueva cuenta con su clave, y registrarla en ACME
                settings = new CertesSettings()
                {
                    AccountEmail = email,
                    ServiceUri   = serviceUri,
                    Key          = KeyFactory.NewKey(KeyAlgorithm.RS256).ToDer()
                };

                // Register the account
                this.AcmeContext = new AcmeContext(serviceUri, KeyFactory.FromDer(settings.Key), this.AcmeHttpClient);
                IAccountContext accountCtx = this.AcmeContext.NewAccount(settings.AccountEmail, true).Result;
                File.WriteAllText(settingsFilePath, JsonConvert.SerializeObject(settings));

                Certes.Acme.Resource.Directory directory = this.AcmeContext.GetDirectory().Result;
                this.Logger.LogInfo(true, $"Successfully registered account {settings.AccountEmail} with certificate authority {serviceUri.AbsoluteUri}");
                if ((directory.Meta != null) && (directory.Meta.TermsOfService != null))
                {
                    this.Logger.LogInfo(true, $"Please check the ACME Service ToS at: {directory.Meta.TermsOfService}");
                }
            }

            this.CertesSettings = settings;
        }
Exemple #20
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="filename"></param>
        /// <returns></returns>
        protected string GetGlobalStoragePath(string filename)
        {
            var environmentSettingsFile =
                UtilsSystem.EnsureDirectoryExists(
                    UtilsSystem.CombinePaths(
                        Environment.GetFolderPath(Environment.SpecialFolder.CommonApplicationData),
                        "iischef",
                        "config",
                        filename));

            return(environmentSettingsFile);
        }
        public void TestResolveJunctionPath()
        {
            var logger = new TestLogsLogger(this, nameof(this.TestResolveJunctionPath));

            string testPath = UtilsSystem.GetTempPath("symlink_test" + Guid.NewGuid());

            // Probar resolución de nivel 1

            string test1OriginalPath = UtilsSystem.EnsureDirectoryExists(Path.Combine(testPath, "test1"), true);
            string test1LinkPath     = Path.Combine(testPath, "test1_link");
            string test1JunctionPath = Path.Combine(testPath, "test1_junction");

            UtilsJunction.EnsureLink(test1LinkPath, test1OriginalPath, logger, true, linkType: UtilsJunction.LinkTypeRequest.Symlink);
            UtilsJunction.EnsureLink(test1JunctionPath, test1OriginalPath, logger, true, linkType: UtilsJunction.LinkTypeRequest.Junction);

            Assert.Equal(test1OriginalPath, UtilsJunction.ResolvePath(test1LinkPath));
            Assert.Equal(test1OriginalPath, UtilsJunction.ResolvePath(test1JunctionPath));

            // Probar resolución de subdirectorio existente y no existente

            string test2OriginalPath = UtilsSystem.EnsureDirectoryExists(Path.Combine(testPath, "test2"), true);
            string test2LinkPath     = Path.Combine(testPath, "test2_link");
            string test2JunctionPath = Path.Combine(testPath, "test2_junction");

            UtilsJunction.EnsureLink(test2LinkPath, test2OriginalPath, logger, true, linkType: UtilsJunction.LinkTypeRequest.Symlink);
            UtilsJunction.EnsureLink(test2JunctionPath, test2OriginalPath, logger, true, linkType: UtilsJunction.LinkTypeRequest.Junction);

            string test2LinkSubDir     = UtilsSystem.EnsureDirectoryExists(Path.Combine(test2LinkPath, "sub1", "sub2"), true);
            string test2JunctionSubDir = UtilsSystem.EnsureDirectoryExists(Path.Combine(test2JunctionPath, "sub3", "sub4"), true);

            Assert.Equal(Path.Combine(test2OriginalPath, "sub1", "sub2"), UtilsJunction.ResolvePath(test2LinkSubDir));
            Assert.Equal(Path.Combine(test2OriginalPath, "sub3", "sub4"), UtilsJunction.ResolvePath(test2JunctionSubDir));

            // Ahora subdirectorios que no existen
            Assert.Equal(Path.Combine(test2OriginalPath, "sub4", "sub5"), UtilsJunction.ResolvePath(Path.Combine(test2LinkPath, "sub4", "sub5")));
            Assert.Equal(Path.Combine(test2OriginalPath, "sub6", "sub7"), UtilsJunction.ResolvePath(Path.Combine(test2JunctionPath, "sub6", "sub7")));

            // Ahora una cadena de enlaces dentro de otro enlace...
            string test3LinkSubDir = Path.Combine(test2LinkPath, "sub8");

            UtilsSystem.EnsureDirectoryExists(Path.Combine(test2LinkPath, "test3"), true);
            UtilsJunction.EnsureLink(test3LinkSubDir, Path.Combine(test2LinkPath, "test3"), logger, true, linkType: UtilsJunction.LinkTypeRequest.Symlink);

            Assert.Equal(Path.Combine(test2OriginalPath, "test3"), UtilsJunction.ResolvePath(test3LinkSubDir));

            UtilsSystem.DeleteDirectory(testPath, logger, 2);

            // Non existent and malformed network uri get reconstructed as-is
            string testNetworkUri = "\\\\147.83.73.25\\a\\b\\c\\\\d";

            Assert.Equal(testNetworkUri, UtilsJunction.ResolvePath(testNetworkUri));
        }
Exemple #22
0
        /// <summary>
        /// Get an instance of AppVeyorClient
        /// </summary>
        /// <param name="token">API Token</param>
        /// <param name="baseUri">Base URI</param>
        /// <param name="logger"></param>
        /// <param name="tempDir"></param>
        public Client(
            string token,
            string baseUri,
            ILoggerInterface logger,
            string tempDir)
        {
            string apiTempDir =
                UtilsSystem.EnsureDirectoryExists(UtilsSystem.CombinePaths(tempDir, "_appveyor", "api"), true);

            this.TempDir     = tempDir;
            this.Token       = token;
            this.Logger      = logger;
            this.BaseUri     = baseUri;
            this.SimpleStore = new SimpleStore(apiTempDir);
        }
Exemple #23
0
        /// <summary>
        /// Get a shared site root for the application
        /// </summary>
        /// <returns></returns>
        public string GetAcmeTemporarySiteRootForApplication()
        {
            // Create a phantom website only to serve the file...
            var wellKnownSharedPath = Path.Combine(this.StoragePath, "webroot_" + this.AppId);

            UtilsSystem.DirectoryCreateIfNotExists(wellKnownSharedPath);

            // Grant specific user permissions
            UtilsWindowsAccounts.AddPermissionToDirectoryIfMissing(
                this.Deployment.WindowsUsernameFqdn(),
                wellKnownSharedPath,
                FileSystemRights.ReadAndExecute,
                this.GlobalSettings.directoryPrincipal);

            return(wellKnownSharedPath);
        }
        /// <summary>
        ///
        /// </summary>
        /// <param name="fileName"></param>
        /// <param name="dir"></param>
        /// <returns></returns>
        protected static Assembly LoadAssemblyWithPrefix(string fileName, string dir)
        {
            string path;

            path = Path.Combine(UtilsSystem.GetCodeBaseDir(), dir, fileName);
            if (File.Exists(path))
            {
                return(Assembly.LoadFrom(path));
            }

            path = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, dir, fileName);
            if (File.Exists(path))
            {
                return(Assembly.LoadFrom(path));
            }

            return(null);
        }
Exemple #25
0
        /// <inheritdoc cref="IDownloaderInterface"/>
        public Artifact PullFromId(string version, string preferredLocalArtifactPath)
        {
            if (string.IsNullOrWhiteSpace(version))
            {
                version = this.Settings.path;
            }

            Artifact artifact = new Artifact
            {
                id        = version,
                localPath = preferredLocalArtifactPath,
                isRemote  = true
            };

            // Use artifact temp path, or local system temporary directory.
            if (Directory.Exists(artifact.localPath))
            {
                UtilsSystem.DeleteDirectory(artifact.localPath, this.Logger);
            }

            // The ID is the PATH to the local zip, so just unzip
            this.Logger.LogInfo(true, "Unzipping file....");
            ZipFile.ExtractToDirectory(version, artifact.localPath);
            this.Logger.LogInfo(true, "Unzipping finished....");

            artifact.obtainedAt = DateTime.UtcNow;

            artifact.artifactSettings = new ArtifactSettings();

            // We will merge data from both git and settings file, local settigns file
            // will override anything from GIT (if available).
            artifact.artifactSettings.PopulateFromGit(artifact.localPath);
            artifact.artifactSettings.PopulateFromSettingsFile(artifact.localPath, this.Logger);
            artifact.artifactSettings.PopulateFromEnvironment();

            // Branch name is critical to some deployment... populate with a no-branch-found....
            if (string.IsNullOrEmpty(artifact.artifactSettings.branch))
            {
                artifact.artifactSettings.branch = "no-branch-found";
                this.Logger.LogInfo(true, "Could not identify git branch for artifact. Using default: 'no-branch-found'");
            }

            return(artifact);
        }
Exemple #26
0
        /// <inheritdoc cref="IDownloaderInterface"/>
        public Artifact PullFromId(string version, string preferredLocalArtifactPath)
        {
            Artifact artifact = new Artifact
            {
                id        = version,
                localPath = preferredLocalArtifactPath,
                isRemote  = true
            };

            // Use artifact temp path, or local system temporary directory.
            if (Directory.Exists(artifact.localPath))
            {
                UtilsSystem.DeleteDirectory(artifact.localPath, this.Logger);
            }

            // Use the build version to pull the build information.
            Build build = this.Client.GetBuildFromVersion(version, this.Settings.username, this.Settings.project);

            // Make sure that the builds matches the current active branch, otherwise throw an exception
            if (!build.branch.Equals(this.Settings.branch, StringComparison.CurrentCultureIgnoreCase))
            {
                throw new Exception($"Requested version '{version}' with branch '{build.branch}' does not belong to active settings branch '{this.Settings.branch}'");
            }

            this.Client.DownloadSingleArtifactFromBuild(this.ApplicationId, build, this.Settings.artifact_regex, artifact.localPath, this.Logger);

            artifact.artifactSettings = new ArtifactSettings();
            artifact.artifactSettings.PopulateFromSettingsFile(artifact.localPath, this.Logger);

            if (string.IsNullOrWhiteSpace(artifact.artifactSettings.branch))
            {
                artifact.artifactSettings.branch = Convert.ToString(build.branch);
            }

            if (string.IsNullOrWhiteSpace(artifact.artifactSettings.commit_sha))
            {
                artifact.artifactSettings.commit_sha = Convert.ToString(build.commitId);
            }

            return(artifact);
        }
Exemple #27
0
        /// <summary>
        /// Find the matching deployer of the parent application when
        /// inheritance is configured for this application.
        /// </summary>
        /// <typeparam name="TType"></typeparam>
        /// <returns></returns>
        public TType getDeployerFromParentApp <TType>()
            where TType : DeployerBase
        {
            // We need a parent application for this to work.
            if (this.ParentApp == null)
            {
                return(null);
            }

            // Try to grab parent deployment...
            Deployment parentDeployment;
            string     activeDeploymentPathStorage = UtilsSystem.CombinePaths(this.GlobalSettings.activeDeploymentDir, "active." + this.ParentApp.GetId() + ".json");

            if (File.Exists(activeDeploymentPathStorage))
            {
                parentDeployment = Deployment.InstanceFromPath(activeDeploymentPathStorage, this.GlobalSettings);
                DeployerSettingsBase      ourSettings          = this.DeployerSettings.castTo <DeployerSettingsBase>();
                List <IDeployerInterface> deployersAndServices = new List <IDeployerInterface>();
                deployersAndServices.AddRange(parentDeployment.GrabServices(this.Logger));
                deployersAndServices.AddRange(parentDeployment.GrabDeployers(this.Logger));

                // Only keep those that match our type
                deployersAndServices = deployersAndServices.Where(s => s.GetType() == typeof(TType)).ToList();

                // Filter by ID
                foreach (TType t in deployersAndServices)
                {
                    if (t.DeployerSettings.castTo <DeployerSettingsBase>().id == ourSettings.id)
                    {
                        return(t);
                    }
                }

                return(null);
            }
            else
            {
                return(null);
            }
        }
Exemple #28
0
        /// <summary>
        /// Grab from local GIT repo.
        /// </summary>
        /// <param name="path"></param>
        public void PopulateFromGit(string path)
        {
            // Crawl up to find the first directory covered by GIT. There might be a difference
            // between the artifact folder structure and the repository (local working copy) itself...
            DirectoryInfo difo    = new DirectoryInfo(path);
            string        gitpath = null;

            while (difo != null && difo.Exists)
            {
                if (Directory.Exists(UtilsSystem.CombinePaths(difo.FullName, ".git")))
                {
                    gitpath = difo.FullName;
                    break;
                }

                difo = difo.Parent;
            }

            if (gitpath == null)
            {
                return;
            }

            try
            {
                // Try to get information directly from GIT??
                var repo = new LibGit2Sharp.Repository(gitpath, new LibGit2Sharp.RepositoryOptions()
                {
                });

                this.branch     = repo.Head.FriendlyName;
                this.commit_sha = repo.Commits.First().Sha;
                this.version    = this.commit_sha;
            }
            catch (Exception e)
            {
                // Trying to read settings from GIT can be delicate. Such as...
                // https://github.com/GitTools/GitVersion/issues/1043
            }
        }
        public void TestPfxFromPem()
        {
            BindingRedirectHandler.DoBindingRedirects(AppDomain.CurrentDomain);

            string pfxFilePath = Path.GetTempPath() + "ssl-pfx-test-" + Guid.NewGuid() + ".pfx";

            string certificatePassword = null;
            string crtFilePath         = UtilsSystem.GetResourceFileAsPath("certificate_files_example\\a0e8efb7cca4452ed304b1d9614ec89d-crt.pem");
            string keyFilePath         = UtilsSystem.GetResourceFileAsPath("certificate_files_example\\a0e8efb7cca4452ed304b1d9614ec89d-key.pem");

            UtilsCertificate.CreatePfXfromPem(crtFilePath, keyFilePath, pfxFilePath, certificatePassword);

            // Make sure that the certificate file is valid and works
            X509Certificate2Collection collection = new X509Certificate2Collection();

            collection.Import(pfxFilePath, certificatePassword, X509KeyStorageFlags.EphemeralKeySet);
            var originalCert = collection[0];

            Assert.Equal("033679B39C0CDA50C745ABD173FB0DD381A1", originalCert.SerialNumber);

            File.Delete(pfxFilePath);
        }
        public void TestLongPathSupport()
        {
            string uncPath     = "\\\\serverxx\\directory";
            string uncPathLong = UtilsSystem.AddLongPathSupport(uncPath);

            Assert.Equal("\\\\?\\UNC\\serverxx\\directory", uncPathLong);
            Assert.Equal(uncPath, UtilsSystem.RemoveLongPathSupport(uncPathLong));
            Assert.Equal(uncPath, UtilsSystem.RemoveLongPathSupport(uncPath));

            string regularPath     = "c:\\windows\\temp";
            string regularPathLong = UtilsSystem.AddLongPathSupport(regularPath);

            Assert.Equal("\\\\?\\c:\\windows\\temp", regularPathLong);
            Assert.Equal(regularPath, UtilsSystem.RemoveLongPathSupport(regularPathLong));
            Assert.Equal(regularPath, UtilsSystem.RemoveLongPathSupport(regularPath));

            // Create a very long filename, individual segments can't be over 255 characters
            string fileName = "c:\\";

            for (int x = 0; x < 100; x++)
            {
                fileName += Guid.NewGuid() + "\\";
            }

            Assert.ThrowsAny <Exception>(() =>
            {
                Directory.CreateDirectory(fileName);
            });

            var fileNameWithLongPathSupport = UtilsSystem.EnsureLongPathSupportIfAvailable(fileName);

            Directory.CreateDirectory(fileNameWithLongPathSupport);

            fileNameWithLongPathSupport += "info.txt";

            File.WriteAllText(fileNameWithLongPathSupport, "empty contents");

            File.Delete(fileNameWithLongPathSupport);
        }