Ejemplo n.º 1
0
 public DockerEngineClient(
     ISshClient sshClient,
     ILogger logger)
 {
     this.sshClient = sshClient;
     this.logger    = logger;
 }
        /// <summary>
        /// These sets of commands are taken from https://docs.docker.com/install/linux/docker-ce/ubuntu/.
        /// </summary>
        private async Task InstallDockerAsync(ISshClient sshClient)
        {
            this.description = "Installing Docker Engine";

            //SET UP THE REPOSITORY
            await RunCommandsAsync(
                sshClient,
                SshRetryPolicy.AllowRetries,
                new[]
            {
                "sudo apt-get update",
                "echo '* libraries/restart-without-asking boolean true' | sudo debconf-set-selections",
                "sudo apt-get -y install apt-transport-https ca-certificates curl gnupg-agent software-properties-common",
                "curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -",
                "sudo add-apt-repository \"deb [arch=amd64] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable\""
            });

            //INSTALL DOCKER ENGINE - COMMUNITY
            await RunCommandsAsync(
                sshClient,
                SshRetryPolicy.AllowRetries,
                new[]
            {
                "sudo apt-get update",
                "sudo apt-get -y install docker-ce docker-ce-cli containerd.io"
            });
        }
        private async Task OpenExposedFirewallPortsOnInstanceAsync(ISshClient sshClient)
        {
            if (this.InstanceName == null)
            {
                throw new InvalidOperationException("No instance name was found.");
            }

            this.description = "Opening firewall for exposed ports and protocols";

            var mergedDockerComposeYmlContents = await GetMergedDockerComposeYmlFileContentsAsync(sshClient);

            var dockerComposeParser = this.dockerComposeParserFactory.Create(mergedDockerComposeYmlContents);

            var portsToOpen = new HashSet <ExposedPortRange>()
            {
                GetSshPort()
            };

            var ports = dockerComposeParser.GetExposedHostPorts();

            foreach (var port in ports)
            {
                portsToOpen.Add(port);
            }

            await this.mediator.Send(new OpenFirewallPortsCommand(
                                         this.InstanceName,
                                         portsToOpen));
        }
        private async Task AuthenticateDockerAsync(ISshClient sshClient)
        {
            var authenticationArguments = this.Authentication;

            if (authenticationArguments == null)
            {
                return;
            }

            foreach (var authenticationArgument in authenticationArguments)
            {
                await sshClient.ExecuteCommandAsync(
                    SshRetryPolicy.AllowRetries,
                    "echo @password | docker login -u @username --password-stdin @registryHostName",
                    new Dictionary <string, string?>()
                {
                    {
                        "username", authenticationArgument.Username
                    },
                    {
                        "password", authenticationArgument.Password
                    },
                    {
                        "registryHostName", authenticationArgument.RegistryHostName
                    }
                });
            }
        }
        private static async Task EnsureDirectoryAsync(ISshClient sshClient, string path)
        {
            await sshClient.ExecuteCommandAsync(
                SshRetryPolicy.AllowRetries,
                $"mkdir -m 777 -p ./{path}");

            await SetUserPermissionsOnPathAsync(sshClient, path);
        }
        //private async Task InstallKubernetesOnNodeAsync(
        //    ISshClient sshClient,
        //    InstanceType instanceType)
        //{
        //    await InstallKubernetesToolsAsync(sshClient);

        //    switch (instanceType)
        //    {
        //        case InstanceType.KubernetesControlPlane:
        //            await InitializeKubernetesControlPlaneNodeAsync(sshClient);
        //            break;

        //        case InstanceType.KubernetesWorker:
        //            await InitializeKubernetesWorkerNodeAsync(sshClient);
        //            break;

        //        default:
        //            throw new InvalidOperationException("Unknown instance type.");
        //    }
        //}

        //private async Task InitializeKubernetesWorkerNodeAsync(ISshClient sshClient)
        //{
        //    throw new NotImplementedException("Kubernetes worker support has not been created yet.");
        //}

        private async Task ConfigureDockerDaemonAsync(ISshClient sshClient)
        {
            this.description = "Configuring Docker Daemon";

            await sshClient.ExecuteCommandAsync(
                SshRetryPolicy.AllowRetries,
                "sudo systemctl enable docker");
        }
        private async Task <string> GetMergedDockerComposeYmlFileContentsAsync(ISshClient sshClient)
        {
            var dockerComposeYmlFilePathArguments = GetDockerComposeFilesCommandLineArgumentString();
            var environmentVariablesPrefix        = GetEnvironmentVariablesCommandLinePrefixString();

            return(await sshClient.ExecuteCommandAsync(
                       SshRetryPolicy.AllowRetries,
                       $"cd dogger && {environmentVariablesPrefix} docker-compose {dockerComposeYmlFilePathArguments} config"));
        }
Ejemplo n.º 8
0
 public SshStep(
     ListAsk listAsk,
     ListResources listResources,
     ISshClient sshClient)
 {
     this.listResources = listResources;
     this.sshClient     = sshClient;
     this.listAsk       = listAsk;
 }
Ejemplo n.º 9
0
        public VBoxInfrastructure(
            VBoxHelper vBoxHelper,
            ISshClient sshClient)
        {
            this.vBoxHelper = vBoxHelper;
            this.sshClient  = sshClient;

            //this.vmPilote.PrivateRegistryPort = 5443;
            //this.vmPilote.PrivateRegistryDomain = "privateregistry.mynetwork.local";
        }
Ejemplo n.º 10
0
 public InfraWebServerCreateVm(
     ListAsk listAsk,
     ListResources listResources,
     IInfrastructure infrastructure,
     ISshClient sshClient)
 {
     this.listAsk        = listAsk;
     this.infrastructure = infrastructure;
     this.listResources  = listResources;
     this.sshClient      = sshClient;
 }
Ejemplo n.º 11
0
 public PiloteStep(
     ListAsk listAsk,
     ListResources listResources,
     CiExeCommands ciExeCommands,
     ISshClient sshClient)
 {
     this.listResources = listResources;
     this.ciExeCommands = ciExeCommands;
     this.sshClient     = sshClient;
     this.listAsk       = listAsk;
 }
        private async Task RunContainersAsync(ISshClient sshClient)
        {
            if (InstanceName == null)
            {
                throw new InvalidOperationException("Could not find instance name.");
            }

            await AuthenticateDockerAsync(sshClient);

            var filesArgument          = GetDockerComposeFilesCommandLineArgumentString();
            var buildArgumentsArgument = PrependArgumentNameToStrings("--build-arg", GetBuildArgumentAssignments());

            var environmentVariablesPrefix = GetEnvironmentVariablesCommandLinePrefixString();

            try
            {
                await sshClient.ExecuteCommandAsync(
                    SshRetryPolicy.AllowRetries,
                    $"cd dogger && {environmentVariablesPrefix} docker-compose {filesArgument} down --rmi all --volumes --remove-orphans");

                await sshClient.ExecuteCommandAsync(
                    SshRetryPolicy.AllowRetries,
                    $"cd dogger && {environmentVariablesPrefix} docker-compose {filesArgument} pull --include-deps");

                await sshClient.ExecuteCommandAsync(
                    SshRetryPolicy.AllowRetries,
                    $"cd dogger && {environmentVariablesPrefix} docker-compose {filesArgument} build --force-rm --parallel --no-cache {buildArgumentsArgument}");

                await sshClient.ExecuteCommandAsync(
                    SshRetryPolicy.ProhibitRetries,
                    $"cd dogger && {environmentVariablesPrefix} docker-compose {filesArgument} --compatibility up --detach --remove-orphans --always-recreate-deps --force-recreate --renew-anon-volumes");
            }
            catch (SshCommandExecutionException ex) when(ex.Result.ExitCode == 1)
            {
                var listFilesDump = await sshClient.ExecuteCommandAsync(
                    SshRetryPolicy.AllowRetries,
                    "cd dogger && ls -R");

                await this.mediator.Send(new ServerDeploymentFailedEvent(
                                             InstanceName,
                                             ex.Result.Text,
                                             listFilesDump));

                throw new StateUpdateException(
                          "Could not run containers: " + ex.Result.Text,
                          ex,
                          new BadRequestObjectResult(
                              new ValidationProblemDetails()
                {
                    Type  = "DOCKER_COMPOSE_UP_FAIL",
                    Title = ex.Result.Text
                }));
            }
        }
 private static async Task RunCommandsAsync(
     ISshClient sshClient,
     SshRetryPolicy retryPolicy,
     string[] commands)
 {
     foreach (var command in commands)
     {
         await sshClient.ExecuteCommandAsync(
             retryPolicy,
             command);
     }
 }
        //private async Task InstallKubernetesToolsAsync(ISshClient sshClient)
        //{
        //    this.description = "Installing Kubernetes";

        //    await RunCommandsAsync(
        //        sshClient,
        //        SshRetryPolicy.AllowRetries,
        //        new[]
        //        {
        //            "sudo apt-get update",
        //            "sudo apt-get install -y apt-transport-https curl",
        //            "sudo curl -s https://packages.cloud.google.com/apt/doc/apt-key.gpg | sudo apt-key add -",
        //            "sudo cat <<EOF | sudo tee /etc/apt/sources.list.d/kubernetes.list\ndeb https://apt.kubernetes.io/ kubernetes-xenial main\nEOF",
        //            "sudo apt-get update",
        //            "sudo apt-get install -y kubelet kubeadm kubectl",
        //            "sudo apt-mark hold kubelet kubeadm kubectl"
        //        });
        //}

        ///// <summary>
        ///// From: https://kubernetes.io/docs/setup/production-environment/tools/kubeadm/create-cluster-kubeadm/#installing-kubeadm-on-your-hosts
        ///// </summary>
        //private async Task InitializeKubernetesControlPlaneNodeAsync(ISshClient sshClient)
        //{
        //    throw new NotImplementedException("Kubernetes control plane support has not been created yet.");
        //}

        /// <summary>
        /// These sets of commands are taken from https://docs.docker.com/compose/install/
        /// </summary>
        private async Task InstallDockerComposeAsync(ISshClient sshClient)
        {
            this.description = "Installing Docker Compose";

            await RunCommandsAsync(
                sshClient,
                SshRetryPolicy.AllowRetries,
                new[]
            {
                "sudo curl -L \"https://github.com/docker/compose/releases/download/1.25.3/docker-compose-$(uname -s)-$(uname -m)\" -o /usr/local/bin/docker-compose",
                "sudo chmod +x /usr/local/bin/docker-compose"
            });
        }
        /// <summary>
        /// These sets of commands are taken from https://docs.docker.com/engine/install/linux-postinstall/
        /// </summary>
        private async Task ConfigurePostInstallAsync(ISshClient sshClient)
        {
            this.description = "Configuring Docker permissions";

            await sshClient.ExecuteCommandAsync(
                SshRetryPolicy.AllowRetries,
                "sudo usermod -aG docker $USER");

            //verify that we can run docker without root access.
            await sshClient.ExecuteCommandAsync(
                SshRetryPolicy.AllowRetries,
                "docker --version");
        }
        private static async Task SetSystemConfigurationValueAsync(
            ISshClient sshClient,
            string key,
            string value)
        {
            await sshClient.ExecuteCommandAsync(
                SshRetryPolicy.AllowRetries,
                $"sudo sysctl -w {key}={value}");

            await sshClient.ExecuteCommandAsync(
                SshRetryPolicy.AllowRetries,
                $"sudo bash -c \"echo '{key}={value}' >> /etc/sysctl.conf\"");
        }
        protected override async Task <ProvisioningStateUpdateResult> OnUpdateAsync(ISshClient sshClient)
        {
            if (this.IpAddress == null)
            {
                throw new InvalidOperationException($"Must provide IP address to {nameof(InstallSoftwareOnInstanceState)}");
            }

            await InstallDockerAsync(sshClient);
            await InstallDockerComposeAsync(sshClient);
            await ConfigureDockerDaemonAsync(sshClient);
            await ConfigurePostInstallAsync(sshClient);

            await SetSystemConfigurationValueAsync(sshClient, "vm.max_map_count", "262144");

            return(ProvisioningStateUpdateResult.Succeeded);
        }
        protected override async Task <ProvisioningStateUpdateResult> OnUpdateAsync(ISshClient sshClient)
        {
            if (this.InstanceName == null)
            {
                throw new InvalidOperationException("Instance name has not been set.");
            }

            await this.mediator.Send(
                new RegisterInstanceAsProvisionedCommand(
                    this.InstanceName)
            {
                UserId = this.UserId
            });

            return(ProvisioningStateUpdateResult.Succeeded);
        }
        protected override async Task <ProvisioningStateUpdateResult> OnUpdateAsync(ISshClient sshClient)
        {
            if (this.DockerComposeYmlFilePaths == null)
            {
                throw new InvalidOperationException("Docker Compose file paths must be set.");
            }

            await ClearExistingDoggerFilesAsync(sshClient);
            await CreateFilesOnServerAsync(sshClient);

            await OpenExposedFirewallPortsOnInstanceAsync(sshClient);
            await RunContainersAsync(sshClient);

            await SendServerDeploymentCompletedEventAsync();

            return(ProvisioningStateUpdateResult.Succeeded);
        }
        private async Task CreateFilesOnServerAsync(ISshClient sshClient)
        {
            var files = this.Files;

            if (files == null)
            {
                return;
            }

            foreach (var file in files)
            {
                await CreateSensitiveFileOnServerAsync(
                    sshClient,
                    file.Path,
                    file.Contents);
            }
        }
        private static async Task CreateSensitiveFileOnServerAsync(
            ISshClient sshClient,
            string filePath,
            byte[] contents)
        {
            filePath = SanitizeRelativePath(filePath);

            if (filePath.Contains("/", StringComparison.InvariantCulture))
            {
                var folderPath = filePath.Substring(0, filePath.LastIndexOf('/'));
                await EnsureDirectoryAsync(sshClient, $"./dogger/{folderPath}");
            }

            await sshClient.TransferFileAsync(
                SshRetryPolicy.AllowRetries,
                $"dogger/{filePath}",
                contents);

            await SetUserPermissionsOnPathAsync(sshClient, $"dogger/{filePath}");
        }
Ejemplo n.º 22
0
        public CiExeCommands(
            InstallCA installCA,
            InstallRegistry installRegistry,
            InstallVault installVault,
            BuildWebApp1 buildWebApp1,

            // WebServer
            InstallTraefik installTraefik,
            InstallWebApp installWebApp,

            ISshClient sshClient
            )
        {
            volume1 = "--volume /var/run/docker.sock:/var/run/docker.sock ";
            volume2 = "--volume " + "/cidata" + ":/cidata ";

            this.InstallCA = Create <InstallCA>("install-ca", async() => await installCA.Install());
            this.CleanCA   = Create <InstallCA>("clean-ca", async() => await installCA.Clean());

            this.InstallRegistry = Create <InstallRegistry>("install-registry", async() => await installRegistry.Install());
            this.CleanRegistry   = Create <InstallRegistry>("clean-registry", async() => await installRegistry.Clean());

            this.InstallVault = Create <InstallVault>("install-vault", async() => await installVault.Init());

            this.BuildWebApp1 = Create <BuildWebApp1>("build-webapp1", async() => await buildWebApp1.Build());
            this.CleanWebApp1 = Create <BuildWebApp1>("clean-webapp1", async() => await buildWebApp1.CleanBuild());

            this.PublishWebApp1   = Create <BuildWebApp1>("publish-webapp1", async() => await buildWebApp1.Publish());
            this.UnpublishWebApp1 = Create <BuildWebApp1>("cleanpublish-webapp1", async() => await buildWebApp1.CleanPublish());

            // Webserver
            this.InstallTraefik = Create <InstallTraefik>("webserver-install-webapp1", async() => await installTraefik.Install());
            this.CleanTraefik   = Create <InstallTraefik>("clean-webapp1", async() => await installTraefik.Clean());

            this.InstallWebApp1      = Create <InstallWebApp>("webserver-install-webapp1", async() => await installWebApp.Install());
            this.CleanInstallWebApp1 = Create <InstallWebApp>("clean-webapp1", async() => await installWebApp.CleanInstall());
            this.sshClient           = sshClient;
        }
Ejemplo n.º 23
0
 protected abstract Task <ProvisioningStateUpdateResult> OnUpdateAsync(ISshClient sshClient);
Ejemplo n.º 24
0
 public SshMirrorRegistry(ISshClient sshClient)
 {
     this.sshClient = sshClient;
 }
 private static async Task RemoveDirectoryAsync(ISshClient sshClient, string path)
 {
     await sshClient.ExecuteCommandAsync(
         SshRetryPolicy.AllowRetries,
         $"sudo rm ./{path} -rf");
 }
 private static async Task ClearExistingDoggerFilesAsync(ISshClient sshClient)
 {
     await RemoveDirectoryAsync(sshClient, "dogger");
     await EnsureDirectoryAsync(sshClient, "dogger");
 }
 private static async Task SetUserPermissionsOnPathAsync(ISshClient sshClient, string fileName)
 {
     await sshClient.ExecuteCommandAsync(
         SshRetryPolicy.AllowRetries,
         $"sudo chmod 777 ./{fileName}");
 }
Ejemplo n.º 28
0
 public SshCiexe(ISshClient sshClient)
 {
     this.sshClient = sshClient;
 }
Ejemplo n.º 29
0
 private IDockerEngineClient CreateForSshClient(ISshClient sshClient)
 {
     return(new DockerEngineClient(
                sshClient,
                logger));
 }