From 5b0b3eb423dcc8de5c1044349710c1d09a9f3aae Mon Sep 17 00:00:00 2001 From: Nathan Willoughby <86938706+nathanwoctopusdeploy@users.noreply.github.com> Date: Mon, 27 Nov 2023 12:11:16 +1000 Subject: [PATCH] Add Vagrant and Docker Scripts to setup Tentacles for compatibility testing (#479) Added docker compose file to stand up docker containers with many versions of Tentacle Added Vagrant scripts to setup a windows vm with a provided set of tentacles. --- README.md | 3 + testing/.gitignore | 6 ++ testing/README.md | 17 +++++ .../azure/deploy.ps1 | 0 .../azure/install-tentacle.ps1 | 0 .../azure/readme.md | 0 .../azure/vm.bicep | 0 .../azure/vm.bicepparam | 0 testing/compatibility/docker/README.md | 50 ++++++++++++ .../docker/docker-compose.mustache | 66 ++++++++++++++++ .../compatibility/docker/example.config.json | 7 ++ testing/compatibility/docker/example.env | 9 +++ testing/compatibility/docker/generate.ps1 | 32 ++++++++ testing/compatibility/docker/run.ps1 | 3 + .../compatibility/vagrant/Linux/Vagrantfile | 58 ++++++++++++++ .../compatibility/vagrant/Linux/bootstrap.ps1 | 76 +++++++++++++++++++ .../compatibility/vagrant/Linux/example.env | 14 ++++ .../compatibility/vagrant/Linux/install.ps1 | 9 +++ .../compatibility/vagrant/Linux/listening.ps1 | 52 +++++++++++++ .../compatibility/vagrant/Linux/polling.ps1 | 49 ++++++++++++ testing/compatibility/vagrant/README.md | 72 ++++++++++++++++++ .../compatibility/vagrant/Windows/Vagrantfile | 35 +++++++++ .../vagrant/Windows/bootstrap.ps1 | 73 ++++++++++++++++++ .../compatibility/vagrant/Windows/example.env | 14 ++++ .../compatibility/vagrant/Windows/install.ps1 | 9 +++ .../vagrant/Windows/listening.ps1 | 52 +++++++++++++ .../compatibility/vagrant/Windows/polling.ps1 | 49 ++++++++++++ 27 files changed, 755 insertions(+) create mode 100644 testing/.gitignore create mode 100644 testing/README.md rename testing/{compatability => compatibility}/azure/deploy.ps1 (100%) rename testing/{compatability => compatibility}/azure/install-tentacle.ps1 (100%) rename testing/{compatability => compatibility}/azure/readme.md (100%) rename testing/{compatability => compatibility}/azure/vm.bicep (100%) rename testing/{compatability => compatibility}/azure/vm.bicepparam (100%) create mode 100644 testing/compatibility/docker/README.md create mode 100644 testing/compatibility/docker/docker-compose.mustache create mode 100644 testing/compatibility/docker/example.config.json create mode 100644 testing/compatibility/docker/example.env create mode 100644 testing/compatibility/docker/generate.ps1 create mode 100644 testing/compatibility/docker/run.ps1 create mode 100644 testing/compatibility/vagrant/Linux/Vagrantfile create mode 100644 testing/compatibility/vagrant/Linux/bootstrap.ps1 create mode 100644 testing/compatibility/vagrant/Linux/example.env create mode 100644 testing/compatibility/vagrant/Linux/install.ps1 create mode 100644 testing/compatibility/vagrant/Linux/listening.ps1 create mode 100644 testing/compatibility/vagrant/Linux/polling.ps1 create mode 100644 testing/compatibility/vagrant/README.md create mode 100644 testing/compatibility/vagrant/Windows/Vagrantfile create mode 100644 testing/compatibility/vagrant/Windows/bootstrap.ps1 create mode 100644 testing/compatibility/vagrant/Windows/example.env create mode 100644 testing/compatibility/vagrant/Windows/install.ps1 create mode 100644 testing/compatibility/vagrant/Windows/listening.ps1 create mode 100644 testing/compatibility/vagrant/Windows/polling.ps1 diff --git a/README.md b/README.md index c5ec3c1d4..435631e10 100644 --- a/README.md +++ b/README.md @@ -99,3 +99,6 @@ Currently we can only debug netcore apps running in WSL from VSCode, Visual Stud "problemMatcher": "$msCompile" } ``` +## Additional Resources + +- Scripts to help with manual testing can be found in [./testing](./testing/README.md). \ No newline at end of file diff --git a/testing/.gitignore b/testing/.gitignore new file mode 100644 index 000000000..9d39ea74f --- /dev/null +++ b/testing/.gitignore @@ -0,0 +1,6 @@ +.vs +.vagrant +.env +compatibility/docker/config.generated.json +compatibility/docker/docker-compose.yml +compatibility/docker/config.json \ No newline at end of file diff --git a/testing/README.md b/testing/README.md new file mode 100644 index 000000000..9c1c1a3b1 --- /dev/null +++ b/testing/README.md @@ -0,0 +1,17 @@ +# Manually Testing Tentacle + +## Compatibility Testing + +The following Vagrant and Docker and Azure scripts are available to provision Tentacles and assist with manually setting up different versions of Tentacle for compatibility testing. + +### Vagrant + +Use the [Vagrant](./compatibility/Vagrant/README.md) scripts to setup a Windows or Linux VM with a selection of Tentacle versions, both Polling and Listening Deployment Targets and Workers are supported. + +### Docker + +Use the [Docker Compose](./compatibility/docker/README.md) scripts to setup docker containers with a selection of Tentacle versions, both Polling and Listening Deployment Targets and Workers are supported. + +### Azure + +Use the [Azure](./compatibility/azure/README.md) scripts to setup Azure Virtual Machines with a selection of Tentacle versions, both Polling and Listening Deployment Targets and Workers are supported. \ No newline at end of file diff --git a/testing/compatability/azure/deploy.ps1 b/testing/compatibility/azure/deploy.ps1 similarity index 100% rename from testing/compatability/azure/deploy.ps1 rename to testing/compatibility/azure/deploy.ps1 diff --git a/testing/compatability/azure/install-tentacle.ps1 b/testing/compatibility/azure/install-tentacle.ps1 similarity index 100% rename from testing/compatability/azure/install-tentacle.ps1 rename to testing/compatibility/azure/install-tentacle.ps1 diff --git a/testing/compatability/azure/readme.md b/testing/compatibility/azure/readme.md similarity index 100% rename from testing/compatability/azure/readme.md rename to testing/compatibility/azure/readme.md diff --git a/testing/compatability/azure/vm.bicep b/testing/compatibility/azure/vm.bicep similarity index 100% rename from testing/compatability/azure/vm.bicep rename to testing/compatibility/azure/vm.bicep diff --git a/testing/compatability/azure/vm.bicepparam b/testing/compatibility/azure/vm.bicepparam similarity index 100% rename from testing/compatability/azure/vm.bicepparam rename to testing/compatibility/azure/vm.bicepparam diff --git a/testing/compatibility/docker/README.md b/testing/compatibility/docker/README.md new file mode 100644 index 000000000..b1e705617 --- /dev/null +++ b/testing/compatibility/docker/README.md @@ -0,0 +1,50 @@ +# Docker + +Setup docker containers with a set of Polling and Listening Deployment Targets and Workers + +## Pre-Req Installation + +Install Powershell + +Install Docker + +## Configuration + +Copy the file `example.config.json` to `config.json` and modify the settings + +- **pollingDeploymentTargets** true to set-up polling deployment targets e.g. `"pollingDeploymentTargets": true` +- **listeningDeploymentTargets** true to set-up listening deployment targets e.g. `"listeningDeploymentTargets": true` +- **pollingWorkers** true to set-up polling workers e.g. `"pollingWorkers": true` +- **listeningWorkers** true to set-up listening workers e.g. `"listeningWorkers": true` +- **tentacleVersions** comma separated list of versions to install e.g. `"tentacleVersions": "6.1.1531,6.2.277,6.3.417,6.3.605,latest"` + +Copy the file `example.env` to `.env` and modify the settings + +- **serverUrl** The url of Octopus Server to configure the Tentacles for e.g. `serverUrl=http://mymachine.local:8066` +- **serverPollingPort** The Octopus Server polling port e.g. `serverPollingPort=10943` +- **serverApiKey** The Octopus Server API Key e.g. `serverApiKey=API-APIKEY01` +- **environment** The environment to configure the Deployment Targets for e.g. `environment=Development` +- **pollingRole** The role to assign to the polling Deployment Targets e.g. `pollingRole=pollingBreadRoll` +- **listeningRole** The role to assign to the listening Deployment Targets e.g. `listeningRole=listeningBreadRoll` +- **space** the space to configure the Tentacle for e.g. `space=Default` Note: Versions of Tentacle prior to `4.x` had no concept of spaces so will be configured against the `Default` workspace +- **workerPool** The name of the worker pool to add workers to e.g. `workerPool=Default Worker Pool` + +`tentacleVersions` can be any version that is available on [Docker Hub](https://hub.docker.com/r/octopusdeploy/tentacle/tags) + +## Running + +Generate the docker compose file + +`.\generate.ps1` + +> This will generate 2 files. `config.generated.json` and `docker-compose.yml` + +Deploy the containers + +`.\run.ps1` + +> This calls `docker-compose up --remove-orphans` + +Delete the containers + +`docker-compose down` \ No newline at end of file diff --git a/testing/compatibility/docker/docker-compose.mustache b/testing/compatibility/docker/docker-compose.mustache new file mode 100644 index 000000000..d43dfbeae --- /dev/null +++ b/testing/compatibility/docker/docker-compose.mustache @@ -0,0 +1,66 @@ +version: '3.8' +services: +{{#versions}} +{{#pollingDeploymentTargets}} + pollingDeploymentTarget{{version}}: + image: "octopusdeploy/tentacle:{{version}}" + privileged: true + environment: + TargetName: "DockerPollingDeploymentTarget.{{version}}" + Space: ${space} + TargetEnvironment: "${environment}" + TargetRole: "${pollingRole}" + ACCEPT_EULA: "Y" + ServerPort: "${serverPollingPort}" + ServerApiKey: ${serverApiKey} + ServerUrl: "${serverUrl}" +{{/pollingDeploymentTargets}} +{{#listeningDeploymentTargets}} + listeningDeploymentTarget{{version}}: + image: "octopusdeploy/tentacle:{{version}}" + privileged: true + environment: + TargetName: "DockerListeningDeploymentTarget.{{version}}" + Space: ${space} + TargetEnvironment: "${environment}" + TargetRole: "${listeningRole}" + ACCEPT_EULA: "Y" + ListeningPort: "{{deploymentTargetListeningPort}}" + ServerApiKey: ${serverApiKey} + ServerUrl: "${serverUrl}" + PublicHostNameConfiguration: "Custom" + CustomPublicHostName: "${CustomPublicHostName}" + ports: + - "{{deploymentTargetListeningPort}}:10933" +{{/listeningDeploymentTargets}} +{{#pollingWorkers}} + pollingWorker{{version}}: + image: "octopusdeploy/tentacle:{{version}}" + privileged: true + environment: + TargetName: "DockerPollingWorker.{{version}}" + TargetWorkerPool: "${workerPool}" + Space: ${space} + ACCEPT_EULA: "Y" + ServerPort: "${serverPollingPort}" + ServerApiKey: ${serverApiKey} + ServerUrl: "${serverUrl}" +{{/pollingWorkers}} +{{#listeningWorkers}} + listeningWorker{{version}}: + image: "octopusdeploy/tentacle:{{version}}" + privileged: true + environment: + TargetName: "DockerListeningWorker.{{version}}" + TargetWorkerPool: "${workerPool}" + Space: ${space} + ACCEPT_EULA: "Y" + ListeningPort: "{{workerListeningPort}}" + ServerApiKey: ${serverApiKey} + ServerUrl: "${serverUrl}" + PublicHostNameConfiguration: "Custom" + CustomPublicHostName: "${CustomPublicHostName}" + ports: + - "{{workerListeningPort}}:10933" +{{/listeningWorkers}} +{{/versions}} \ No newline at end of file diff --git a/testing/compatibility/docker/example.config.json b/testing/compatibility/docker/example.config.json new file mode 100644 index 000000000..c4176beb8 --- /dev/null +++ b/testing/compatibility/docker/example.config.json @@ -0,0 +1,7 @@ +{ + "pollingDeploymentTargets": true, + "listeningDeploymentTargets": true, + "pollingWorkers": true, + "listeningWorkers": true, + "tentacleVersions": "6.1.1531,6.2.277,6.3.417,6.3.605,latest" +} diff --git a/testing/compatibility/docker/example.env b/testing/compatibility/docker/example.env new file mode 100644 index 000000000..a986c5cb3 --- /dev/null +++ b/testing/compatibility/docker/example.env @@ -0,0 +1,9 @@ +serverUrl=http://host.docker.internal:8066 +serverPollingPort=10943 +serverApiKey=API-APIKEY01 +environment=Development +pollingRole=polling +listeningRole=listen +space=Default +workerPool=Default Worker Pool +customPublicHostName=MyMachine.local \ No newline at end of file diff --git a/testing/compatibility/docker/generate.ps1 b/testing/compatibility/docker/generate.ps1 new file mode 100644 index 000000000..fc2b7a4ae --- /dev/null +++ b/testing/compatibility/docker/generate.ps1 @@ -0,0 +1,32 @@ +# Generate the configuration + +$config = Get-Content 'config.json' -raw | ConvertFrom-Json +$tentacleVersionsString = $config.tentacleVersions; +$tentacleVersions = $tentacleVersionsString.Split(',') + +$versions = 1..$tentacleVersions.Count +$startPort = 11900 + +for ($i = 0; $i -lt $tentacleVersions.Count; $i++) { + $v = New-Object -TypeName psobject + $v | Add-Member -MemberType NoteProperty -Name "version" -Value $tentacleVersions[$i] + $v | Add-Member -MemberType NoteProperty -Name "workerListeningPort" -Value $startPort + $v | Add-Member -MemberType NoteProperty -Name "deploymentTargetListeningPort" -Value ($startPort + 1) + $versions[$i] = $v; + + $startPort += 2 +} + +$config | add-member -Name "versions" -value $versions -MemberType NoteProperty + +$config | ConvertTo-Json -depth 32 | set-content 'config.generated.json' + +# Install Mustache + +Install-Module Poshstache -f + +# Generate the docker-compose file + +$jsonConfigFile = "config.generated.json" +$jsonConfig = Get-Content $jsonConfigFile | Out-String +ConvertTo-PoshstacheTemplate -InputFile "docker-compose.mustache" -ParametersObject $jsonConfig | Out-File "docker-compose.yml" -Force -Encoding "UTF8" \ No newline at end of file diff --git a/testing/compatibility/docker/run.ps1 b/testing/compatibility/docker/run.ps1 new file mode 100644 index 000000000..5dd073659 --- /dev/null +++ b/testing/compatibility/docker/run.ps1 @@ -0,0 +1,3 @@ +.\generate.ps1 + +docker-compose up --remove-orphans \ No newline at end of file diff --git a/testing/compatibility/vagrant/Linux/Vagrantfile b/testing/compatibility/vagrant/Linux/Vagrantfile new file mode 100644 index 000000000..e3d718901 --- /dev/null +++ b/testing/compatibility/vagrant/Linux/Vagrantfile @@ -0,0 +1,58 @@ +# -*- mode: ruby -*- +# vi: set ft=ruby : + +# All Vagrant configuration is done below. The "2" in Vagrant.configure +# configures the configuration version (we support older styles for +# backwards compatibility). Please don't change it unless you know what +# you're doing. +Vagrant.configure("2") do |config| + + config.vm.box = "ubuntu/focal64" + config.env.enable # Enable vagrant-env(.env) + config.vm.network "public_network" + config.vm.synced_folder '.', '/vagrant', disabled: true + + config.vm.box_check_update = false + + config.vm.provider "virtualbox" do |vb| + vb.gui = true + vb.memory = 10240 + vb.cpus = 6 + end + + config.vm.provider :hyperv do |v, override| + v.gui = true + v.maxmemory = 10240 + v.memory = 10240 + v.cpus = 6 + end + + $installPowershell = <<-SCRIPT + # Update the list of packages + sudo apt-get update + # Install pre-requisite packages. + sudo apt-get install -y wget apt-transport-https software-properties-common + # Download the Microsoft repository GPG keys + wget -q "https://packages.microsoft.com/config/ubuntu/$(lsb_release -rs)/packages-microsoft-prod.deb" + # Register the Microsoft repository GPG keys + sudo dpkg -i packages-microsoft-prod.deb + # Delete the the Microsoft repository GPG keys file + rm packages-microsoft-prod.deb + # Update the list of packages after we added packages.microsoft.com + sudo apt-get update + # Install PowerShell + sudo apt-get install -y powershell + # Start PowerShell + pwsh + SCRIPT + + config.vm.provision "shell", inline: $installPowershell + + config.vm.provision "file", source: "./bootstrap.ps1", destination: "/tmp/bootstrap.ps1" + config.vm.provision "file", source: "./install.ps1", destination: "/tmp/install.ps1" + config.vm.provision "file", source: "./polling.ps1", destination: "/tmp/polling.ps1" + config.vm.provision "file", source: "./listening.ps1", destination: "/tmp/listening.ps1" + + config.vm.provision :shell, path: "bootstrap.ps1", upload_path: "/tmp/vagrant-shell.ps1", :args => "-serverUrl " + "'" + ENV['serverUrl'] + "'" + " -serverPollingPort " + ENV['serverPollingPort'] + " -serverApiKey " + "'" + ENV['serverApiKey'] + "'" + " -environment " + "'" + ENV['environment'] + "'" + " -listeningRole " + "'" + ENV['listeningRole'] + "'" + " -pollingRole " + "'" + ENV['pollingRole'] + "'" + " -space " + "'" + ENV['space'] + "'" + " -tentacleVersions " + "'" + ENV['tentacleVersions'] + "'" + " -listening " + ENV['listening'] + " -polling " + ENV['polling'] + " -serverThumbprint " + "'" + ENV['serverThumbprint'] + "'" + " -deploymentTargets " + ENV['deploymentTargets'] + " -workers " + ENV['workers'] + " -workerPool " + "'" + ENV['workerPool'] + "'" + +end diff --git a/testing/compatibility/vagrant/Linux/bootstrap.ps1 b/testing/compatibility/vagrant/Linux/bootstrap.ps1 new file mode 100644 index 000000000..9d2793328 --- /dev/null +++ b/testing/compatibility/vagrant/Linux/bootstrap.ps1 @@ -0,0 +1,76 @@ +#!/usr/bin/env pwsh +param([string] $serverUrl, +[string] $serverPollingPort, +[string] $serverApiKey, +[string] $environment, +[string] $pollingRole, +[string] $listeningRole, +[string] $space, +[string] $tentacleVersions, +[string] $listening, +[string] $polling, +[string] $deploymentTargets, +[string] $workers, +[string] $serverThumbprint, +[string] $workerPool) + +echo "serverUrl:$serverUrl" +echo "serverPollingPort:$serverPollingPort" +echo "serverApiKey:$serverApiKey" +echo "environment:$environment" +echo "listeningRole:$listeningRole" +echo "pollingRole:$pollingRole" +echo "space:$space" +echo "workerPool:$workerPool" + +sudo ufw disable + +$versions = $tentacleVersions.Split(",") + +echo "verisons:$versions" +echo "listening:$listening" +echo "polling:$polling" + +echo "deploymentTargets:$deploymentTargets" +echo "workers:$workers" + +cd /tmp/ + +$port = 12900 + +apt-key adv --fetch-keys https://apt.octopus.com/public.key +add-apt-repository "deb https://apt.octopus.com/ stretch main" +apt-get update + +foreach ( $version in $versions ) +{ + ./install.ps1 -version $version + + if($polling.ToLower() -eq "true") + { + if($deploymentTargets.ToLower() -eq "true") + { + ./polling.ps1 -deploymentTarget $True -version "$version" -serverUrl "$serverUrl" -serverPollingPort "$serverPollingPort" -serverApiKey "$serverApiKey" -environment "$environment" -roll "$listeningRole" -space "$space" -workerpool "na" + } + + if($workers.ToLower() -eq "true") + { + ./polling.ps1 -deploymentTarget $False -version "$version" -serverUrl "$serverUrl" -serverPollingPort "$serverPollingPort" -serverApiKey "$serverApiKey" -environment "na" -roll "na" -space "$space" -workerpool "$workerPool" + } + } + + if($listening.ToLower() -eq "true") + { + if($deploymentTargets.ToLower() -eq "true") + { + ./listening.ps1 -deploymentTarget $True -version "$version" -serverUrl "$serverUrl" -serverApiKey "$serverApiKey" -environment "$environment" -roll "$pollingRole" -space "$space" -port $port.ToString() -serverthumbprint $serverThumbprint -workerpool "na" + $port = $port + 1 + } + + if($workers.ToLower() -eq "true") + { + ./listening.ps1 -deploymentTarget $False -version "$version" -serverUrl "$serverUrl" -serverApiKey "$serverApiKey" -environment "na" -roll "na" -space "$space" -port $port.ToString() -serverthumbprint $serverThumbprint -workerpool "$workerPool" + $port = $port + 1 + } + } +} diff --git a/testing/compatibility/vagrant/Linux/example.env b/testing/compatibility/vagrant/Linux/example.env new file mode 100644 index 000000000..74a4b7929 --- /dev/null +++ b/testing/compatibility/vagrant/Linux/example.env @@ -0,0 +1,14 @@ +serverUrl=http://MyMachine:8066 +serverThumbprint=ABCDEF123456 +serverPollingPort=10943 +serverApiKey=API-APIKEY01 +environment=Development +pollingRole=pollingBreadRoll +listeningRole=listeningBreadRoll +space=Default +tentacleVersions=5.0.15,6.0.645,6.1.1531,6.2.277,6.3.417,6.3.605 +polling=True +listening=True +deploymentTargets=True +workers=True +workerPool=Default Worker Pool \ No newline at end of file diff --git a/testing/compatibility/vagrant/Linux/install.ps1 b/testing/compatibility/vagrant/Linux/install.ps1 new file mode 100644 index 000000000..dabe4f63b --- /dev/null +++ b/testing/compatibility/vagrant/Linux/install.ps1 @@ -0,0 +1,9 @@ +param ([string] $version) + +$path = "/opt/octopus/tentacle$version/" + +If(!(test-path -PathType container $path)) +{ + apt-get install tentacle=$version + cp -R "/opt/octopus/tentacle/" $path +} \ No newline at end of file diff --git a/testing/compatibility/vagrant/Linux/listening.ps1 b/testing/compatibility/vagrant/Linux/listening.ps1 new file mode 100644 index 000000000..0f751631e --- /dev/null +++ b/testing/compatibility/vagrant/Linux/listening.ps1 @@ -0,0 +1,52 @@ +param ([string] $version, +[string] $serverUrl, +[string] $serverusername, +[string] $serverApiKey, +[string] $environment, +[string] $roll, +[string] $space, +[string] $port, +[string] $serverthumbprint, +[bool] $deploymentTarget, +[string] $workerPool) + +$hasSpaces = !$version.StartsWith("3.") +$path = "/opt/octopus/tentacle$version" +$hostname = hostname + +if($deploymentTarget){ + $typeName = "DeploymentTarget" + }else { + $typeName = "Worker" + } + +."$path/Tentacle" create-instance --instance "LinuxListening$typeName.$version" --config "/opt/OctopusListening$typeName$version/Tentacle.config" +."$path/Tentacle" new-certificate --instance "LinuxListening$typeName.$version" --if-blank +."$path/Tentacle" configure --instance "LinuxListening$typeName.$version" --reset-trust +."$path/Tentacle" configure --instance "LinuxListening$typeName.$version" --app "/opt/OctopusListening$typeName$version/Applications" --port "$port" --noListen "False" +."$path/Tentacle" configure --instance "LinuxListening$typeName.$version" --trust "$serverthumbprint" + +if($deploymentTarget) +{ + if($hasSpaces) + { + ."$path/Tentacle" register-with --instance "LinuxListening$typeName.$version" --server "$serverUrl" --name "LinuxListening$typeName.$version" --comms-style "TentaclePassive" --tentacle-comms-port "$port" --force --apiKey "$serverApiKey" --environment "$environment" --role "$roll" --space $space --publicHostName $hostname + } + else + { + ."$path/Tentacle" register-with --instance "LinuxListening$typeName.$version" --server "$serverUrl" --name "LinuxListening$typeName.$version" --comms-style "TentaclePassive" --tentacle-comms-port "$port" --force --apiKey "$serverApiKey" --environment "$environment" --role "$roll" --publicHostName $hostname + } +} +else +{ + if($hasSpaces) + { + ."$path/Tentacle" register-worker --instance "LinuxListening$typeName.$version" --server "$serverUrl" --name "LinuxListening$typeName.$version" --comms-style "TentaclePassive" --tentacle-comms-port "$port" --force --apiKey "$serverApiKey" --space $space --workerpool "$workerPool" --publicHostName $hostname + } + else + { + ."$path/Tentacle" register-worker --instance "LinuxListening$typeName.$version" --server "$serverUrl" --name "LinuxListening$typeName.$version" --comms-style "TentaclePassive" --tentacle-comms-port "$port" --force --apiKey "$serverApiKey" --workerpool "$workerPool" --publicHostName $hostname + } +} + +."$path/Tentacle" service --instance "LinuxListening$typeName.$version" --install --stop --start \ No newline at end of file diff --git a/testing/compatibility/vagrant/Linux/polling.ps1 b/testing/compatibility/vagrant/Linux/polling.ps1 new file mode 100644 index 000000000..aea971592 --- /dev/null +++ b/testing/compatibility/vagrant/Linux/polling.ps1 @@ -0,0 +1,49 @@ +param ([string] $version, +[string] $serverUrl, +[string] $serverPollingPort, +[string] $serverApiKey, +[string] $environment, +[string] $roll, +[string] $space, +[bool] $deploymentTarget, +[string] $workerPool) + +$hasSpaces = !$version.StartsWith("3.") +$path = "/opt/octopus/tentacle$version" + +if($deploymentTarget){ + $typeName = "DeploymentTarget" + }else { + $typeName = "Worker" + } + +."$path/Tentacle" create-instance --instance "LinuxPolling$typeName.$version" --config "/opt/OctopusPolling$typeName$version/Tentacle.config" +."$path/Tentacle" new-certificate --instance "LinuxPolling$typeName.$version" --if-blank +."$path/Tentacle" configure --instance "LinuxPolling$typeName.$version" --reset-trust +."$path/Tentacle" configure --instance "LinuxPolling$typeName.$version" --app "/opt/OctopusPolling$typeName$version/Applications" --port "10933" --noListen "True" +."$path/Tentacle" polling-proxy --instance "LinuxPolling$typeName.$version" --proxyEnable "False" + +if($deploymentTarget) +{ + if($hasSpaces) + { + ."$path/Tentacle" register-with --instance "LinuxPolling$typeName.$version" --server "$serverUrl" --name "LinuxPolling$typeName.$version" --comms-style "TentacleActive" --server-comms-port "$serverPollingPort" --force --apiKey "$serverApiKey" --environment "$environment" --role "$roll" --space $space + } + else + { + ."$path/Tentacle" register-with --instance "LinuxPolling$typeName.$version" --server "$serverUrl" --name "LinuxPolling$typeName.$version" --comms-style "TentacleActive" --server-comms-port "$serverPollingPort" --force --apiKey "$serverApiKey" --environment "$environment" --role "$roll" + } +} +else +{ + if($hasSpaces) + { + ."$path/Tentacle" register-worker --instance "LinuxPolling$typeName.$version" --server "$serverUrl" --name "LinuxPolling$typeName.$version" --comms-style "TentacleActive" --server-comms-port "$serverPollingPort" --force --apiKey "$serverApiKey" --space $space --workerpool "$workerPool" + } + else + { + ."$path/Tentacle" register-worker --instance "LinuxPolling$typeName.$version" --server "$serverUrl" --name "LinuxPolling$typeName.$version" --comms-style "TentacleActive" --server-comms-port "$serverPollingPort" --force --apiKey "$serverApiKey" --workerpool "$workerPool" + } +} + +."$path/Tentacle" service --instance "LinuxPolling$typeName.$version" --install --stop --start \ No newline at end of file diff --git a/testing/compatibility/vagrant/README.md b/testing/compatibility/vagrant/README.md new file mode 100644 index 000000000..73e07d693 --- /dev/null +++ b/testing/compatibility/vagrant/README.md @@ -0,0 +1,72 @@ +# Vagrant + +Setup a Windows or Linux VM with a set of Polling and Listening Deployment Targets and Workers + +> NOTE: For Windows host all commands should be run in the `./Windows` directory + +> NOTE: For Linux host all commands should be run in the `./Linux` directory + +## Install VirtualBox + +Install [VirtualBox](https://www.virtualbox.org/wiki/Downloads) + +> Hyper-V can be used on Windows but issues were experienced with Ubuntu networking and local DNS resolution. + +## Install Vagrant + +### Windows + +Install Vagrant + +`choco install vagrant -y` + +See [Install Vagrant](https://developer.hashicorp.com/vagrant/downloads) for alternative installation options + +### Linux + +See [Install Vagrant](https://developer.hashicorp.com/vagrant/downloads) + +## Install Vagrant Plugins + +`vagrant plugin install vagrant-env` + +## Configuration + +In the `./Windows` or `./Linux` directory Copy the file `example.env` to `.env` and modify the settings + +- **serverUrl** The url of Octopus Server to configure the Tentacles for e.g. `serverUrl=http://mymachine:8066` +- **serverThumbprint** The Octopus Server Thumbprint e.g. `serverThumbprint=ABCDEF123456` +- **serverPollingPort** The Octopus Server polling port e.g. `serverPollingPort=10943` +- **serverApiKey** The Octopus Server API Key e.g. `serverApiKey=API-APIKEY01` +- **environment** The environment to configure the Deployment Targets for e.g. `environment=Development` +- **pollingRole** The role to assign to the polling Deployment Targets e.g. `pollingRole=pollingBreadRoll` +- **listeningRole** The role to assign to the listening Deployment Targets e.g. `listeningRole=listeningBreadRoll` +- **space** the space to configure the Tentacle for e.g. `space=Default` Note: Versions of Tentacle prior to `4.x` had no concept of spaces so will be configured against the `Default` workspace +- **tentacleVersions** comma separated list of versions to install e.g. `tentacleVersions=3.25.0,4.0.7,5.0.15,6.0.645,6.1.1531,6.2.277,6.3.417,6.3.605` +- **polling** True to set-up polling Tentacles e.g. `polling=True` +- **listening** True to set-up listening Tentacles e.g. `listening=True` +- **deploymentTargets** True to set-up deployment targets e.g. `deploymentTargets=True` +- **workers** True to set-up workers e.g. `workers=True` +- **workerPool** The name of the worker pool to add workers to e.g. `workerPool=Default Worker Pool` + +`tentacleVersions` can be any version that is available on [Chocolatey](https://community.chocolatey.org/packages/OctopusDeploy.Tentacle#versionhistory) for Windows or [apt-get](https://octopus.com/docs/infrastructure/deployment-targets/tentacle/linux#installing-and-configuring-linux-tentacle) for Linux `apt-cache policy tentacle` + +## Running + +Create the VM and install the Tentacles with + +`vargrant up` + +> This can take 10+ minutes to create and provision the VM. More if you have a large number of Tentacle versions. + +Delete the VM with + +`vargant destroy` + +Re-run the provisioning scripts (when the VM is already created and running) with + +`vagrant provision` + +> It is safe to run `vagrant up` followed by `vagrant provision` however not all changes to `.env` parameters may be supported e.g. removing a `tentacleVersion` will not delete the removed version and deregister it with Server but adding a new version will add it successfully. + +> Issues were intermittently experience with mismatching certificates after running run `vagrant up` followed by `vagrant provision` \ No newline at end of file diff --git a/testing/compatibility/vagrant/Windows/Vagrantfile b/testing/compatibility/vagrant/Windows/Vagrantfile new file mode 100644 index 000000000..f4a3546ab --- /dev/null +++ b/testing/compatibility/vagrant/Windows/Vagrantfile @@ -0,0 +1,35 @@ +# -*- mode: ruby -*- +# vi: set ft=ruby : + +# All Vagrant configuration is done below. The "2" in Vagrant.configure +# configures the configuration version (we support older styles for +# backwards compatibility). Please don't change it unless you know what +# you're doing. +Vagrant.configure("2") do |config| + + config.vm.box = "gusztavvargadr/windows-11" + config.vm.network "public_network" + config.env.enable # Enable vagrant-env(.env) + + config.vm.synced_folder '.', '/vagrant', disabled: true + + config.vm.box_check_update = false + + config.vm.provider "virtualbox" do |vb| + vb.memory = 10240 + vb.cpus = 6 + end + + config.vm.provider :hyperv do |v, override| + v.maxmemory = 10240 + v.memory = 10240 + v.cpus = 6 + end + + config.vm.provision "file", source: "./install.ps1", destination: "C:/tmp/install.ps1" + config.vm.provision "file", source: "./polling.ps1", destination: "C:/tmp/polling.ps1" + config.vm.provision "file", source: "./listening.ps1", destination: "C:/tmp/listening.ps1" + + config.vm.provision :shell, path: "bootstrap.ps1", :args => "-serverUrl " + "'" + ENV['serverUrl'] + "'" + " -serverPollingPort " + ENV['serverPollingPort'] + " -serverApiKey " + "'" + ENV['serverApiKey'] + "'" + " -environment " + "'" + ENV['environment'] + "'" + " -listeningRole " + "'" + ENV['listeningRole'] + "'" + " -pollingRole " + "'" + ENV['pollingRole'] + "'" + " -space " + "'" + ENV['space'] + "'" + " -tentacleVersions " + "'" + ENV['tentacleVersions'] + "'" + " -listening " + ENV['listening'] + " -polling " + ENV['polling'] + " -serverThumbprint " + "'" + ENV['serverThumbprint'] + "'" + " -deploymentTargets " + ENV['deploymentTargets'] + " -workers " + ENV['workers'] + " -workerPool " + "'" + ENV['workerPool'] + "'" + +end diff --git a/testing/compatibility/vagrant/Windows/bootstrap.ps1 b/testing/compatibility/vagrant/Windows/bootstrap.ps1 new file mode 100644 index 000000000..388b1e8c2 --- /dev/null +++ b/testing/compatibility/vagrant/Windows/bootstrap.ps1 @@ -0,0 +1,73 @@ +param([string] $serverUrl, +[string] $serverPollingPort, +[string] $serverApiKey, +[string] $environment, +[string] $pollingRole, +[string] $listeningRole, +[string] $space, +[string] $tentacleVersions, +[string] $listening, +[string] $polling, +[string] $deploymentTargets, +[string] $workers, +[string] $serverThumbprint, +[string] $workerPool) + +echo "serverUrl:$serverUrl" +echo "serverPollingPort:$serverPollingPort" +echo "serverApiKey:$serverApiKey" +echo "environment:$environment" +echo "listeningRole:$listeningRole" +echo "pollingRole:$pollingRole" +echo "space:$space" +echo "workerPool:$workerPool" + +Set-NetFirewallProfile -Profile Domain,Public,Private -Enabled False + +$versions = $tentacleVersions.Split(",") + +echo "verisons:$versions" +echo "listening:$listening" +echo "polling:$polling" + +echo "deploymentTargets:$deploymentTargets" +echo "workers:$workers" + +cd c:\tmp\ + +$port = 10940 + +foreach ( $version in $versions ) +{ + .\install.ps1 -version $version + + if($polling.ToLower() -eq "true") + { + if($deploymentTargets.ToLower() -eq "true") + { + .\polling.ps1 -deploymentTarget $True -version "$version" -serverUrl "$serverUrl" -serverPollingPort "$serverPollingPort" -serverApiKey "$serverApiKey" -environment "$environment" -roll "$listeningRole" -space "$space" -workerpool "na" + } + + if($workers.ToLower() -eq "true") + { + .\polling.ps1 -deploymentTarget $False -version "$version" -serverUrl "$serverUrl" -serverPollingPort "$serverPollingPort" -serverApiKey "$serverApiKey" -environment "na" -roll "na" -space "$space" -workerpool "$workerPool" + } + } + + if($listening.ToLower() -eq "true") + { + if($deploymentTargets.ToLower() -eq "true") + { + .\listening.ps1 -deploymentTarget $True -version "$version" -serverUrl "$serverUrl" -serverApiKey "$serverApiKey" -environment "$environment" -roll "$pollingRole" -space "$space" -port $port.ToString() -serverthumbprint $serverThumbprint -workerpool "na" + $port = $port + 1 + } + + if($workers.ToLower() -eq "true") + { + .\listening.ps1 -deploymentTarget $False -version "$version" -serverUrl "$serverUrl" -serverApiKey "$serverApiKey" -environment "na" -roll "na" -space "$space" -port $port.ToString() -serverthumbprint $serverThumbprint -workerpool "$workerPool" + $port = $port + 1 + } + } +} + +# Restart-Service -Name "OctopusDeploy Tentacle:*" -Force -Verbose \ No newline at end of file diff --git a/testing/compatibility/vagrant/Windows/example.env b/testing/compatibility/vagrant/Windows/example.env new file mode 100644 index 000000000..ebbef1015 --- /dev/null +++ b/testing/compatibility/vagrant/Windows/example.env @@ -0,0 +1,14 @@ +serverUrl=http://MyMachine.local:8066 +serverThumbprint=ABCDEF123456 +serverPollingPort=10943 +serverApiKey=API-APIKEY01 +environment=Development +pollingRole=pollingBreadRoll +listeningRole=listeningBreadRoll +space=Default +tentacleVersions=3.25.0,4.0.7,5.0.15,6.0.645,6.1.1531,6.2.277,6.3.417,6.3.605 +polling=True +listening=True +deploymentTargets=True +workers=True +workerPool=Default Worker Pool \ No newline at end of file diff --git a/testing/compatibility/vagrant/Windows/install.ps1 b/testing/compatibility/vagrant/Windows/install.ps1 new file mode 100644 index 000000000..4eaf8febf --- /dev/null +++ b/testing/compatibility/vagrant/Windows/install.ps1 @@ -0,0 +1,9 @@ +param ([string] $version) + +$path = "C:\Program Files\Octopus Deploy\Tentacle$version\" + +If(!(test-path -PathType container $path)) +{ + choco install octopusdeploy.tentacle --version=$version --force -y + xcopy /E /I "C:\Program Files\Octopus Deploy\Tentacle\" $path +} \ No newline at end of file diff --git a/testing/compatibility/vagrant/Windows/listening.ps1 b/testing/compatibility/vagrant/Windows/listening.ps1 new file mode 100644 index 000000000..b2a394c72 --- /dev/null +++ b/testing/compatibility/vagrant/Windows/listening.ps1 @@ -0,0 +1,52 @@ +param ([string] $version, +[string] $serverUrl, +[string] $serverusername, +[string] $serverApiKey, +[string] $environment, +[string] $roll, +[string] $space, +[string] $port, +[string] $serverthumbprint, +[bool] $deploymentTarget, +[string] $workerPool) + +$hasSpaces = !$version.StartsWith("3.") +$path = "C:\Program Files\Octopus Deploy\Tentacle$version" +$hostname = $env:computername + +if($deploymentTarget){ + $typeName = "DeploymentTarget" + }else { + $typeName = "Worker" + } + +."$path\Tentacle.exe" create-instance --instance "WindowsListening$typeName.$version" --config "C:\OctopusListening$typeName$version\Tentacle.config" +."$path\Tentacle.exe" new-certificate --instance "WindowsListening$typeName.$version" --if-blank +."$path\Tentacle.exe" configure --instance "WindowsListening$typeName.$version" --reset-trust +."$path\Tentacle.exe" configure --instance "WindowsListening$typeName.$version" --app "C:\OctopusListening$typeName$version\Applications" --port "$port" --noListen "False" +."$path\Tentacle.exe" configure --instance "WindowsListening$typeName.$version" --trust "$serverthumbprint" + +if($deploymentTarget) +{ + if($hasSpaces) + { + ."$path\Tentacle.exe" register-with --instance "WindowsListening$typeName.$version" --server "$serverUrl" --name "WindowsListening$typeName.$version" --comms-style "TentaclePassive" --tentacle-comms-port "$port" --force --apiKey "$serverApiKey" --environment "$environment" --role "$roll" --space $space --publicHostName $hostname + } + else + { + ."$path\Tentacle.exe" register-with --instance "WindowsListening$typeName.$version" --server "$serverUrl" --name "WindowsListening$typeName.$version" --comms-style "TentaclePassive" --tentacle-comms-port "$port" --force --apiKey "$serverApiKey" --environment "$environment" --role "$roll" --publicHostName $hostname + } +} +else +{ + if($hasSpaces) + { + ."$path\Tentacle.exe" register-worker --instance "WindowsListening$typeName.$version" --server "$serverUrl" --name "WindowsListening$typeName.$version" --comms-style "TentaclePassive" --tentacle-comms-port "$port" --force --apiKey "$serverApiKey" --space $space --workerpool "$workerPool" --publicHostName $hostname + } + else + { + ."$path\Tentacle.exe" register-worker --instance "WindowsListening$typeName.$version" --server "$serverUrl" --name "WindowsListening$typeName.$version" --comms-style "TentaclePassive" --tentacle-comms-port "$port" --force --apiKey "$serverApiKey" --workerpool "$workerPool" --publicHostName $hostname + } +} + +."$path\Tentacle.exe" service --instance "WindowsListening$typeName.$version" --install --stop --start \ No newline at end of file diff --git a/testing/compatibility/vagrant/Windows/polling.ps1 b/testing/compatibility/vagrant/Windows/polling.ps1 new file mode 100644 index 000000000..e5a03e123 --- /dev/null +++ b/testing/compatibility/vagrant/Windows/polling.ps1 @@ -0,0 +1,49 @@ +param ([string] $version, +[string] $serverUrl, +[string] $serverPollingPort, +[string] $serverApiKey, +[string] $environment, +[string] $roll, +[string] $space, +[bool] $deploymentTarget, +[string] $workerPool) + +$hasSpaces = !$version.StartsWith("3.") +$path = "C:\Program Files\Octopus Deploy\Tentacle$version" + +if($deploymentTarget){ + $typeName = "DeploymentTarget" + }else { + $typeName = "Worker" + } + +."$path\Tentacle.exe" create-instance --instance "WindowsPolling$typeName.$version" --config "C:\OctopusPolling$typeName$version\Tentacle.config" +."$path\Tentacle.exe" new-certificate --instance "WindowsPolling$typeName.$version" --if-blank +."$path\Tentacle.exe" configure --instance "WindowsPolling$typeName.$version" --reset-trust +."$path\Tentacle.exe" configure --instance "WindowsPolling$typeName.$version" --app "C:\OctopusPolling$typeName$version\Applications" --port "10933" --noListen "True" +."$path\Tentacle.exe" polling-proxy --instance "WindowsPolling$typeName.$version" --proxyEnable "False" + +if($deploymentTarget) +{ + if($hasSpaces) + { + ."$path\Tentacle.exe" register-with --instance "WindowsPolling$typeName.$version" --server "$serverUrl" --name "WindowsPolling$typeName.$version" --comms-style "TentacleActive" --server-comms-port "$serverPollingPort" --force --apiKey "$serverApiKey" --environment "$environment" --role "$roll" --space $space + } + else + { + ."$path\Tentacle.exe" register-with --instance "WindowsPolling$typeName.$version" --server "$serverUrl" --name "WindowsPolling$typeName.$version" --comms-style "TentacleActive" --server-comms-port "$serverPollingPort" --force --apiKey "$serverApiKey" --environment "$environment" --role "$roll" + } +} +else +{ + if($hasSpaces) + { + ."$path\Tentacle.exe" register-worker --instance "WindowsPolling$typeName.$version" --server "$serverUrl" --name "WindowsPolling$typeName.$version" --comms-style "TentacleActive" --server-comms-port "$serverPollingPort" --force --apiKey "$serverApiKey" --space $space --workerpool "$workerPool" + } + else + { + ."$path\Tentacle.exe" register-worker --instance "WindowsPolling$typeName.$version" --server "$serverUrl" --name "WindowsPolling$typeName.$version" --comms-style "TentacleActive" --server-comms-port "$serverPollingPort" --force --apiKey "$serverApiKey" --workerpool "$workerPool" + } +} + +."$path\Tentacle.exe" service --instance "WindowsPolling$typeName.$version" --install --stop --start \ No newline at end of file