├── .config └── dotnet-tools.json ├── .dockerignore ├── .gitattributes ├── .github ├── CODEOWNERS ├── ISSUE_TEMPLATE │ └── new_issue.yml ├── pull_request_template.md └── workflows │ ├── approve-renovate-pull-request.yml │ └── update-dependencies.yml ├── .gitignore ├── .nuke ├── build.schema.json └── parameters.json ├── LICENSE.txt ├── NuGet.Config ├── README.md ├── _artifacts.upload.filespec.json ├── build-k8s-docker-local.ps1 ├── build.cmd ├── build.ps1 ├── build.sh ├── build ├── .editorconfig ├── Build.Pack.cs ├── Build.Tests.cs ├── Build.cs ├── Configuration.cs ├── Git.cs ├── Logging.cs ├── ModifiableFileWithRestoreContentsOnDispose.cs ├── Signing.cs ├── TestConfigurationOnLinuxDistribution.cs ├── _build.csproj ├── _build.csproj.DotSettings ├── docs │ └── build-and-release.md └── test-scripts │ └── integration │ ├── common │ ├── dotnet-install.sh │ ├── run-integration-tests-on-vm-agents.sh │ ├── set-dotnet-envvars.sh │ └── setup-vm-agent.sh │ └── run-kubernetes-tests-on-vm-agents.sh ├── certificates └── OctopusDevelopment.pfx ├── credits ├── credits.md └── credits.md.template ├── docker-compose.build-dev.yml ├── docker-compose.build.yml ├── docker-compose.yml ├── docker ├── Tests │ ├── OctopusRegistration.Tests.ps1 │ ├── OpenPorts.Tests.ps1 │ └── VolumeMapping.Tests.ps1 ├── Volumes │ ├── listening-tentacle │ │ ├── Applications │ │ │ └── .gitignore │ │ └── TentacleHome │ │ │ └── .gitignore │ ├── octopus-server │ │ ├── Import │ │ │ ├── Environments │ │ │ │ └── Development.json │ │ │ └── metadata.json │ │ ├── MasterKey │ │ │ └── .gitignore │ │ └── Repository │ │ │ ├── .gitignore │ │ │ ├── Serilog.Sinks.TextWriter │ │ │ └── Serilog.Sinks.TextWriter.2.1.0.nupkg │ │ │ └── Spaces-1 │ │ │ └── feeds-builtin │ │ │ └── Serilog.Sinks.TextWriter │ │ │ └── Serilog.Sinks.TextWriter.2.1.0.nupkg │ └── polling-tentacle │ │ ├── Applications │ │ └── .gitignore │ │ └── TentacleHome │ │ └── .gitignore ├── common.ps1 ├── kubernetes-agent-tentacle │ ├── Dockerfile │ ├── bootstrapRunner │ │ ├── bootstrapRunner.go │ │ └── go.mod │ ├── dev │ │ ├── Dockerfile │ │ └── scripts │ │ │ ├── bootstrap.sh │ │ │ └── start-debugger.sh │ └── scripts │ │ ├── configure-and-run.sh │ │ └── register.sh ├── linux │ ├── Dockerfile │ ├── install-scripts │ │ └── install-docker.sh │ └── scripts │ │ ├── configure-and-run.sh │ │ ├── configure-tentacle.sh │ │ ├── dockerd-entrypoint.sh │ │ └── run-tentacle.sh ├── readme.md ├── run-tests.ps1 └── windows │ ├── Dockerfile │ └── Scripts │ ├── build-common.ps1 │ ├── common.ps1 │ ├── configure-and-run-tentacle-wrapper.ps1 │ ├── configure-tentacle.ps1 │ ├── healthcheck-tentacle.ps1 │ ├── octopus-common.ps1 │ └── run-tentacle.ps1 ├── docs ├── artifactory.png ├── chocolatey.png ├── downloads-page.png ├── meaningful-change.md ├── octopus-deploy.png ├── rollout.md ├── slipway-create-release.png ├── slipway.png └── tc-create-release.png ├── global.json ├── installer ├── Installer.1.1.dotCover ├── Installer.sln ├── Octopus.Tentacle.Installer │ ├── Octopus.Tentacle.Installer.wixproj │ ├── Product.wxs │ └── Tentacle.Generated.wxs └── Resources │ ├── Banner.bmp │ ├── Dialog.bmp │ ├── Icon.ico │ ├── Information.ico │ ├── License.rtf │ └── Warning.ico ├── k8s-agent-debug-cluster-config ├── k8s-agent-debug-cluster.yaml ├── launchSettings.template.json ├── local-persistent-volume.yaml └── local-storage-class.yaml ├── linux-packages ├── content │ ├── after-install.sh │ ├── before-uninstall.sh │ └── configure-tentacle.sh ├── packaging-scripts │ ├── create-linux-packages.sh │ ├── package.sh │ └── unsigned │ │ ├── create-linux-packages.sh │ │ └── package.sh └── test-scripts │ ├── install-package.sh │ └── test-linux-package.sh ├── octoversion.json ├── renovate-config.js ├── scripts ├── Harden-InstallationDirectory.ps1 └── deploy │ ├── test-linux-package-from-feed-in-dists.sh │ └── test-linux-package-from-feed.sh ├── setup-k8s-agent-for-local-debug.sh ├── signtool.exe ├── source ├── .run │ ├── Build and Push Kubernetes Tentacle docker image (powershell, amd64).run.xml │ └── Build and Push Kubernetes Tentacle docker image (shell, arm64).run.xml ├── Chocolatey-Net-Framework │ ├── OctopusDeploy.Tentacle.nuspec │ └── chocolateyInstall.ps1 ├── Chocolatey-Self-Contained │ ├── OctopusDeploy.Tentacle.SelfContained.nuspec │ └── chocolateyInstall.ps1 ├── Octopus.Manager.Tentacle.Tests │ ├── ApplicationStartupSanityCheckFixture.cs │ ├── AssemblyInfo.cs │ ├── Builders │ │ ├── SetupTentacleWizardModelBuilder.cs │ │ └── TelemetryServiceBuilder.cs │ ├── ConfiguringTentacleServiceFixture.cs │ ├── InstanceSelectorFixture.cs │ ├── Octopus.Manager.Tentacle.Tests.csproj │ ├── Utils │ │ ├── CommandLineInvocationExtension.cs │ │ └── TentacleManagerInstanceIdentifierServiceFixture.cs │ └── WizardFixtures │ │ ├── DeleteWizardFixture.cs │ │ ├── ProxyWizardFixture.cs │ │ └── SetupTentacleWizardFixture.cs ├── Octopus.Manager.Tentacle │ ├── App.config │ ├── App.xaml │ ├── App.xaml.cs │ ├── Controls │ │ ├── AutoCompleteTagControl.xaml │ │ ├── AutoCompleteTagControl.xaml.cs │ │ ├── ControlGroup.cs │ │ ├── ErrorMessage.cs │ │ ├── ErrorPanelControl.xaml │ │ ├── ErrorPanelControl.xaml.cs │ │ ├── ImageLink.cs │ │ ├── PasswordEditor.cs │ │ ├── RetinaImage.cs │ │ └── ServiceWatcher.cs │ ├── Converters │ │ ├── BooleanToVisibilityConverter.cs │ │ ├── BooleanToYesNoConverter.cs │ │ ├── CapitalizeFirstLetterConverter.cs │ │ ├── EnumBooleanConverter.cs │ │ ├── EnumToVisibilityConverter.cs │ │ ├── InverseBooleanConverter.cs │ │ ├── InverseBooleanToVisibilityConverter.cs │ │ ├── StringEmptyConverter.cs │ │ └── StringToVisibilityConverter.cs │ ├── DeleteWizard │ │ ├── DeleteWizardModel.cs │ │ └── Views │ │ │ ├── DeleteWelcome.cs │ │ │ └── DeleteWelcome.xaml │ ├── Dialogs │ │ ├── EditTrustedOctopusDialog.xaml │ │ ├── EditTrustedOctopusDialog.xaml.cs │ │ ├── ErrorDialog.cs │ │ ├── ErrorDialog.xaml │ │ ├── NewInstanceNameDialog.cs │ │ ├── NewInstanceNameDialog.xaml │ │ ├── RunProcessDialog.cs │ │ ├── RunProcessDialog.xaml │ │ ├── ServerConnectionDialog.xaml │ │ ├── ServerConnectionDialog.xaml.cs │ │ ├── SetPasswordDialog.cs │ │ ├── SetPasswordDialog.xaml │ │ ├── ViewScriptDialog.cs │ │ └── ViewScriptDialog.xaml │ ├── Infrastructure │ │ ├── DispatchHelper.cs │ │ ├── ElevationHelper.cs │ │ ├── ICanHaveSensitiveValues.cs │ │ ├── IHaveServices.cs │ │ ├── IScriptableViewModel.cs │ │ ├── OctoService.cs │ │ ├── TelemetryEvent.cs │ │ ├── TelemetryEventBatch.cs │ │ ├── TentacleManagerScriptExecuted.cs │ │ ├── TextBoxLogger.cs │ │ ├── UnhandledErrorTrapper.cs │ │ └── ViewModel.cs │ ├── Octopus.Manager.Tentacle.csproj │ ├── PreReq │ │ ├── IPrerequisite.cs │ │ ├── IPrerequisiteProfile.cs │ │ ├── PowerShellPrerequisite.cs │ │ ├── PreReqWindow.cs │ │ ├── PreReqWindow.xaml │ │ ├── PrerequisiteCheckResult.cs │ │ └── TentaclePrerequisiteProfile.cs │ ├── Properties │ │ ├── Annotations.cs │ │ ├── AssemblyInfo.cs │ │ ├── Icon.ico │ │ ├── Resources.Designer.cs │ │ ├── Resources.resx │ │ ├── Settings.Designer.cs │ │ └── Settings.settings │ ├── Proxy │ │ ├── ProxyConfigurationControl.xaml │ │ ├── ProxyConfigurationControl.xaml.cs │ │ ├── ProxyConfigurationDialog.xaml │ │ ├── ProxyConfigurationDialog.xaml.cs │ │ ├── ProxyConfigurationTab.cs │ │ ├── ProxyConfigurationTab.xaml │ │ ├── ProxyWizardModel.cs │ │ └── ProxyWizardModelWrapper.cs │ ├── Resources │ │ ├── Icon.ico │ │ ├── Images │ │ │ ├── TentacleActive.png │ │ │ ├── TentaclePassive.png │ │ │ ├── Warning-ico-dropshadow.png │ │ │ ├── Warning-ico-dropshadow@2x.png │ │ │ ├── Warning-ico-dropshadow@3x.png │ │ │ ├── Warning-ico-dropshadow@4x.png │ │ │ ├── alert-error.png │ │ │ ├── alert-error@2x.png │ │ │ ├── alert-error@3x.png │ │ │ ├── alert-error@4x.png │ │ │ ├── alert.png │ │ │ ├── alert@2x.png │ │ │ ├── alert@3x.png │ │ │ ├── alert@4x.png │ │ │ ├── button_circle_blue_right.png │ │ │ ├── button_circle_blue_right@2x.png │ │ │ ├── button_circle_blue_right@3x.png │ │ │ ├── button_circle_blue_right@4x.png │ │ │ ├── button_rounded_green_delete.png │ │ │ ├── button_rounded_green_delete@2x.png │ │ │ ├── button_rounded_green_delete@3x.png │ │ │ ├── button_rounded_green_delete@4x.png │ │ │ ├── button_rounded_green_last.png │ │ │ ├── button_rounded_green_last@2x.png │ │ │ ├── button_rounded_green_last@3x.png │ │ │ ├── button_rounded_green_last@4x.png │ │ │ ├── button_rounded_green_next.png │ │ │ ├── button_rounded_green_next@2x.png │ │ │ ├── button_rounded_green_next@3x.png │ │ │ ├── button_rounded_green_next@4x.png │ │ │ ├── button_rounded_green_right.png │ │ │ ├── button_rounded_green_right@2x.png │ │ │ ├── button_rounded_green_right@3x.png │ │ │ ├── button_rounded_green_right@4x.png │ │ │ ├── button_rounded_orange_next.png │ │ │ ├── button_rounded_orange_next@2x.png │ │ │ ├── button_rounded_orange_next@3x.png │ │ │ ├── button_rounded_orange_next@4x.png │ │ │ ├── clipboard-export.png │ │ │ ├── clipboard-export@2x.png │ │ │ ├── clipboard-export@3x.png │ │ │ ├── clipboard-export@4x.png │ │ │ ├── database-export.png │ │ │ ├── database-export@2x.png │ │ │ ├── database-export@3x.png │ │ │ ├── database-export@4x.png │ │ │ ├── database-favorite2.png │ │ │ ├── database-favorite2@2x.png │ │ │ ├── database-favorite2@3x.png │ │ │ ├── database-favorite2@4x.png │ │ │ ├── database-import.png │ │ │ ├── database-import@2x.png │ │ │ ├── database-import@3x.png │ │ │ ├── database-import@4x.png │ │ │ ├── database-up.png │ │ │ ├── database-up@2x.png │ │ │ ├── database-up@3x.png │ │ │ ├── database-up@4x.png │ │ │ ├── database_restore.png │ │ │ ├── database_restore@2x.png │ │ │ ├── database_restore@3x.png │ │ │ ├── database_restore@4x.png │ │ │ ├── delete.png │ │ │ ├── delete@2x.png │ │ │ ├── delete@3x.png │ │ │ ├── delete@4x.png │ │ │ ├── help.png │ │ │ ├── help@2x.png │ │ │ ├── help@3x.png │ │ │ ├── help@4x.png │ │ │ ├── history.png │ │ │ ├── history@2x.png │ │ │ ├── history@3x.png │ │ │ ├── history@4x.png │ │ │ ├── internet-edit.png │ │ │ ├── internet-edit@2x.png │ │ │ ├── internet-edit@3x.png │ │ │ ├── internet-edit@4x.png │ │ │ ├── internet_browse.png │ │ │ ├── internet_browse@2x.png │ │ │ ├── internet_browse@3x.png │ │ │ ├── internet_browse@4x.png │ │ │ ├── key.png │ │ │ ├── key@2x.png │ │ │ ├── key@3x.png │ │ │ ├── key@4x.png │ │ │ ├── nav_blue_right.png │ │ │ ├── nav_blue_right@2x.png │ │ │ ├── nav_blue_right@3x.png │ │ │ ├── nav_blue_right@4x.png │ │ │ ├── ok.png │ │ │ ├── ok@2x.png │ │ │ ├── ok@3x.png │ │ │ ├── ok@4x.png │ │ │ ├── ok_button.png │ │ │ ├── ok_button@2x.png │ │ │ ├── ok_button@3x.png │ │ │ ├── ok_button@4x.png │ │ │ ├── server_network-internet.png │ │ │ ├── server_network-internet@2x.png │ │ │ ├── server_network-internet@3x.png │ │ │ ├── server_network-internet@4x.png │ │ │ ├── visitor_man-internet.png │ │ │ ├── visitor_man-internet@2x.png │ │ │ ├── visitor_man-internet@3x.png │ │ │ ├── visitor_man-internet@4x.png │ │ │ ├── warning.png │ │ │ ├── warning@2x.png │ │ │ ├── warning@3x.png │ │ │ └── warning@4x.png │ │ ├── Logo-Small-White-Text.png │ │ ├── Styles.xaml │ │ ├── logo-1x.png │ │ └── logo-2x.png │ ├── Shell │ │ ├── ITab.cs │ │ ├── ITabWithNotifications.cs │ │ ├── InstanceSelectionModel.cs │ │ ├── ShellView.cs │ │ ├── ShellView.xaml │ │ ├── ShellViewModel.cs │ │ ├── TabView.cs │ │ ├── TabbedWizard.cs │ │ └── TabbedWizard.xaml │ ├── TentacleConfiguration │ │ ├── InstanceConfigurationLoader.cs │ │ ├── SetupWizard │ │ │ ├── ReviewAndRunScriptTabViewModel.cs │ │ │ ├── SetupTentacleWizardModel.cs │ │ │ └── Views │ │ │ │ ├── CommunicationStyleTab.xaml │ │ │ │ ├── CommunicationStyleTab.xaml.cs │ │ │ │ ├── MachineType.xaml │ │ │ │ ├── MachineType.xaml.cs │ │ │ │ ├── OctopusServerConnectionTab.xaml │ │ │ │ ├── OctopusServerConnectionTab.xaml.cs │ │ │ │ ├── ReviewAndRunScriptTabView.cs │ │ │ │ ├── ReviewAndRunScriptTabView.xaml │ │ │ │ ├── StorageTab.xaml │ │ │ │ ├── StorageTab.xaml.cs │ │ │ │ ├── TentacleActiveDetailsTab.xaml │ │ │ │ ├── TentacleActiveDetailsTab.xaml.cs │ │ │ │ ├── TentaclePassiveTab.xaml │ │ │ │ ├── TentaclePassiveTab.xaml.cs │ │ │ │ ├── WelcomeTab.xaml │ │ │ │ └── WelcomeTab.xaml.cs │ │ ├── TentacleManager │ │ │ ├── TentacleManagerModel.cs │ │ │ ├── TentacleManagerView.xaml │ │ │ └── TentacleManagerView.xaml.cs │ │ └── TentacleManagerModule.cs │ ├── TentacleManager.cs │ ├── Util │ │ ├── BrowserHelper.cs │ │ ├── CommandLine.cs │ │ ├── PasswordBoxAssistant.cs │ │ ├── RelayCommand.cs │ │ ├── StringExtensions.cs │ │ ├── TelemetryService.cs │ │ └── TentacleManagerInstanceIdentifierService.cs │ ├── Validators │ │ ├── BindingProxy.cs │ │ └── InstanceName.cs │ └── app.manifest ├── Octopus.Tentacle.Client.Tests │ ├── DefaultScriptObserverBackoffStrategyTests.cs │ ├── ExecuteShellScriptCommandBuilderTests.cs │ ├── Octopus.Tentacle.Client.Tests.csproj │ ├── PollingTentacleScriptObserverBackoffStrategyTests.cs │ ├── RpcCallExecutorFixture.cs │ └── RpcCallRetryHandlerFixture.cs ├── Octopus.Tentacle.Client │ ├── AssemblyInfo.cs │ ├── Capabilities │ │ └── CapabilitiesResponseV2ExtensionMethods.cs │ ├── EventDriven │ │ └── CommandContext.cs │ ├── ExceptionExtensionMethods.cs │ ├── Execution │ │ ├── RpcCallExecutor.cs │ │ └── RpcCallExecutorFactory.cs │ ├── ITentacleClient.cs │ ├── ITentacleServiceDecoratorFactory.cs │ ├── Kubernetes │ │ └── KubernetesCapabilitiesResponseV2ExtensionMethods.cs │ ├── Observability │ │ ├── ClientOperationMetricsBuilder.cs │ │ ├── NonThrowingTentacleClientObserver.cs │ │ ├── RpcCallMetricsBuilder.cs │ │ └── TentacleClientObserverExtensionMethods.cs │ ├── Octopus.Tentacle.Client.csproj │ ├── Retries │ │ ├── RpcCallRetryHandler.cs │ │ ├── RpcCallRetryPolicyBuilder.cs │ │ ├── RpcRetrySettings.cs │ │ ├── TaskCompletionResult.cs │ │ └── TaskExtensionMethods.cs │ ├── ScriptExecutor.cs │ ├── Scripts │ │ ├── DefaultScriptObserverBackoffStrategy.cs │ │ ├── ExponentialBackoff.cs │ │ ├── HalibutClientExceptionExtensionMethods.cs │ │ ├── IScriptExecutor.cs │ │ ├── IScriptObserverBackoffStrategy.cs │ │ ├── KubernetesScriptServiceV1Executor.cs │ │ ├── Models │ │ │ ├── Builders │ │ │ │ ├── ExecuteKubernetesScriptCommandBuilder.cs │ │ │ │ ├── ExecuteScriptCommandBuilder.cs │ │ │ │ └── ExecuteShellScriptCommandBuilder.cs │ │ │ ├── ExecuteKubernetesScriptCommand.cs │ │ │ ├── ExecuteScriptCommand.cs │ │ │ ├── ExecuteShellScriptCommand.cs │ │ │ ├── KubernetesImageConfiguration.cs │ │ │ ├── ScriptExecutionResult.cs │ │ │ ├── ScriptExecutionStatus.cs │ │ │ └── ScriptIsolationConfiguration.cs │ │ ├── ObservingScriptOrchestrator.cs │ │ ├── OnScriptCompleted.cs │ │ ├── OnScriptStatusResponseReceived.cs │ │ ├── PollingTentacleScriptObserverBackoffStrategy.cs │ │ ├── ScriptExecutorFactory.cs │ │ ├── ScriptObserverBackoffStrategy.cs │ │ ├── ScriptOperationExecutionResult.cs │ │ ├── ScriptServiceV1Executor.cs │ │ ├── ScriptServiceV2Executor.cs │ │ ├── ScriptServiceVersion.cs │ │ ├── ScriptServiceVersionSelector.cs │ │ ├── TaskExtensionMethods.cs │ │ └── UnsafeStartAttemptException.cs │ ├── ServiceHelpers │ │ └── AllClients.cs │ ├── StartScriptIsBeingReAttempted.cs │ ├── TentacleClient.cs │ └── TentacleClientOptions.cs ├── Octopus.Tentacle.CommonTestUtils │ ├── Builders │ │ ├── ScriptBuilder.cs │ │ ├── StartScriptCommandBuilder.cs │ │ ├── StartScriptCommandV2Builder.cs │ │ └── StartScriptCommandV2BuilderExtensionMethods.cs │ ├── Certificates │ │ ├── Server.pfx │ │ └── Tentacle.pfx │ ├── DataStreamExtensionMethods.cs │ ├── Diagnostics │ │ ├── InMemoryLog.cs │ │ ├── InMemoryLogAssertionExtensionMethods.cs │ │ └── TestConsoleLog.cs │ ├── Logging │ │ └── StringBuilderLogEventSink.cs │ ├── LoggingUtils.cs │ ├── Octopus.Tentacle.CommonTestUtils.csproj │ ├── OctopusPackageDownloader.cs │ ├── PlatformDetection.cs │ ├── TemporaryDirectory.cs │ ├── TestCertificates.cs │ └── TestTentacleClientObserver.cs ├── Octopus.Tentacle.Contracts │ ├── Builders │ │ └── UniqueScriptTicketBuilder.cs │ ├── CancelScriptCommand.cs │ ├── Capabilities │ │ ├── BackwardsCompatibleAsyncCapabilitiesV2Decorator.cs │ │ ├── BackwardsCompatibleAsyncClientCapabilitiesV2Decorator.cs │ │ ├── BackwardsCompatibleCapabilitiesV2Decorator.cs │ │ ├── BackwardsCompatibleCapabilitiesV2Helper.cs │ │ ├── CapabilitiesResponseV2.cs │ │ ├── ICapabilitiesServiceV2.cs │ │ └── ICapabilitiesServiceV2ExtensionMethods.cs │ ├── ClientServices │ │ ├── IAsyncClientCapabilitiesServiceV2.cs │ │ ├── IAsyncClientFileTransferService.cs │ │ ├── IAsyncClientKubernetesScriptServiceV1.cs │ │ ├── IAsyncClientScriptService.cs │ │ └── IAsyncClientScriptServiceV2.cs │ ├── CompleteScriptCommand.cs │ ├── IFileTransferService.cs │ ├── IScriptService.cs │ ├── KubernetesScriptServiceV1 │ │ ├── CancelKubernetesScriptCommandV1.cs │ │ ├── CompleteKubernetesScriptCommandV1.cs │ │ ├── IKubernetesScriptServiceV1.cs │ │ ├── KubernetesScriptStatusRequestV1.cs │ │ ├── KubernetesScriptStatusResponseV1.cs │ │ ├── PodImageConfigurationV1.cs │ │ └── StartKubernetesScriptCommandV1.cs │ ├── Legacy │ │ ├── AssemblyMappingSerializationBinderDecorator.cs │ │ ├── HalibutRuntimeExtensionMethods.cs │ │ ├── MessageSerializerBuilderExtensionMethods.cs │ │ ├── NamespaceMappingSerializationBinderDecorator.cs │ │ └── ReMappedLegacyTypes.cs │ ├── Logging │ │ └── ITentacleClientTaskLog.cs │ ├── Observability │ │ ├── ClientOperationMetrics.cs │ │ ├── ITentacleClientObserver.cs │ │ ├── NoTentacleClientObserver.cs │ │ ├── RpcCall.cs │ │ ├── RpcCallMetrics.cs │ │ └── TimedOperation.cs │ ├── Octopus.Tentacle.Contracts.csproj │ ├── ScriptExitCodes.cs │ ├── ScriptFile.cs │ ├── ScriptIsolationLevel.cs │ ├── ScriptServiceV2 │ │ ├── CancelScriptCommandV2.cs │ │ ├── CompleteScriptCommandV2.cs │ │ ├── IScriptServiceV2.cs │ │ ├── ScriptStatusRequestV2.cs │ │ ├── ScriptStatusResponseV2.cs │ │ └── StartScriptCommandV2.cs │ ├── ScriptStatus.cs │ ├── ScriptStatusRequest.cs │ ├── ScriptStatusResponse.cs │ ├── ScriptTicket.cs │ ├── ScriptType.cs │ ├── Services │ │ ├── Capabilities │ │ │ └── IAsyncCapabilitiesServiceV2.cs │ │ ├── FileTransfer │ │ │ └── IAsyncFileTransferService.cs │ │ └── Scripts │ │ │ └── IAsyncScriptServiceV2.cs │ ├── StartScriptCommand.cs │ ├── TentacleContracts.cs │ └── UploadResult.cs ├── Octopus.Tentacle.Core │ ├── Configuration │ │ └── IHomeDirectoryProvider.cs │ ├── Diagnostics │ │ ├── ICustomPrettyPrintHandler.cs │ │ ├── ILog.cs │ │ ├── ISystemLog.cs │ │ ├── LogCategory.cs │ │ ├── PrettyPrint.cs │ │ ├── StringFormatMethodAttribute.cs │ │ └── TypeExtensionMethods.cs │ ├── Maintenance │ │ └── IRunningScriptReporter.cs │ ├── Octopus.Tentacle.Core.csproj │ ├── Services │ │ ├── FileTransfer │ │ │ └── FileTransferService.cs │ │ ├── IServiceAttribute.cs │ │ ├── Scripts │ │ │ ├── IRunningScript.cs │ │ │ ├── Locking │ │ │ │ ├── AcquireLockResult.cs │ │ │ │ ├── AsyncReaderWriterLockExtensions.cs │ │ │ │ └── ScriptIsolationMutex.cs │ │ │ ├── Logging │ │ │ │ ├── IScriptLog.cs │ │ │ │ ├── IScriptLogWriter.cs │ │ │ │ └── ScriptLog.cs │ │ │ ├── RunningScript.cs │ │ │ ├── ScriptServiceV2.cs │ │ │ ├── ScriptTicketFactory.cs │ │ │ ├── Security │ │ │ │ └── Masking │ │ │ │ │ ├── AhoCorasick.cs │ │ │ │ │ ├── SensitiveDataMask.cs │ │ │ │ │ └── SensitiveValueMasker.cs │ │ │ ├── Shell │ │ │ │ ├── Bash.cs │ │ │ │ ├── IShell.cs │ │ │ │ └── PowerShell.cs │ │ │ ├── StateStore │ │ │ │ ├── IScriptStateStore.cs │ │ │ │ ├── IScriptStateStoreFactory.cs │ │ │ │ ├── ScriptState.cs │ │ │ │ ├── ScriptStateStore.cs │ │ │ │ └── ScriptStateStoreFactory.cs │ │ │ ├── Util │ │ │ │ ├── Humanize.cs │ │ │ │ └── ScriptLogExtensions.cs │ │ │ └── WorkSpace │ │ │ │ ├── BashScriptWorkspace.cs │ │ │ │ ├── IScriptWorkspace.cs │ │ │ │ ├── IScriptWorkspaceFactory.cs │ │ │ │ ├── ScriptWorkspace.cs │ │ │ │ └── ScriptWorkspaceFactory.cs │ │ └── ServiceAttribute.cs │ └── Util │ │ ├── CommandLine │ │ └── SilentProcessRunner.cs │ │ ├── FileSystem │ │ ├── DeletionOptions.cs │ │ └── IOctopusFileSystem.cs │ │ ├── HashCalculator.cs │ │ ├── Locking │ │ ├── SemaphoreSlimExtensions.cs │ │ └── SemaphoreSlimReleaser.cs │ │ ├── PlatformDetection.cs │ │ ├── ProcessIdentity.cs │ │ └── Security │ │ └── AesEncryption.cs ├── Octopus.Tentacle.Kubernetes.Tests.Integration │ ├── KubernetesAgent │ │ ├── KubernetesAgentIntegrationTest.cs │ │ ├── KubernetesAgentMetricsIntegrationTest.cs │ │ ├── KubernetesAgentMigrateFromPreinstallationTest.cs │ │ ├── KubernetesClusterOneTimeSetUp.cs │ │ └── KubernetesScriptServiceV1IntegrationTest.cs │ ├── KubernetesClientCompatibilityTests.cs │ ├── KubernetesTestsGlobalContext.cs │ ├── Octopus.Tentacle.Kubernetes.Tests.Integration.csproj │ ├── Setup │ │ ├── DockerImageLoader.cs │ │ ├── KindConfiguration │ │ │ ├── kind-config-v1-28.yaml │ │ │ ├── kind-config-v1-29.yaml │ │ │ ├── kind-config-v1-30.yaml │ │ │ └── kind-config-v1-31.yaml │ │ ├── KubernetesAgentInstaller.cs │ │ ├── KubernetesClusterInstaller.cs │ │ ├── RequiredToolDownloader.cs │ │ ├── SetupHelpers.cs │ │ ├── Tooling │ │ │ ├── HelmDownloader.cs │ │ │ ├── IToolDownloader.cs │ │ │ ├── KindDownloader.cs │ │ │ ├── KubeCtlDownloader.cs │ │ │ └── ToolDownloader.cs │ │ ├── agent-values.yaml │ │ ├── docker-desktop-network-routing.yaml │ │ └── linux-network-routing.yaml │ ├── Support │ │ ├── AssemblyExtensions.cs │ │ ├── TestSupportConfigMapService.cs │ │ ├── kind-with-registry.ps1 │ │ ├── kind-with-registry.sh │ │ ├── kind.ps1 │ │ └── kind.sh │ ├── Tooling │ │ └── KubeCtlTool.cs │ ├── Usings.cs │ └── Util │ │ └── ExecuteKubernetesScriptCommandBuilderExtensionMethods.cs ├── Octopus.Tentacle.Tests.Integration.Common │ ├── AssemblyInfo.cs │ ├── Builders │ │ └── Decorators │ │ │ ├── CapabilitiesServiceV2DecoratorBuilder.cs │ │ │ ├── CombiningTentacleServiceDecoratorFactory.cs │ │ │ ├── FileTransferServiceDecoratorBuilder.cs │ │ │ ├── KubernetesScriptServiceV1DecoratorBuilder.cs │ │ │ ├── Proxies │ │ │ ├── MethodInvocationHookProxyDecorator.cs │ │ │ ├── MethodLoggingProxyDecorator.cs │ │ │ ├── MethodUsageProxyDecorator.cs │ │ │ ├── MethodUsages.cs │ │ │ ├── RecordMethodUsagesExtensionMethods.cs │ │ │ └── ServiceProxy.cs │ │ │ ├── ScriptServiceDecoratorBuilder.cs │ │ │ ├── ScriptServiceV2DecoratorBuilder.cs │ │ │ ├── TentacleServiceDecoratorBuilder.cs │ │ │ ├── TentacleServiceDecoratorBuilderExtensions.cs │ │ │ ├── UniversalScriptServiceDecorator.cs │ │ │ └── UniversalScriptServiceDecoratorBuilder.cs │ ├── Logging │ │ ├── SerilogLoggerBuilder.cs │ │ ├── TestContextConnectionLog.cs │ │ ├── TestContextLogCreator.cs │ │ ├── TestContextLogFactory.cs │ │ └── TraceLogFileLogger.cs │ └── Octopus.Tentacle.Tests.Integration.Common.csproj ├── Octopus.Tentacle.Tests.Integration │ ├── AssemblyInfo.cs │ ├── CapabilitiesServiceV2Test.cs │ ├── ClientFileTransferRetriesTimeout.cs │ ├── ClientFileTransfersAreNotRetriedWhenRetriesAreDisabled.cs │ ├── ClientFileTransfersAreRetriedWhenRetriesAreEnabled.cs │ ├── ClientGathersRpcCallMetrics.cs │ ├── ClientScriptExecutionAdditionalScripts.cs │ ├── ClientScriptExecutionCanBeCancelledWhenRetriesAreDisabled.cs │ ├── ClientScriptExecutionCanBeCancelledWhenRetriesAreEnabled.cs │ ├── ClientScriptExecutionCanRecoverFromNetworkIssues.cs │ ├── ClientScriptExecutionIsolationMutex.cs │ ├── ClientScriptExecutionRetriesTimeout.cs │ ├── ClientScriptExecutionScriptArgumentsWork.cs │ ├── ClientScriptExecutionScriptFilesAreSent.cs │ ├── ClientScriptExecutionScriptServiceNonV1IsNotRetriedWhenRetriesAreDisabled.cs │ ├── ClientScriptExecutionScriptServiceV1IsNotRetried.cs │ ├── ClientScriptExecutionWillAttemptACancelCallWhenGetStatusFails.cs │ ├── ClientScriptExecutionWorksWithMultipleVersions.cs │ ├── ClientScriptExecutorObservesScriptObserverBackoffStrategy.cs │ ├── FileTransferServiceTests.cs │ ├── MachineConfigurationHomeDirectoryTests.cs │ ├── Octopus.Tentacle.Tests.Integration.csproj │ ├── ScriptServiceTests.cs │ ├── ScriptServiceV2IntegrationTest.cs │ ├── ScriptsAreGivenRequiredEnvironmentVariables.cs │ ├── Startup │ │ ├── LinuxConfigureServiceHelperFixture.cs │ │ ├── Packages │ │ │ └── Acme.Service │ │ │ │ ├── Acme.Service.exe │ │ │ │ └── Acme.Service.nuspec │ │ └── WindowsServiceConfiguratorFixture.cs │ ├── Support │ │ ├── AllCombinations.cs │ │ ├── CartesianProduct.cs │ │ ├── ClientAndTentacle.cs │ │ ├── ClientAndTentacleBuilder.cs │ │ ├── EnumExtensions.cs │ │ ├── EnumerableExtensionMethods.cs │ │ ├── ExceptionContract.cs │ │ ├── ExceptionContractAssertionBuilder.cs │ │ ├── ExceptionContractAssertionBuilderExtensionMethods.cs │ │ ├── ExtensionMethods │ │ │ ├── DirectoryInfoExtensionMethods.cs │ │ │ ├── FluentAssertionExtensionMethods.cs │ │ │ ├── LogExtensionMethods.cs │ │ │ ├── ScriptExecutionResultExtensionMethods.cs │ │ │ └── ServiceEndPointExtensionMethods.cs │ │ ├── FailureScenario.cs │ │ ├── HalibutTimeoutsAndLimitsForTestBuilder.cs │ │ ├── IntegrationTest.cs │ │ ├── IntegrationTestTimeout.cs │ │ ├── Legacy │ │ │ ├── LegacyClientAndTentacle.cs │ │ │ ├── LegacyClientAndTentacleBuilder.cs │ │ │ ├── LegacyTentacleClient.cs │ │ │ ├── LegacyTentacleClientBuilder.cs │ │ │ └── ScriptExecutionOrchestrator.cs │ │ ├── ListeningTentacleBuilder.cs │ │ ├── Logging │ │ │ ├── TestContextConnectionLog.cs │ │ │ └── TestContextLogCreator.cs │ │ ├── PendingRequestQueueFactories │ │ │ └── CancelWhenRequestQueuedPendingRequestQueueFactory.cs │ │ ├── PollingTentacleBuilder.cs │ │ ├── RetryHelper.cs │ │ ├── RpcCallStage.cs │ │ ├── RunningTentacle.cs │ │ ├── RuntimeDetection.cs │ │ ├── ScriptServiceVersionToTest.cs │ │ ├── Server.cs │ │ ├── SetupFixtures │ │ │ ├── BumpThreadPoolForAllTests.cs │ │ │ ├── ISetupFixture.cs │ │ │ ├── ShowOneTimeSetupLogInfo.cs │ │ │ ├── TurnOnTraceLoggingForLogFileForLatestTentacle.cs │ │ │ └── WarmTentacleCache.cs │ │ ├── TaskHelper.cs │ │ ├── TentacleBuilder.cs │ │ ├── TentacleBuilderExtensionMethods.cs │ │ ├── TentacleConfigurationTestCase.cs │ │ ├── TentacleConfigurationsAttribute.cs │ │ ├── TentacleExeFinder.cs │ │ ├── TentacleFetchers │ │ │ ├── ITentacleFetcher.cs │ │ │ ├── LinuxTentacleFetcher.cs │ │ │ ├── NugetTentacleFetcher.cs │ │ │ ├── TentacleBinaryCache.cs │ │ │ ├── TentacleFetcher.cs │ │ │ ├── TentacleFetcherFactory.cs │ │ │ ├── VersionDependentTentacleFetcher.cs │ │ │ └── WindowsOnlyNugetBinsTentacleFetcher.cs │ │ ├── TentacleRuntime.cs │ │ ├── TentacleTestCaseSourceAttribute.cs │ │ ├── TentacleType.cs │ │ ├── TentacleVersions.cs │ │ ├── TestAttributes │ │ │ ├── LinuxTestAttribute.cs │ │ │ ├── RequiresAdminOnWindowsAttribute.cs │ │ │ ├── RequiresSudoOnLinuxAttribute.cs │ │ │ └── WindowsTestAttribute.cs │ │ ├── TestDecoratorsAreCalledInTheCorrectOrder.cs │ │ ├── TestEnvironmentHelper.cs │ │ ├── TestSerilogITentacleClientTaskLog.cs │ │ └── ValuesOf.cs │ ├── TentacleClientObserver.cs │ ├── TentacleCommandLineTests.cs │ ├── TentacleIntegrationSetupCanBeLongRunningClickHereToSeeLogsFixtures.cs │ ├── TentacleStartupAndShutdownTests.cs │ ├── Util │ │ ├── Builders │ │ │ ├── Decorators │ │ │ │ └── TentacleServiceDecoratorBuilderExtensions.cs │ │ │ ├── TentacleClientExtensionMethods.cs │ │ │ ├── TestExecuteScriptCommandBuilderExtensionMethods.cs │ │ │ └── TestExecuteShellScriptCommandBuilder.cs │ │ ├── FuncScriptObserverBackoffStrategy.cs │ │ ├── LinuxTestUserPrincipal.cs │ │ ├── ListProcessOutputExtensionMethods.cs │ │ ├── OctopusPhysicalFileSystemFixture.cs │ │ ├── PendingRequestQueueHelpers │ │ │ ├── CancellationObservingPendingRequestQueueFactory.cs │ │ │ └── CancellationTokenObservingPendingRequestQueueDecorator.cs │ │ ├── RandomTemporaryFileBuilder.cs │ │ ├── Reference.cs │ │ ├── RunningScriptFixture.cs │ │ ├── SerilogLoggerBuilder.cs │ │ ├── SilentProcessRunnerFixture.cs │ │ ├── TcpTentacleHelpers │ │ │ ├── ListeningResponseMessageTcpKiller.cs │ │ │ ├── PollingResponseMessageTcpKiller.cs │ │ │ ├── PortForwarderDataSentLogger.cs │ │ │ ├── ResponseMessageTcpKiller.cs │ │ │ └── TcpConnectionUtilities.cs │ │ ├── TentacleClientTestExtensionMethods.cs │ │ ├── TestScriptLog.cs │ │ ├── TestUserPrincipal.cs │ │ └── Wait.cs │ └── WorkspaceCleanerTests.cs ├── Octopus.Tentacle.Tests │ ├── App.config │ ├── ArgsParsing.cs │ ├── AssentRunner.cs │ ├── Capabilities │ │ ├── BackwardsCompatibleCapabilitiesV2DecoratorFixture.cs │ │ ├── BackwardsCompatibleCapabilitiesV2HelperFixture.cs │ │ ├── BackwardsCompatibleCapabilitiesV2TestServices.cs │ │ └── CapabilitiesServiceV2Fixture.cs │ ├── Certificates │ │ ├── CertificateGeneratorFixture.cs │ │ └── CertificateValidatorFixture.cs │ ├── Commands │ │ ├── CommandFixture.cs │ │ ├── ConfigureCommandFixture.cs │ │ ├── DeregisterMachineCommandFixture.cs │ │ ├── DeregisterWorkerCommandFixture.cs │ │ ├── ImportCertificateCommandFixture.cs │ │ ├── ListInstancesCommandFixture.cs │ │ ├── MigratePreInstalledKubernetesDeploymentTargetCommandTest.cs │ │ ├── NewCertificateCommandFixture.cs │ │ ├── OptionSets │ │ │ └── ApiEndpointOptionsFixture.cs │ │ ├── ProxyConfigurationCommandFixture.cs │ │ ├── RegisterKubernetesDeploymentTargetCommandFixture.cs │ │ ├── RegisterKubernetesWorkerCommandFixture.cs │ │ ├── RegisterMachineCommandFixture.cs │ │ ├── RegisterWorkerCommandFixture.cs │ │ ├── RunAgentCommandFixture.cs │ │ ├── ServerCommsCommandTest.cs │ │ ├── StubHomeConfiguration.cs │ │ └── StubTentacleConfiguration.cs │ ├── Communications │ │ ├── AutofacServiceFactoryFixture.cs │ │ ├── HalibutInitializerFixture.cs │ │ ├── KnownServiceFixture.cs │ │ └── TentacleCommunicationsModuleFixture.cs │ ├── Configuration │ │ ├── AggregatedKeyValueStoreFixture.cs │ │ ├── ApplicationInstanceSelectorFixture.cs │ │ ├── ApplicationInstanceStoreFixture.cs │ │ ├── Crypto │ │ │ ├── LinuxGeneratedMachineKeyFixture.cs │ │ │ ├── LinuxMachineKeyEncryptorFixture.cs │ │ │ └── WindowsMachineKeyEncryptorFixture.cs │ │ ├── CurrentRoundTripTestBase.cs │ │ ├── EnvFileConfigurationContributorFixture.cs │ │ ├── EnvFileLocatorFixture.cs │ │ ├── EnvironmentConfigurationContributorFixture.cs │ │ ├── EnvironmentValuesFixture.cs │ │ ├── InMemoryKeyValueStoreFixture.cs │ │ ├── JsonHierarchicalConsoleKeyValueStoreFixture.cs │ │ ├── MapEnvironmentVariablesFixture.cs │ │ ├── OctopusServerConfigurationFixture.cs │ │ ├── Proxy │ │ │ └── ProxyPasswordMaskValuesProviderFixture.cs │ │ ├── ProxyConfigParserFixture.cs │ │ ├── ProxyInitializerTests.cs │ │ ├── RoundTripTestBaseFixture.cs │ │ └── XmlFileKeyValueStoreFixture.cs │ ├── Contracts │ │ ├── FileTransferFixture.cs │ │ ├── Legacy │ │ │ ├── AssemblyMappingSerializationBinderDecoratorFixture.cs │ │ │ ├── CanSerializeAndDeserializeJsonWithLegacyNameSpace.cs │ │ │ ├── NamespaceMappingSerializationBinderDecoratorFixture.cs │ │ │ └── RecordingSerializationBinder.cs │ │ ├── ScriptTicketFixture.cs │ │ ├── ServiceFixture.cs │ │ └── UniqueScriptTicketBuilderFixture.cs │ ├── DependenciesTest.cs │ ├── Diagnostics │ │ ├── AbstractLogFixture.cs │ │ ├── Formatters │ │ │ └── PluralStringFormatterFixture.cs │ │ ├── Metrics │ │ │ └── KubernetesAgentMetricsFixture.cs │ │ └── SensitiveValueMaskerFixture.cs │ ├── FileSystem │ │ └── FileSystemCleanerFixture.cs │ ├── Integration │ │ ├── ScriptLogFixture.cs │ │ ├── ScriptServiceFixture.cs │ │ └── ScriptServiceV2Fixture.cs │ ├── Kubernetes │ │ ├── ClusterVersionTests.cs │ │ ├── KubernetesDirectoryInformationProviderFixture.cs │ │ ├── KubernetesEventMonitorFixture.cs │ │ ├── KubernetesOrphanedPodCleanerTests.cs │ │ ├── KubernetesPhysicalFileSystemFixture.cs │ │ ├── KubernetesPodContainerResolverTests.cs │ │ ├── KubernetesPodMonitorTests.cs │ │ ├── KubernetesUtilitiesFixture.cs │ │ ├── PodLogEncryptionProviderTests.cs │ │ ├── PodLogLineParserFixture.cs │ │ ├── PodLogReaderFixture.cs │ │ ├── ReferenceCountingKeyedBinarySemaphoreTests.cs │ │ └── TrackedScriptPodFixture.cs │ ├── Octopus.Tentacle.Tests.csproj │ ├── Octopus.Tentacle.Tests.csproj.DotSettings │ ├── Orchestration │ │ └── Agentless │ │ │ └── Ssh │ │ │ └── SshHealthReporterFixture.cs │ ├── Resources │ │ ├── TestCertificate.Readme.md │ │ ├── TestCertificateNoPassword.pfx │ │ ├── TestCertificateNoPrivateKey.pfx │ │ └── TestCertificateWithPassword.pfx │ ├── Scripts │ │ ├── ExponentialBackoffFixture.cs │ │ ├── ScriptIsolationMutexFixture.cs │ │ └── ScriptStateStoreTests.cs │ ├── Security │ │ ├── AesEncryptionFixture.cs │ │ ├── AhoCorasickMemoryPerfTests.cs │ │ ├── Certificates │ │ │ └── CertificateEncoderFixture.cs │ │ ├── SensitiveDataMaskFixture.cs │ │ └── SensitiveDataMaskMultiLineFixture.cs │ ├── Setup.cs │ ├── Startup │ │ ├── CheckServicesCommandFixture.cs │ │ ├── FileSystemCleanerFixture.cs │ │ ├── Packages │ │ │ └── Acme.Service │ │ │ │ ├── Acme.Service.csproj │ │ │ │ ├── Acme.Service.exe │ │ │ │ └── Acme.Service.nuspec │ │ └── WatchdogCommandFixture.cs │ ├── Support │ │ ├── InMemoryLog.cs │ │ ├── TaskHelper.cs │ │ ├── TemporaryDirectory.cs │ │ ├── TestAttributes │ │ │ ├── LinuxTestAttribute.cs │ │ │ ├── NotMacTestAttribute.cs │ │ │ └── WindowsTestAttribute.cs │ │ └── TestConsoleLog.cs │ ├── TestExecutionContext.cs │ ├── Util │ │ ├── Approved │ │ │ └── AssentRunner.PrettyPrint_AsyncException.approved.txt │ │ ├── HashCalculatorFixture.cs │ │ ├── LinuxTestUserPrincipal.cs │ │ ├── ProcessIdentity.cs │ │ ├── SerializationExtensionMethods.cs │ │ ├── TemporaryEnvironmentVariable.cs │ │ └── TestUserPrincipal.cs │ └── web.config ├── Octopus.Tentacle.Upgrader │ ├── GlobalSuppressions.cs │ ├── Log.cs │ ├── Octopus.Tentacle.Upgrader.csproj │ ├── Program.cs │ ├── Properties │ │ └── AssemblyInfo.cs │ ├── ServiceBouncer.cs │ └── SoftwareInstaller.cs ├── Octopus.Tentacle │ ├── AssemblyInfo.cs │ ├── Background │ │ └── BackgroundTask.cs │ ├── Certificates │ │ ├── CertificateGenerator.cs │ │ ├── CertificateValidator.cs │ │ └── CertificatesModule.cs │ ├── Commands │ │ ├── CanBeNullAttribute.cs │ │ ├── ClearTrustedServersCommand.cs │ │ ├── ClientModule.cs │ │ ├── ConfigureCommand.cs │ │ ├── CreateInstanceCommand.cs │ │ ├── DeleteInstanceCommand.cs │ │ ├── DeregisterMachineCommand.cs │ │ ├── DeregisterWorkerCommand.cs │ │ ├── ExtractCommand.cs │ │ ├── ImportCertificateCommand.cs │ │ ├── ListInstancesCommand.cs │ │ ├── MigratePreInstalledKubernetesDeploymentTargetCommand.cs │ │ ├── NewCertificateCommand.cs │ │ ├── OptionSets │ │ │ ├── ApiEndpointOptions.cs │ │ │ ├── IOctopusClientInitializer.cs │ │ │ ├── OctopusClientInitializer.cs │ │ │ └── OctopusClientInitializerModule.cs │ │ ├── PollCommand.cs │ │ ├── PollingProxyConfigurationCommand.cs │ │ ├── RegisterKubernetesClusterCommand.cs │ │ ├── RegisterKubernetesDeploymentTargetCommand.cs │ │ ├── RegisterKubernetesWorkerCommand.cs │ │ ├── RegisterMachineCommand.cs │ │ ├── RegisterMachineCommandBase.cs │ │ ├── RegisterWorkerCommand.cs │ │ ├── RegisterWorkerCommandBase.cs │ │ ├── RunAgentCommand.cs │ │ ├── ServerCommsCommand.cs │ │ ├── ShowConfigurationCommand.cs │ │ ├── ShowThumbprintCommand.cs │ │ ├── SpaceRepositoryFactory.cs │ │ ├── UpdateTrustCommand.cs │ │ └── VersionCommand.cs │ ├── Communications │ │ ├── AutofacServiceFactory.cs │ │ ├── HalibutInitializer.cs │ │ ├── IAutofacServiceSource.cs │ │ ├── IHalibutInitializer.cs │ │ ├── IOctopusServerChecker.cs │ │ ├── KnownService.cs │ │ ├── KnownServiceSource.cs │ │ ├── OctopusServerChecker.cs │ │ ├── TentacleCommunicationsModule.cs │ │ └── UnknownServiceNameException.cs │ ├── Configuration │ │ ├── ApplicationName.cs │ │ ├── ConfigurationModule.cs │ │ ├── Crypto │ │ │ ├── ICryptoKeyNixSource.cs │ │ │ ├── IMachineKeyEncryptor.cs │ │ │ ├── LinuxGeneratedMachineKey.cs │ │ │ ├── LinuxMachineIdKey.cs │ │ │ ├── LinuxMachineKeyEncryptor.cs │ │ │ └── MachineKeyEncryptor.cs │ │ ├── DictionaryKeyValueStore.cs │ │ ├── EnvironmentVariableMappings │ │ │ ├── EnvironmentVariable.cs │ │ │ ├── EnvironmentVariableReader.cs │ │ │ ├── IEnvironmentVariableReader.cs │ │ │ ├── IMapEnvironmentValuesToConfigItems.cs │ │ │ └── MapsEnvironmentValuesToConfigItems.cs │ │ ├── FlatDictionaryKeyValueStore.cs │ │ ├── HierarchicalDictionaryKeyValueStore.cs │ │ ├── HomeConfiguration.cs │ │ ├── IHomeConfiguration.cs │ │ ├── IKeyValueStore.cs │ │ ├── ILoggingConfiguration.cs │ │ ├── IPollingProxyConfiguration.cs │ │ ├── IProxyConfiguration.cs │ │ ├── IProxyInitializer.cs │ │ ├── IRegistryApplicationInstanceStore.cs │ │ ├── ITentacleConfiguration.cs │ │ ├── IWritableKeyValueStore.cs │ │ ├── InMemoryKeyValueStore.cs │ │ ├── Instances │ │ │ ├── AggregatedKeyValueStore.cs │ │ │ ├── ApplicationConfigurationContributionFlag.cs │ │ │ ├── ApplicationInstanceConfiguration.cs │ │ │ ├── ApplicationInstanceManager.cs │ │ │ ├── ApplicationInstanceRecord.cs │ │ │ ├── ApplicationInstanceSelector.cs │ │ │ ├── ApplicationInstanceStore.cs │ │ │ ├── EnvFileConfigurationContributor.cs │ │ │ ├── EnvFileLocator.cs │ │ │ ├── EnvironmentConfigurationContributor.cs │ │ │ ├── IAggregatableKeyValueStore.cs │ │ │ ├── IApplicationConfigurationContributor.cs │ │ │ ├── IApplicationInstanceManager.cs │ │ │ ├── IApplicationInstanceSelector.cs │ │ │ ├── IApplicationInstanceStore.cs │ │ │ ├── NullRegistryApplicationInstanceStore.cs │ │ │ └── WindowsRegistryApplicationInstanceStore.cs │ │ ├── JsonHierarchicalConsoleKeyValueStore.cs │ │ ├── JsonHierarchicalFileKeyValueStore.cs │ │ ├── JsonHierarchicalKeyValueStore.cs │ │ ├── JsonSerialization.cs │ │ ├── KeyValueStoreBase.cs │ │ ├── LogInitializer.cs │ │ ├── LogMaskingModule.cs │ │ ├── LoggingConfiguration.cs │ │ ├── MapsTentacleEnvironmentValuesToConfigItems.cs │ │ ├── OctopusServerConfiguration.cs │ │ ├── PollingProxyConfiguration.cs │ │ ├── ProtectionLevel.cs │ │ ├── Proxy │ │ │ └── ProxyPasswordMaskValuesProvider.cs │ │ ├── ProxyConfigParser.cs │ │ ├── ProxyConfiguration.cs │ │ ├── ProxyInitializer.cs │ │ ├── ServiceName.cs │ │ ├── StartUpConfigFileInstanceRequest.cs │ │ ├── StartUpDynamicInstanceRequest.cs │ │ ├── StartUpInstanceRequest.cs │ │ ├── StartUpKubernetesConfigMapInstanceRequest.cs │ │ ├── StartUpRegistryInstanceRequest.cs │ │ ├── TentacleConfiguration.cs │ │ ├── TentacleConfigurationModule.cs │ │ ├── WatchdogConfiguration.cs │ │ ├── WindowsMachineKeyEncryptor.cs │ │ ├── XmlFileKeyValueStore.cs │ │ ├── XmlKeyValueStore.cs │ │ ├── XmlSetting.cs │ │ └── XmlSettingsRoot.cs │ ├── ControlledFailureException.cs │ ├── Diagnostics │ │ ├── DelayedLog.cs │ │ ├── EventLogTarget.cs │ │ ├── Formatters │ │ │ └── PluralStringFormatter.cs │ │ ├── ILogAppender.cs │ │ ├── KnowledgeBase │ │ │ ├── ExceptionKnowledge.cs │ │ │ ├── ExceptionKnowledgeBase.cs │ │ │ ├── ExceptionKnowledgeBaseEntry.cs │ │ │ └── ExceptionKnowledgeBuilder.cs │ │ ├── Log.cs │ │ ├── LogEvent.cs │ │ ├── LoggingModule.cs │ │ ├── NLogAppender.cs │ │ ├── NullEventLogTarget.cs │ │ ├── NullLog.cs │ │ ├── OctopusLogsDirectoryRenderer.cs │ │ └── SystemLog.cs │ ├── ExternalInit.cs │ ├── GlobalSuppressions.cs │ ├── Internals │ │ ├── CertificateGeneration │ │ │ ├── CryptContext.cs │ │ │ ├── CryptKey.cs │ │ │ ├── FinalizableObject.cs │ │ │ ├── KeyExchangeKey.cs │ │ │ ├── KeyType.cs │ │ │ ├── SelfSignedCertProperties.cs │ │ │ ├── Win32ErrorHelper.cs │ │ │ ├── Win32Native.cs │ │ │ └── _Readme.txt │ │ └── Options │ │ │ ├── Option.cs │ │ │ ├── OptionAction.cs │ │ │ ├── OptionContext.cs │ │ │ ├── OptionException.cs │ │ │ ├── OptionSet.cs │ │ │ ├── OptionValueCollection.cs │ │ │ ├── OptionValueType.cs │ │ │ └── _Readme.txt │ ├── Kubernetes │ │ ├── ClusterVersion.cs │ │ ├── ConfigMapNames.cs │ │ ├── Configuration │ │ │ └── ConfigMapKeyValueStore.cs │ │ ├── Crypto │ │ │ ├── KubernetesMachineEncryptionKeyProvider.cs │ │ │ ├── KubernetesMachineKeyEncryptor.cs │ │ │ ├── PodLogEncryptionProvider.cs │ │ │ ├── ScriptPodLogEncryptionKeyGenerator.cs │ │ │ └── ScriptPodLogEncryptionKeyProvider.cs │ │ ├── Diagnostics │ │ │ ├── KubernetesAgentMetrics.cs │ │ │ └── PersistenceProvider.cs │ │ ├── EventHelpers.cs │ │ ├── EventMapper.cs │ │ ├── IKubernetesClientConfigProvider.cs │ │ ├── InClusterKubernetesClientConfigProvider.cs │ │ ├── InMemoryTentacleScriptLog.cs │ │ ├── KubernetesAgentToolsImageVersionMetadata.cs │ │ ├── KubernetesAgentToolsImageVersionMetadataProvider.cs │ │ ├── KubernetesClientExtensionMethods.cs │ │ ├── KubernetesClusterService.cs │ │ ├── KubernetesConfig.cs │ │ ├── KubernetesConfigMapService.cs │ │ ├── KubernetesDirectoryInformationProvider.cs │ │ ├── KubernetesEventMonitor.cs │ │ ├── KubernetesEventMonitorTask.cs │ │ ├── KubernetesEventService.cs │ │ ├── KubernetesModule.cs │ │ ├── KubernetesOrphanedPodCleaner.cs │ │ ├── KubernetesOrphanedPodCleanerTask.cs │ │ ├── KubernetesPhysicalFileSystem.cs │ │ ├── KubernetesPodContainerResolver.cs │ │ ├── KubernetesPodLogService.cs │ │ ├── KubernetesPodMonitor.cs │ │ ├── KubernetesPodMonitorTask.cs │ │ ├── KubernetesPodService.cs │ │ ├── KubernetesRawScriptPodCreator.cs │ │ ├── KubernetesScriptPodCreator.cs │ │ ├── KubernetesScriptPodNameExtensions.cs │ │ ├── KubernetesSecretService.cs │ │ ├── KubernetesService.cs │ │ ├── KubernetesUtilities.cs │ │ ├── LocalMachineKubernetesClientConfigProvider.cs │ │ ├── OctopusLabels.cs │ │ ├── PodLogLineParser.cs │ │ ├── PodLogReader.cs │ │ ├── ScriptPodSinceTimeStore.cs │ │ ├── Synchronisation │ │ │ ├── IKeyedSemaphore.cs │ │ │ └── Internal │ │ │ │ ├── ReferenceCountingBinarySemaphoreSlim.cs │ │ │ │ ├── ReferenceCountingKeyedBinarySemaphore.cs │ │ │ │ └── SemaphoreSlimReleaser.cs │ │ ├── TentacleScriptLogProvider.cs │ │ └── UnimplementedKubernetesClientConfigProvider.cs │ ├── Maintenance │ │ ├── MaintenanceModule.cs │ │ ├── WorkspaceCleaner.cs │ │ ├── WorkspaceCleanerConfiguration.cs │ │ └── WorkspaceCleanerTask.cs │ ├── NullableReferenceTypeAttributes.cs │ ├── Octopus.Tentacle.csproj │ ├── Packages │ │ ├── IPackageInstaller.cs │ │ └── NuGetPackageInstaller.cs │ ├── Program.cs │ ├── Properties │ │ ├── AssemblyInfo.cs │ │ ├── Icon.ico │ │ └── OctopusTentacle.cs │ ├── Security │ │ ├── CertificateExpectations.cs │ │ ├── CertificateValidationDirection.cs │ │ └── Certificates │ │ │ └── CertificateEncoder.cs │ ├── Services │ │ ├── Capabilities │ │ │ └── CapabilitiesServiceV2.cs │ │ ├── KubernetesServiceAttribute.cs │ │ ├── Scripts │ │ │ ├── IAsyncScriptService.cs │ │ │ ├── Kubernetes │ │ │ │ ├── IAsyncKubernetesScriptServiceV1.cs │ │ │ │ └── KubernetesScriptServiceV1.cs │ │ │ └── ScriptService.cs │ │ └── ServicesModule.cs │ ├── Startup │ │ ├── AbstractCommand.cs │ │ ├── AbstractStandardCommand.cs │ │ ├── AutofacExtensions.cs │ │ ├── CheckServicesCommand.cs │ │ ├── CommandLocator.cs │ │ ├── CommandMetadata.cs │ │ ├── CommandModule.cs │ │ ├── ConsoleHost.cs │ │ ├── FileSystemCleaner.cs │ │ ├── HelpCommand.cs │ │ ├── ICommand.cs │ │ ├── ICommandHost.cs │ │ ├── ICommandLocator.cs │ │ ├── ICommandOptions.cs │ │ ├── ICommandRuntime.cs │ │ ├── IServiceConfigurator.cs │ │ ├── LinuxServiceConfigurator.cs │ │ ├── LogFileOnlyLogger.cs │ │ ├── LsaUtility.cs │ │ ├── MutexHost.cs │ │ ├── NoninteractiveHost.cs │ │ ├── OctopusProgram.cs │ │ ├── PathsToDeleteOnStartup.core.txt │ │ ├── PathsToDeleteOnStartup.netfx.txt │ │ ├── ProxyConfigurationCommand.cs │ │ ├── ServiceCommand.cs │ │ ├── ServiceConfigurationState.cs │ │ ├── WatchdogCommand.cs │ │ ├── WindowsServiceAdapter.cs │ │ ├── WindowsServiceConfigurator.cs │ │ └── WindowsServiceHost.cs │ ├── Tentacle.Binaries.nuspec │ ├── Tentacle.Binaries.targets │ ├── Tentacle.Installers.nuspec │ ├── Tentacle.Packages.nuspec │ ├── Tentacle.Packages.targets │ ├── Tentacle.exe.k8s.nlog │ ├── Tentacle.exe.manifest │ ├── Tentacle.exe.nlog │ ├── Time │ │ ├── ExponentialBackoff.cs │ │ ├── Sleep.cs │ │ └── TimeModule.cs │ ├── Util │ │ ├── AssemblyExtensions.cs │ │ ├── CliBuilder.cs │ │ ├── CmdResult.cs │ │ ├── CommandLineInvocation.cs │ │ ├── CommandLineRunner.cs │ │ ├── EnumerableExtensions.cs │ │ ├── EnvironmentHelper.cs │ │ ├── ExceptionExtensions.cs │ │ ├── FileSizeExtensions.cs │ │ ├── ICommandLineRunner.cs │ │ ├── ISilentProcessRunner.cs │ │ ├── KubernetesSupportDetection.cs │ │ ├── ListExtensions.cs │ │ ├── LocalAdminRights.cs │ │ ├── ObjectFormatter.cs │ │ ├── OctopusFileSystemModule.cs │ │ ├── OctopusPhysicalFileSystem.cs │ │ ├── PollingSubscriptionId.cs │ │ ├── RandomStringGenerator.cs │ │ ├── ScriptsModule.cs │ │ ├── ShellModule.cs │ │ ├── StringExtensions.cs │ │ ├── SystemCtlHelper.cs │ │ └── TeamCityDetection.cs │ ├── Variables │ │ └── EnvironmentVariables.cs │ ├── Versioning │ │ ├── AppVersion.cs │ │ ├── AssemblyExtensions.cs │ │ ├── SemanticVersionInfo.cs │ │ ├── SemanticVersionInfoExtensions.cs │ │ └── VersioningModule.cs │ ├── Watchdog │ │ ├── IWatchdog.cs │ │ ├── NullWatchdog.cs │ │ └── Watchdog.cs │ ├── app.config │ └── app.netcore.config ├── Solution Items │ ├── SolutionInfo.cs │ └── VersionInfo.cs ├── Tentacle.sln ├── Tentacle.sln.DotSettings └── text.settings.json └── testing ├── .gitignore ├── README.md └── compatibility ├── azure ├── deploy.ps1 ├── install-tentacle.ps1 ├── readme.md ├── vm.bicep └── vm.bicepparam ├── docker ├── README.md ├── docker-compose.mustache ├── example.config.json ├── example.env ├── generate.ps1 └── run.ps1 └── vagrant ├── Linux ├── Vagrantfile ├── bootstrap.ps1 ├── example.env ├── install.ps1 ├── listening.ps1 └── polling.ps1 ├── README.md └── Windows ├── Vagrantfile ├── bootstrap.ps1 ├── example.env ├── install.ps1 ├── listening.ps1 └── polling.ps1 /.config/dotnet-tools.json: -------------------------------------------------------------------------------- 1 | { 2 | "version": 1, 3 | "isRoot": true, 4 | "tools": { 5 | "cake.tool": { 6 | "version": "0.38.5", 7 | "commands": [ 8 | "dotnet-cake" 9 | ] 10 | }, 11 | "octoversion.tool": { 12 | "version": "0.2.393", 13 | "commands": [ 14 | "octoversion" 15 | ] 16 | }, 17 | "octopus.dotnet.cli": { 18 | "version": "7.4.2", 19 | "commands": [ 20 | "dotnet-octo" 21 | ] 22 | } 23 | } 24 | } -------------------------------------------------------------------------------- /.dockerignore: -------------------------------------------------------------------------------- 1 | .git 2 | .github 3 | .git* 4 | source -------------------------------------------------------------------------------- /.github/CODEOWNERS: -------------------------------------------------------------------------------- 1 | * @OctopusDeploy/team-server-at-scale 2 | 3 | # The Kubernetes parts of Tentacle are owned by Modern Deployments 4 | /docker/kubernetes-agent-tentacle/ @OctopusDeploy/team-modern-deployments 5 | /source/Octopus.Tentacle/Kubernetes/ @OctopusDeploy/team-modern-deployments 6 | /source/Octopus.Tentacle/Services/Scripts/Kubernetes/ @OctopusDeploy/team-modern-deployments 7 | /source/Octopus.Tentacle.Client/Kubernetes/ @OctopusDeploy/team-modern-deployments 8 | /source/Octopus.Tentacle.Kubernetes.Tests.Integration/ @OctopusDeploy/team-modern-deployments 9 | -------------------------------------------------------------------------------- /.nuke/parameters.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "./build.schema.json", 3 | "Solution": "source/Tentacle.sln" 4 | } -------------------------------------------------------------------------------- /NuGet.Config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /_artifacts.upload.filespec.json: -------------------------------------------------------------------------------- 1 | { 2 | "files": [ 3 | { "pattern": "_artifacts/chocolatey/*", "target": "chocolatey" }, 4 | { "pattern": "_artifacts/deb/*", "target": "deb" }, 5 | { "pattern": "_artifacts/msi/*", "target": "msi" }, 6 | { "pattern": "_artifacts/nuget/*", "target": "nuget/OctopusTentacle/" }, 7 | { "pattern": "_artifacts/rpm/*", "target": "rpm" }, 8 | { "pattern": "_artifacts/zip/*", "target": "zip" } 9 | ] 10 | } 11 | -------------------------------------------------------------------------------- /build.cmd: -------------------------------------------------------------------------------- 1 | :; set -eo pipefail 2 | :; SCRIPT_DIR=$(cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd) 3 | :; ${SCRIPT_DIR}/build.sh "$@" 4 | :; exit $? 5 | 6 | @ECHO OFF 7 | powershell -ExecutionPolicy ByPass -NoProfile -File "%~dp0build.ps1" %* 8 | -------------------------------------------------------------------------------- /build/.editorconfig: -------------------------------------------------------------------------------- 1 | [*.cs] 2 | dotnet_style_qualification_for_field = false:warning 3 | dotnet_style_qualification_for_property = false:warning 4 | dotnet_style_qualification_for_method = false:warning 5 | dotnet_style_qualification_for_event = false:warning 6 | dotnet_style_require_accessibility_modifiers = never:warning 7 | 8 | csharp_style_expression_bodied_methods = true:silent 9 | csharp_style_expression_bodied_properties = true:warning 10 | csharp_style_expression_bodied_indexers = true:warning 11 | csharp_style_expression_bodied_accessors = true:warning 12 | -------------------------------------------------------------------------------- /build/Configuration.cs: -------------------------------------------------------------------------------- 1 | // ReSharper disable RedundantUsingDirective 2 | 3 | using System; 4 | using System.ComponentModel; 5 | using System.Linq; 6 | using Nuke.Common.Tooling; 7 | 8 | [TypeConverter(typeof(TypeConverter))] 9 | public class Configuration : Enumeration 10 | { 11 | public static Configuration Debug = new() { Value = nameof(Debug) }; 12 | public static Configuration Release = new() { Value = nameof(Release) }; 13 | 14 | public static implicit operator string(Configuration configuration) 15 | { 16 | return configuration.Value; 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /build/Git.cs: -------------------------------------------------------------------------------- 1 | // ReSharper disable RedundantUsingDirective 2 | using System; 3 | 4 | public static class Git 5 | { 6 | public static string? DeriveGitBranch() => Environment.GetEnvironmentVariable("OCTOVERSION_CurrentBranch"); 7 | } -------------------------------------------------------------------------------- /build/TestConfigurationOnLinuxDistribution.cs: -------------------------------------------------------------------------------- 1 | // ReSharper disable RedundantUsingDirective 2 | using System; 3 | 4 | public class TestConfigurationOnLinuxDistribution 5 | { 6 | public TestConfigurationOnLinuxDistribution(string framework, string runtimeId, string dockerImage, string packageType) 7 | { 8 | Framework = framework; 9 | RuntimeId = runtimeId; 10 | DockerImage = dockerImage; 11 | PackageType = packageType; 12 | } 13 | 14 | public string Framework { get; } 15 | public string RuntimeId { get; } 16 | public string DockerImage { get; } 17 | public string PackageType { get; } 18 | } 19 | -------------------------------------------------------------------------------- /build/test-scripts/integration/common/set-dotnet-envvars.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | set -o xtrace 3 | set -e 4 | 5 | # Use our paths rather than any system level dotnet 6 | export DOTNET_ROOT=$HOME/.dotnet 7 | export PATH=$DOTNET_ROOT:$DOTNET_ROOT/tools:$PATH 8 | -------------------------------------------------------------------------------- /build/test-scripts/integration/common/setup-vm-agent.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # VMs can be out dated so install the latest dotnet to ensure the dll to run 4 | # was not compiled with a newer version 5 | SCRIPT_DIR=$( cd -- "$( dirname -- "${BASH_SOURCE[0]}" )" &> /dev/null && pwd ) 6 | 7 | source $SCRIPT_DIR/dotnet-install.sh 8 | install_dotnet 8.0 9 | -------------------------------------------------------------------------------- /certificates/OctopusDevelopment.pfx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OctopusDeploy/OctopusTentacle/ea14d2f07576b34349c2710609e562b56aa33824/certificates/OctopusDevelopment.pfx -------------------------------------------------------------------------------- /docker-compose.build-dev.yml: -------------------------------------------------------------------------------- 1 | version: '3' 2 | services: 3 | 4 | octopusdeploy-kubernetes-agent-tentacle-linux: 5 | platform: "linux/${BUILD_ARCH:?err}" 6 | build: 7 | context: . 8 | dockerfile: ./docker/kubernetes-agent-tentacle/dev/Dockerfile 9 | args: 10 | IMAGE_TAG: ${IMAGE_TAG:?err} 11 | DEBUGGER_ARCH: ${DEBUGGER_ARCH:?err} 12 | image: docker.packages.octopushq.com/octopusdeploy/kubernetes-agent-tentacle:${BUILD_NUMBER?err}-linux-${BUILD_ARCH:?err}-debug 13 | -------------------------------------------------------------------------------- /docker/Volumes/listening-tentacle/Applications/.gitignore: -------------------------------------------------------------------------------- 1 | # This directory needs to exist so that our Docker containers can bind to it when we `docker-compose up -d` the universe. 2 | * 3 | !.gitignore -------------------------------------------------------------------------------- /docker/Volumes/listening-tentacle/TentacleHome/.gitignore: -------------------------------------------------------------------------------- 1 | # This directory needs to exist so that our Docker containers can bind to it when we `docker-compose up -d` the universe. 2 | * 3 | !.gitignore -------------------------------------------------------------------------------- /docker/Volumes/octopus-server/Import/Environments/Development.json: -------------------------------------------------------------------------------- 1 | { 2 | "$type": "Octopus.Core.Model.Environments.DeploymentEnvironment, Octopus.Core", 3 | "Id": "Environments-1", 4 | "Name": "Development", 5 | "Description": "", 6 | "SortOrder": 0, 7 | "UseGuidedFailure": false 8 | } -------------------------------------------------------------------------------- /docker/Volumes/octopus-server/Import/metadata.json: -------------------------------------------------------------------------------- 1 | { 2 | "$type": "Octopus.Migrator.Core.ExportProcess.ServerMetadata, Octopus.Migrator.Core", 3 | "Id": "SKYNET", 4 | "Name": "SKYNET", 5 | "Created": "2017-03-10T19:34:16.8844884+10:00", 6 | "DatabaseVersion": "0.0.0", 7 | "Hello": "QodGbnfU53iwUAt0ayr+og==|AAAAAAAAAAAAAAAAAAAAAA==" 8 | } -------------------------------------------------------------------------------- /docker/Volumes/octopus-server/MasterKey/.gitignore: -------------------------------------------------------------------------------- 1 | # This directory needs to exist so that our Docker containers can bind to it when we `docker-compose up -d` the universe. 2 | * 3 | !.gitignore -------------------------------------------------------------------------------- /docker/Volumes/octopus-server/Repository/.gitignore: -------------------------------------------------------------------------------- 1 | # This directory needs to exist so that our Docker containers can bind to it when we `docker-compose up -d` the universe. 2 | -------------------------------------------------------------------------------- /docker/Volumes/octopus-server/Repository/Serilog.Sinks.TextWriter/Serilog.Sinks.TextWriter.2.1.0.nupkg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OctopusDeploy/OctopusTentacle/ea14d2f07576b34349c2710609e562b56aa33824/docker/Volumes/octopus-server/Repository/Serilog.Sinks.TextWriter/Serilog.Sinks.TextWriter.2.1.0.nupkg -------------------------------------------------------------------------------- /docker/Volumes/octopus-server/Repository/Spaces-1/feeds-builtin/Serilog.Sinks.TextWriter/Serilog.Sinks.TextWriter.2.1.0.nupkg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OctopusDeploy/OctopusTentacle/ea14d2f07576b34349c2710609e562b56aa33824/docker/Volumes/octopus-server/Repository/Spaces-1/feeds-builtin/Serilog.Sinks.TextWriter/Serilog.Sinks.TextWriter.2.1.0.nupkg -------------------------------------------------------------------------------- /docker/Volumes/polling-tentacle/Applications/.gitignore: -------------------------------------------------------------------------------- 1 | # This directory needs to exist so that our Docker containers can bind to it when we `docker-compose up -d` the universe. 2 | * 3 | !.gitignore -------------------------------------------------------------------------------- /docker/Volumes/polling-tentacle/TentacleHome/.gitignore: -------------------------------------------------------------------------------- 1 | # This directory needs to exist so that our Docker containers can bind to it when we `docker-compose up -d` the universe. 2 | * 3 | !.gitignore -------------------------------------------------------------------------------- /docker/kubernetes-agent-tentacle/bootstrapRunner/go.mod: -------------------------------------------------------------------------------- 1 | module KubernetesAgentBootstrapRunner 2 | -------------------------------------------------------------------------------- /docker/kubernetes-agent-tentacle/dev/scripts/bootstrap.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | ./dev-scripts/start-debugger.sh & ./scripts/configure-and-run.sh 4 | 5 | wait -n 6 | 7 | exit $? -------------------------------------------------------------------------------- /docker/kubernetes-agent-tentacle/dev/scripts/start-debugger.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | /usr/local/bin/debugger -port 7777 -------------------------------------------------------------------------------- /docker/linux/scripts/configure-and-run.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | set -eu 3 | 4 | /scripts/configure-tentacle.sh 5 | 6 | exec /scripts/run-tentacle.sh 7 | -------------------------------------------------------------------------------- /docker/windows/Scripts/configure-and-run-tentacle-wrapper.ps1: -------------------------------------------------------------------------------- 1 | & ./configure-tentacle.ps1 -Verbose 2 | & ./run-tentacle.ps1 -Verbose -------------------------------------------------------------------------------- /docs/artifactory.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OctopusDeploy/OctopusTentacle/ea14d2f07576b34349c2710609e562b56aa33824/docs/artifactory.png -------------------------------------------------------------------------------- /docs/chocolatey.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OctopusDeploy/OctopusTentacle/ea14d2f07576b34349c2710609e562b56aa33824/docs/chocolatey.png -------------------------------------------------------------------------------- /docs/downloads-page.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OctopusDeploy/OctopusTentacle/ea14d2f07576b34349c2710609e562b56aa33824/docs/downloads-page.png -------------------------------------------------------------------------------- /docs/octopus-deploy.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OctopusDeploy/OctopusTentacle/ea14d2f07576b34349c2710609e562b56aa33824/docs/octopus-deploy.png -------------------------------------------------------------------------------- /docs/slipway-create-release.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OctopusDeploy/OctopusTentacle/ea14d2f07576b34349c2710609e562b56aa33824/docs/slipway-create-release.png -------------------------------------------------------------------------------- /docs/slipway.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OctopusDeploy/OctopusTentacle/ea14d2f07576b34349c2710609e562b56aa33824/docs/slipway.png -------------------------------------------------------------------------------- /docs/tc-create-release.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OctopusDeploy/OctopusTentacle/ea14d2f07576b34349c2710609e562b56aa33824/docs/tc-create-release.png -------------------------------------------------------------------------------- /global.json: -------------------------------------------------------------------------------- 1 | { 2 | "sdk": { 3 | "version": "8.0.303", 4 | "rollForward": "latestFeature" 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /installer/Installer.1.1.dotCover: -------------------------------------------------------------------------------- 1 | 2 | 3 | L:\Stovell\Octopus-auto-update\source\Installers 4 | 5 | 6 | 7 | 8 | * 9 | * 10 | * 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /installer/Resources/Banner.bmp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OctopusDeploy/OctopusTentacle/ea14d2f07576b34349c2710609e562b56aa33824/installer/Resources/Banner.bmp -------------------------------------------------------------------------------- /installer/Resources/Dialog.bmp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OctopusDeploy/OctopusTentacle/ea14d2f07576b34349c2710609e562b56aa33824/installer/Resources/Dialog.bmp -------------------------------------------------------------------------------- /installer/Resources/Icon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OctopusDeploy/OctopusTentacle/ea14d2f07576b34349c2710609e562b56aa33824/installer/Resources/Icon.ico -------------------------------------------------------------------------------- /installer/Resources/Information.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OctopusDeploy/OctopusTentacle/ea14d2f07576b34349c2710609e562b56aa33824/installer/Resources/Information.ico -------------------------------------------------------------------------------- /installer/Resources/Warning.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OctopusDeploy/OctopusTentacle/ea14d2f07576b34349c2710609e562b56aa33824/installer/Resources/Warning.ico -------------------------------------------------------------------------------- /k8s-agent-debug-cluster-config/k8s-agent-debug-cluster.yaml: -------------------------------------------------------------------------------- 1 | kind: Cluster 2 | apiVersion: kind.x-k8s.io/v1alpha4 3 | name: k8s-agent-debug-cluster 4 | nodes: 5 | - role: control-plane 6 | extraMounts: 7 | - hostPath: /tmp/k8s-agent-debug-vol 8 | containerPath: /k8s-agent-debug-vol -------------------------------------------------------------------------------- /k8s-agent-debug-cluster-config/local-persistent-volume.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: PersistentVolume 3 | metadata: 4 | name: local-pv 5 | spec: 6 | capacity: 7 | storage: 10Gi 8 | accessModes: 9 | - ReadWriteMany 10 | persistentVolumeReclaimPolicy: Retain 11 | storageClassName: local-storage 12 | local: 13 | path: /k8s-agent-debug-vol 14 | nodeAffinity: 15 | required: 16 | nodeSelectorTerms: 17 | - matchExpressions: 18 | - key: kubernetes.io/hostname 19 | operator: In 20 | values: 21 | - k8s-agent-debug-cluster-control-plane -------------------------------------------------------------------------------- /k8s-agent-debug-cluster-config/local-storage-class.yaml: -------------------------------------------------------------------------------- 1 | kind: StorageClass 2 | apiVersion: storage.k8s.io/v1 3 | metadata: 4 | name: local-storage 5 | provisioner: kubernetes.io/no-provisioner 6 | volumeBindingMode: WaitForFirstConsumer -------------------------------------------------------------------------------- /linux-packages/content/after-install.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | echo "" 4 | echo "To set up a Tentacle instance, run the following script:" 5 | echo " /opt/octopus/tentacle/configure-tentacle.sh" 6 | echo "" 7 | -------------------------------------------------------------------------------- /linux-packages/content/before-uninstall.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | -------------------------------------------------------------------------------- /octoversion.json: -------------------------------------------------------------------------------- 1 | { 2 | "NonPreReleaseTags": ["main", "refs/heads/main"] 3 | } 4 | -------------------------------------------------------------------------------- /signtool.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OctopusDeploy/OctopusTentacle/ea14d2f07576b34349c2710609e562b56aa33824/signtool.exe -------------------------------------------------------------------------------- /source/Chocolatey-Net-Framework/chocolateyInstall.ps1: -------------------------------------------------------------------------------- 1 | Install-ChocolateyPackage ` 2 | -PackageName 'OctopusDeploy.Tentacle' ` 3 | -FileType 'msi' ` 4 | -SilentArgs '/quiet' ` 5 | -Url 'https://download.octopusdeploy.com/octopus/Octopus.Tentacle.0.0.0.msi' ` 6 | -Url64bit 'https://download.octopusdeploy.com/octopus/Octopus.Tentacle.0.0.0-x64.msi' ` 7 | -Checksum '' ` 8 | -ChecksumType '' ` 9 | -Checksum64 '' ` 10 | -ChecksumType64 '' 11 | -------------------------------------------------------------------------------- /source/Chocolatey-Self-Contained/chocolateyInstall.ps1: -------------------------------------------------------------------------------- 1 | Install-ChocolateyPackage ` 2 | -PackageName 'OctopusDeploy.Tentacle.SelfContained' ` 3 | -FileType 'msi' ` 4 | -SilentArgs '/quiet' ` 5 | -Url 'https://download.octopusdeploy.com/octopus/Octopus.Tentacle.0.0.0-net8.0-windows-win-x86.msi' ` 6 | -Url64bit 'https://download.octopusdeploy.com/octopus/Octopus.Tentacle.0.0.0-net8.0-windows-win-x64.msi' ` 7 | -Checksum '' ` 8 | -ChecksumType '' ` 9 | -Checksum64 '' ` 10 | -ChecksumType64 '' 11 | -------------------------------------------------------------------------------- /source/Octopus.Manager.Tentacle.Tests/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | #if NET8_0_OR_GREATER 2 | using System.Runtime.Versioning; 3 | [assembly: SupportedOSPlatform("windows")] 4 | #endif -------------------------------------------------------------------------------- /source/Octopus.Manager.Tentacle.Tests/Utils/CommandLineInvocationExtension.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using Octopus.Tentacle.Util; 5 | 6 | namespace Octopus.Manager.Tentacle.Tests.Utils 7 | { 8 | public static class CommandLineInvocationExtension 9 | { 10 | public static string ToCommandLineString(this IEnumerable source) 11 | { 12 | return string.Join(Environment.NewLine, source.Select(z => z.ToString())); 13 | } 14 | } 15 | } -------------------------------------------------------------------------------- /source/Octopus.Manager.Tentacle/App.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /source/Octopus.Manager.Tentacle/Controls/ControlGroup.cs: -------------------------------------------------------------------------------- 1 | using System.Windows; 2 | using System.Windows.Controls; 3 | 4 | namespace Octopus.Manager.Tentacle.Controls 5 | { 6 | public class ControlGroup : HeaderedItemsControl 7 | { 8 | public static readonly DependencyProperty TargetProperty = DependencyProperty.Register("Target", typeof (object), typeof (ControlGroup), new PropertyMetadata(null)); 9 | 10 | static ControlGroup() 11 | { 12 | DefaultStyleKeyProperty.OverrideMetadata(typeof (ControlGroup), new FrameworkPropertyMetadata(typeof (ControlGroup))); 13 | } 14 | 15 | public object Target 16 | { 17 | get => GetValue(TargetProperty); 18 | set => SetValue(TargetProperty, value); 19 | } 20 | } 21 | } -------------------------------------------------------------------------------- /source/Octopus.Manager.Tentacle/Converters/BooleanToVisibilityConverter.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Globalization; 3 | using System.Windows; 4 | using System.Windows.Data; 5 | 6 | namespace Octopus.Manager.Tentacle.Converters 7 | { 8 | public class BooleanToVisibilityConverter : IValueConverter 9 | { 10 | public object Convert(object value, Type targetType, object parameter, CultureInfo culture) 11 | { 12 | if ((bool) value) 13 | { 14 | return Visibility.Visible; 15 | } 16 | return Visibility.Collapsed; 17 | } 18 | 19 | public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) 20 | { 21 | throw new NotImplementedException(); 22 | } 23 | } 24 | } -------------------------------------------------------------------------------- /source/Octopus.Manager.Tentacle/Converters/BooleanToYesNoConverter.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Globalization; 3 | using System.Windows.Data; 4 | 5 | namespace Octopus.Manager.Tentacle.Converters 6 | { 7 | public class BooleanToYesNoConverter : IValueConverter 8 | { 9 | public object Convert(object value, Type targetType, object parameter, CultureInfo culture) 10 | { 11 | return value as bool? == true ? "Yes" : "No"; 12 | } 13 | 14 | public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) 15 | { 16 | throw new NotImplementedException(); 17 | } 18 | } 19 | } -------------------------------------------------------------------------------- /source/Octopus.Manager.Tentacle/Converters/InverseBooleanConverter.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Globalization; 3 | using System.Windows.Data; 4 | 5 | namespace Octopus.Manager.Tentacle.Converters 6 | { 7 | public class InverseBooleanConverter : IValueConverter 8 | { 9 | public object Convert(object value, Type targetType, object parameter, CultureInfo culture) 10 | { 11 | if (value is bool) 12 | return !(bool)value; 13 | 14 | return value; 15 | } 16 | 17 | public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) 18 | { 19 | if (value is bool) 20 | return !(bool)value; 21 | 22 | return value; 23 | } 24 | } 25 | } -------------------------------------------------------------------------------- /source/Octopus.Manager.Tentacle/Converters/InverseBooleanToVisibilityConverter.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Globalization; 3 | using System.Windows; 4 | using System.Windows.Data; 5 | 6 | namespace Octopus.Manager.Tentacle.Converters 7 | { 8 | public class InverseBooleanToVisibilityConverter : IValueConverter 9 | { 10 | public object Convert(object value, Type targetType, object parameter, CultureInfo culture) 11 | { 12 | if ((bool) value) 13 | { 14 | return Visibility.Collapsed; 15 | } 16 | return Visibility.Visible; 17 | } 18 | 19 | public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) 20 | { 21 | throw new NotImplementedException(); 22 | } 23 | } 24 | } -------------------------------------------------------------------------------- /source/Octopus.Manager.Tentacle/DeleteWizard/Views/DeleteWelcome.cs: -------------------------------------------------------------------------------- 1 | namespace Octopus.Manager.Tentacle.DeleteWizard.Views 2 | { 3 | /// 4 | /// Interaction logic for DeleteWelcome.xaml 5 | /// 6 | public partial class DeleteWelcome 7 | { 8 | public DeleteWelcome(DeleteWizardModel model) 9 | { 10 | InitializeComponent(); 11 | DataContext = model; 12 | } 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /source/Octopus.Manager.Tentacle/Dialogs/SetPasswordDialog.cs: -------------------------------------------------------------------------------- 1 | using System.Windows; 2 | using System.Windows.Controls; 3 | using MaterialDesignThemes.Wpf; 4 | 5 | namespace Octopus.Manager.Tentacle.Dialogs 6 | { 7 | public partial class SetPasswordDialog : UserControl 8 | { 9 | public SetPasswordDialog() 10 | { 11 | InitializeComponent(); 12 | } 13 | 14 | public string Password => password.Password; 15 | 16 | void SaveClicked(object sender, RoutedEventArgs e) 17 | { 18 | #pragma warning disable CA1416 19 | DialogHost.CloseDialogCommand.Execute(true, null); 20 | #pragma warning restore CA1416 21 | } 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /source/Octopus.Manager.Tentacle/Infrastructure/ICanHaveSensitiveValues.cs: -------------------------------------------------------------------------------- 1 | using Octopus.Tentacle.Core.Diagnostics; 2 | 3 | namespace Octopus.Manager.Tentacle.Infrastructure 4 | { 5 | public interface ICanHaveSensitiveValues 6 | { 7 | void ContributeSensitiveValues(ILog log); 8 | } 9 | } -------------------------------------------------------------------------------- /source/Octopus.Manager.Tentacle/Infrastructure/IHaveServices.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | 3 | namespace Octopus.Manager.Tentacle.Infrastructure 4 | { 5 | public interface IHaveServices 6 | { 7 | IEnumerable Services { get; } 8 | } 9 | } -------------------------------------------------------------------------------- /source/Octopus.Manager.Tentacle/Infrastructure/IScriptableViewModel.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using Octopus.Tentacle.Util; 3 | 4 | namespace Octopus.Manager.Tentacle.Infrastructure 5 | { 6 | public interface IScriptableViewModel : ICanHaveSensitiveValues 7 | { 8 | string InstanceName { get; } 9 | IEnumerable GenerateScript(); 10 | IEnumerable GenerateRollbackScript(); 11 | } 12 | } -------------------------------------------------------------------------------- /source/Octopus.Manager.Tentacle/Infrastructure/OctoService.cs: -------------------------------------------------------------------------------- 1 | namespace Octopus.Manager.Tentacle.Infrastructure 2 | { 3 | public class OctoService 4 | { 5 | public OctoService(string pathToOctopusServerExe, string instanceName) 6 | { 7 | Executable = pathToOctopusServerExe; 8 | InstanceName = instanceName; 9 | } 10 | 11 | public string Executable { get; set; } 12 | public string InstanceName { get; set; } 13 | } 14 | } -------------------------------------------------------------------------------- /source/Octopus.Manager.Tentacle/Infrastructure/TelemetryEventBatch.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using Newtonsoft.Json; 4 | 5 | namespace Octopus.Manager.Tentacle.Infrastructure 6 | { 7 | public class TelemetryEventBatch 8 | { 9 | [JsonProperty("client_upload_time")] 10 | public long Timestamp { get; } = DateTimeOffset.UtcNow.ToUnixTimeSeconds(); 11 | 12 | [JsonProperty("events")] 13 | public IEnumerable Events { get; } 14 | 15 | public TelemetryEventBatch(TelemetryEvent eventObj) 16 | { 17 | Events = new List { eventObj }; 18 | } 19 | } 20 | } -------------------------------------------------------------------------------- /source/Octopus.Manager.Tentacle/PreReq/IPrerequisite.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace Octopus.Manager.Tentacle.PreReq 4 | { 5 | public interface IPrerequisite 6 | { 7 | string StatusMessage { get; } 8 | PrerequisiteCheckResult Check(); 9 | } 10 | } -------------------------------------------------------------------------------- /source/Octopus.Manager.Tentacle/PreReq/IPrerequisiteProfile.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | 3 | namespace Octopus.Manager.Tentacle.PreReq 4 | { 5 | public interface IPrerequisiteProfile 6 | { 7 | IEnumerable Prerequisites { get; } 8 | } 9 | } -------------------------------------------------------------------------------- /source/Octopus.Manager.Tentacle/PreReq/TentaclePrerequisiteProfile.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | 3 | namespace Octopus.Manager.Tentacle.PreReq 4 | { 5 | public class TentaclePrerequisiteProfile : IPrerequisiteProfile 6 | { 7 | public TentaclePrerequisiteProfile() 8 | { 9 | Prerequisites = new IPrerequisite[] 10 | { 11 | new PowerShellPrerequisite() 12 | }; 13 | } 14 | 15 | public IEnumerable Prerequisites { get; } 16 | } 17 | } -------------------------------------------------------------------------------- /source/Octopus.Manager.Tentacle/Properties/Icon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OctopusDeploy/OctopusTentacle/ea14d2f07576b34349c2710609e562b56aa33824/source/Octopus.Manager.Tentacle/Properties/Icon.ico -------------------------------------------------------------------------------- /source/Octopus.Manager.Tentacle/Properties/Settings.settings: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /source/Octopus.Manager.Tentacle/Proxy/ProxyConfigurationTab.cs: -------------------------------------------------------------------------------- 1 | namespace Octopus.Manager.Tentacle.Proxy 2 | { 3 | /// 4 | /// Interaction logic for ProxyConfigurationTab.xaml 5 | /// 6 | public partial class ProxyConfigurationTab 7 | { 8 | public ProxyConfigurationTab(ProxyWizardModel model) 9 | { 10 | InitializeComponent(); 11 | DataContext = model; 12 | } 13 | 14 | public ProxyConfigurationTab() 15 | { 16 | InitializeComponent(); 17 | } 18 | } 19 | } -------------------------------------------------------------------------------- /source/Octopus.Manager.Tentacle/Resources/Icon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OctopusDeploy/OctopusTentacle/ea14d2f07576b34349c2710609e562b56aa33824/source/Octopus.Manager.Tentacle/Resources/Icon.ico -------------------------------------------------------------------------------- /source/Octopus.Manager.Tentacle/Resources/Images/TentacleActive.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OctopusDeploy/OctopusTentacle/ea14d2f07576b34349c2710609e562b56aa33824/source/Octopus.Manager.Tentacle/Resources/Images/TentacleActive.png -------------------------------------------------------------------------------- /source/Octopus.Manager.Tentacle/Resources/Images/TentaclePassive.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OctopusDeploy/OctopusTentacle/ea14d2f07576b34349c2710609e562b56aa33824/source/Octopus.Manager.Tentacle/Resources/Images/TentaclePassive.png -------------------------------------------------------------------------------- /source/Octopus.Manager.Tentacle/Resources/Images/Warning-ico-dropshadow.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OctopusDeploy/OctopusTentacle/ea14d2f07576b34349c2710609e562b56aa33824/source/Octopus.Manager.Tentacle/Resources/Images/Warning-ico-dropshadow.png -------------------------------------------------------------------------------- /source/Octopus.Manager.Tentacle/Resources/Images/Warning-ico-dropshadow@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OctopusDeploy/OctopusTentacle/ea14d2f07576b34349c2710609e562b56aa33824/source/Octopus.Manager.Tentacle/Resources/Images/Warning-ico-dropshadow@2x.png -------------------------------------------------------------------------------- /source/Octopus.Manager.Tentacle/Resources/Images/Warning-ico-dropshadow@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OctopusDeploy/OctopusTentacle/ea14d2f07576b34349c2710609e562b56aa33824/source/Octopus.Manager.Tentacle/Resources/Images/Warning-ico-dropshadow@3x.png -------------------------------------------------------------------------------- /source/Octopus.Manager.Tentacle/Resources/Images/Warning-ico-dropshadow@4x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OctopusDeploy/OctopusTentacle/ea14d2f07576b34349c2710609e562b56aa33824/source/Octopus.Manager.Tentacle/Resources/Images/Warning-ico-dropshadow@4x.png -------------------------------------------------------------------------------- /source/Octopus.Manager.Tentacle/Resources/Images/alert-error.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OctopusDeploy/OctopusTentacle/ea14d2f07576b34349c2710609e562b56aa33824/source/Octopus.Manager.Tentacle/Resources/Images/alert-error.png -------------------------------------------------------------------------------- /source/Octopus.Manager.Tentacle/Resources/Images/alert-error@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OctopusDeploy/OctopusTentacle/ea14d2f07576b34349c2710609e562b56aa33824/source/Octopus.Manager.Tentacle/Resources/Images/alert-error@2x.png -------------------------------------------------------------------------------- /source/Octopus.Manager.Tentacle/Resources/Images/alert-error@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OctopusDeploy/OctopusTentacle/ea14d2f07576b34349c2710609e562b56aa33824/source/Octopus.Manager.Tentacle/Resources/Images/alert-error@3x.png -------------------------------------------------------------------------------- /source/Octopus.Manager.Tentacle/Resources/Images/alert-error@4x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OctopusDeploy/OctopusTentacle/ea14d2f07576b34349c2710609e562b56aa33824/source/Octopus.Manager.Tentacle/Resources/Images/alert-error@4x.png -------------------------------------------------------------------------------- /source/Octopus.Manager.Tentacle/Resources/Images/alert.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OctopusDeploy/OctopusTentacle/ea14d2f07576b34349c2710609e562b56aa33824/source/Octopus.Manager.Tentacle/Resources/Images/alert.png -------------------------------------------------------------------------------- /source/Octopus.Manager.Tentacle/Resources/Images/alert@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OctopusDeploy/OctopusTentacle/ea14d2f07576b34349c2710609e562b56aa33824/source/Octopus.Manager.Tentacle/Resources/Images/alert@2x.png -------------------------------------------------------------------------------- /source/Octopus.Manager.Tentacle/Resources/Images/alert@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OctopusDeploy/OctopusTentacle/ea14d2f07576b34349c2710609e562b56aa33824/source/Octopus.Manager.Tentacle/Resources/Images/alert@3x.png -------------------------------------------------------------------------------- /source/Octopus.Manager.Tentacle/Resources/Images/alert@4x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OctopusDeploy/OctopusTentacle/ea14d2f07576b34349c2710609e562b56aa33824/source/Octopus.Manager.Tentacle/Resources/Images/alert@4x.png -------------------------------------------------------------------------------- /source/Octopus.Manager.Tentacle/Resources/Images/button_circle_blue_right.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OctopusDeploy/OctopusTentacle/ea14d2f07576b34349c2710609e562b56aa33824/source/Octopus.Manager.Tentacle/Resources/Images/button_circle_blue_right.png -------------------------------------------------------------------------------- /source/Octopus.Manager.Tentacle/Resources/Images/button_circle_blue_right@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OctopusDeploy/OctopusTentacle/ea14d2f07576b34349c2710609e562b56aa33824/source/Octopus.Manager.Tentacle/Resources/Images/button_circle_blue_right@2x.png -------------------------------------------------------------------------------- /source/Octopus.Manager.Tentacle/Resources/Images/button_circle_blue_right@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OctopusDeploy/OctopusTentacle/ea14d2f07576b34349c2710609e562b56aa33824/source/Octopus.Manager.Tentacle/Resources/Images/button_circle_blue_right@3x.png -------------------------------------------------------------------------------- /source/Octopus.Manager.Tentacle/Resources/Images/button_circle_blue_right@4x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OctopusDeploy/OctopusTentacle/ea14d2f07576b34349c2710609e562b56aa33824/source/Octopus.Manager.Tentacle/Resources/Images/button_circle_blue_right@4x.png -------------------------------------------------------------------------------- /source/Octopus.Manager.Tentacle/Resources/Images/button_rounded_green_delete.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OctopusDeploy/OctopusTentacle/ea14d2f07576b34349c2710609e562b56aa33824/source/Octopus.Manager.Tentacle/Resources/Images/button_rounded_green_delete.png -------------------------------------------------------------------------------- /source/Octopus.Manager.Tentacle/Resources/Images/button_rounded_green_delete@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OctopusDeploy/OctopusTentacle/ea14d2f07576b34349c2710609e562b56aa33824/source/Octopus.Manager.Tentacle/Resources/Images/button_rounded_green_delete@2x.png -------------------------------------------------------------------------------- /source/Octopus.Manager.Tentacle/Resources/Images/button_rounded_green_delete@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OctopusDeploy/OctopusTentacle/ea14d2f07576b34349c2710609e562b56aa33824/source/Octopus.Manager.Tentacle/Resources/Images/button_rounded_green_delete@3x.png -------------------------------------------------------------------------------- /source/Octopus.Manager.Tentacle/Resources/Images/button_rounded_green_delete@4x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OctopusDeploy/OctopusTentacle/ea14d2f07576b34349c2710609e562b56aa33824/source/Octopus.Manager.Tentacle/Resources/Images/button_rounded_green_delete@4x.png -------------------------------------------------------------------------------- /source/Octopus.Manager.Tentacle/Resources/Images/button_rounded_green_last.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OctopusDeploy/OctopusTentacle/ea14d2f07576b34349c2710609e562b56aa33824/source/Octopus.Manager.Tentacle/Resources/Images/button_rounded_green_last.png -------------------------------------------------------------------------------- /source/Octopus.Manager.Tentacle/Resources/Images/button_rounded_green_last@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OctopusDeploy/OctopusTentacle/ea14d2f07576b34349c2710609e562b56aa33824/source/Octopus.Manager.Tentacle/Resources/Images/button_rounded_green_last@2x.png -------------------------------------------------------------------------------- /source/Octopus.Manager.Tentacle/Resources/Images/button_rounded_green_last@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OctopusDeploy/OctopusTentacle/ea14d2f07576b34349c2710609e562b56aa33824/source/Octopus.Manager.Tentacle/Resources/Images/button_rounded_green_last@3x.png -------------------------------------------------------------------------------- /source/Octopus.Manager.Tentacle/Resources/Images/button_rounded_green_last@4x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OctopusDeploy/OctopusTentacle/ea14d2f07576b34349c2710609e562b56aa33824/source/Octopus.Manager.Tentacle/Resources/Images/button_rounded_green_last@4x.png -------------------------------------------------------------------------------- /source/Octopus.Manager.Tentacle/Resources/Images/button_rounded_green_next.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OctopusDeploy/OctopusTentacle/ea14d2f07576b34349c2710609e562b56aa33824/source/Octopus.Manager.Tentacle/Resources/Images/button_rounded_green_next.png -------------------------------------------------------------------------------- /source/Octopus.Manager.Tentacle/Resources/Images/button_rounded_green_next@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OctopusDeploy/OctopusTentacle/ea14d2f07576b34349c2710609e562b56aa33824/source/Octopus.Manager.Tentacle/Resources/Images/button_rounded_green_next@2x.png -------------------------------------------------------------------------------- /source/Octopus.Manager.Tentacle/Resources/Images/button_rounded_green_next@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OctopusDeploy/OctopusTentacle/ea14d2f07576b34349c2710609e562b56aa33824/source/Octopus.Manager.Tentacle/Resources/Images/button_rounded_green_next@3x.png -------------------------------------------------------------------------------- /source/Octopus.Manager.Tentacle/Resources/Images/button_rounded_green_next@4x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OctopusDeploy/OctopusTentacle/ea14d2f07576b34349c2710609e562b56aa33824/source/Octopus.Manager.Tentacle/Resources/Images/button_rounded_green_next@4x.png -------------------------------------------------------------------------------- /source/Octopus.Manager.Tentacle/Resources/Images/button_rounded_green_right.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OctopusDeploy/OctopusTentacle/ea14d2f07576b34349c2710609e562b56aa33824/source/Octopus.Manager.Tentacle/Resources/Images/button_rounded_green_right.png -------------------------------------------------------------------------------- /source/Octopus.Manager.Tentacle/Resources/Images/button_rounded_green_right@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OctopusDeploy/OctopusTentacle/ea14d2f07576b34349c2710609e562b56aa33824/source/Octopus.Manager.Tentacle/Resources/Images/button_rounded_green_right@2x.png -------------------------------------------------------------------------------- /source/Octopus.Manager.Tentacle/Resources/Images/button_rounded_green_right@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OctopusDeploy/OctopusTentacle/ea14d2f07576b34349c2710609e562b56aa33824/source/Octopus.Manager.Tentacle/Resources/Images/button_rounded_green_right@3x.png -------------------------------------------------------------------------------- /source/Octopus.Manager.Tentacle/Resources/Images/button_rounded_green_right@4x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OctopusDeploy/OctopusTentacle/ea14d2f07576b34349c2710609e562b56aa33824/source/Octopus.Manager.Tentacle/Resources/Images/button_rounded_green_right@4x.png -------------------------------------------------------------------------------- /source/Octopus.Manager.Tentacle/Resources/Images/button_rounded_orange_next.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OctopusDeploy/OctopusTentacle/ea14d2f07576b34349c2710609e562b56aa33824/source/Octopus.Manager.Tentacle/Resources/Images/button_rounded_orange_next.png -------------------------------------------------------------------------------- /source/Octopus.Manager.Tentacle/Resources/Images/button_rounded_orange_next@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OctopusDeploy/OctopusTentacle/ea14d2f07576b34349c2710609e562b56aa33824/source/Octopus.Manager.Tentacle/Resources/Images/button_rounded_orange_next@2x.png -------------------------------------------------------------------------------- /source/Octopus.Manager.Tentacle/Resources/Images/button_rounded_orange_next@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OctopusDeploy/OctopusTentacle/ea14d2f07576b34349c2710609e562b56aa33824/source/Octopus.Manager.Tentacle/Resources/Images/button_rounded_orange_next@3x.png -------------------------------------------------------------------------------- /source/Octopus.Manager.Tentacle/Resources/Images/button_rounded_orange_next@4x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OctopusDeploy/OctopusTentacle/ea14d2f07576b34349c2710609e562b56aa33824/source/Octopus.Manager.Tentacle/Resources/Images/button_rounded_orange_next@4x.png -------------------------------------------------------------------------------- /source/Octopus.Manager.Tentacle/Resources/Images/clipboard-export.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OctopusDeploy/OctopusTentacle/ea14d2f07576b34349c2710609e562b56aa33824/source/Octopus.Manager.Tentacle/Resources/Images/clipboard-export.png -------------------------------------------------------------------------------- /source/Octopus.Manager.Tentacle/Resources/Images/clipboard-export@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OctopusDeploy/OctopusTentacle/ea14d2f07576b34349c2710609e562b56aa33824/source/Octopus.Manager.Tentacle/Resources/Images/clipboard-export@2x.png -------------------------------------------------------------------------------- /source/Octopus.Manager.Tentacle/Resources/Images/clipboard-export@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OctopusDeploy/OctopusTentacle/ea14d2f07576b34349c2710609e562b56aa33824/source/Octopus.Manager.Tentacle/Resources/Images/clipboard-export@3x.png -------------------------------------------------------------------------------- /source/Octopus.Manager.Tentacle/Resources/Images/clipboard-export@4x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OctopusDeploy/OctopusTentacle/ea14d2f07576b34349c2710609e562b56aa33824/source/Octopus.Manager.Tentacle/Resources/Images/clipboard-export@4x.png -------------------------------------------------------------------------------- /source/Octopus.Manager.Tentacle/Resources/Images/database-export.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OctopusDeploy/OctopusTentacle/ea14d2f07576b34349c2710609e562b56aa33824/source/Octopus.Manager.Tentacle/Resources/Images/database-export.png -------------------------------------------------------------------------------- /source/Octopus.Manager.Tentacle/Resources/Images/database-export@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OctopusDeploy/OctopusTentacle/ea14d2f07576b34349c2710609e562b56aa33824/source/Octopus.Manager.Tentacle/Resources/Images/database-export@2x.png -------------------------------------------------------------------------------- /source/Octopus.Manager.Tentacle/Resources/Images/database-export@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OctopusDeploy/OctopusTentacle/ea14d2f07576b34349c2710609e562b56aa33824/source/Octopus.Manager.Tentacle/Resources/Images/database-export@3x.png -------------------------------------------------------------------------------- /source/Octopus.Manager.Tentacle/Resources/Images/database-export@4x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OctopusDeploy/OctopusTentacle/ea14d2f07576b34349c2710609e562b56aa33824/source/Octopus.Manager.Tentacle/Resources/Images/database-export@4x.png -------------------------------------------------------------------------------- /source/Octopus.Manager.Tentacle/Resources/Images/database-favorite2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OctopusDeploy/OctopusTentacle/ea14d2f07576b34349c2710609e562b56aa33824/source/Octopus.Manager.Tentacle/Resources/Images/database-favorite2.png -------------------------------------------------------------------------------- /source/Octopus.Manager.Tentacle/Resources/Images/database-favorite2@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OctopusDeploy/OctopusTentacle/ea14d2f07576b34349c2710609e562b56aa33824/source/Octopus.Manager.Tentacle/Resources/Images/database-favorite2@2x.png -------------------------------------------------------------------------------- /source/Octopus.Manager.Tentacle/Resources/Images/database-favorite2@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OctopusDeploy/OctopusTentacle/ea14d2f07576b34349c2710609e562b56aa33824/source/Octopus.Manager.Tentacle/Resources/Images/database-favorite2@3x.png -------------------------------------------------------------------------------- /source/Octopus.Manager.Tentacle/Resources/Images/database-favorite2@4x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OctopusDeploy/OctopusTentacle/ea14d2f07576b34349c2710609e562b56aa33824/source/Octopus.Manager.Tentacle/Resources/Images/database-favorite2@4x.png -------------------------------------------------------------------------------- /source/Octopus.Manager.Tentacle/Resources/Images/database-import.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OctopusDeploy/OctopusTentacle/ea14d2f07576b34349c2710609e562b56aa33824/source/Octopus.Manager.Tentacle/Resources/Images/database-import.png -------------------------------------------------------------------------------- /source/Octopus.Manager.Tentacle/Resources/Images/database-import@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OctopusDeploy/OctopusTentacle/ea14d2f07576b34349c2710609e562b56aa33824/source/Octopus.Manager.Tentacle/Resources/Images/database-import@2x.png -------------------------------------------------------------------------------- /source/Octopus.Manager.Tentacle/Resources/Images/database-import@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OctopusDeploy/OctopusTentacle/ea14d2f07576b34349c2710609e562b56aa33824/source/Octopus.Manager.Tentacle/Resources/Images/database-import@3x.png -------------------------------------------------------------------------------- /source/Octopus.Manager.Tentacle/Resources/Images/database-import@4x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OctopusDeploy/OctopusTentacle/ea14d2f07576b34349c2710609e562b56aa33824/source/Octopus.Manager.Tentacle/Resources/Images/database-import@4x.png -------------------------------------------------------------------------------- /source/Octopus.Manager.Tentacle/Resources/Images/database-up.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OctopusDeploy/OctopusTentacle/ea14d2f07576b34349c2710609e562b56aa33824/source/Octopus.Manager.Tentacle/Resources/Images/database-up.png -------------------------------------------------------------------------------- /source/Octopus.Manager.Tentacle/Resources/Images/database-up@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OctopusDeploy/OctopusTentacle/ea14d2f07576b34349c2710609e562b56aa33824/source/Octopus.Manager.Tentacle/Resources/Images/database-up@2x.png -------------------------------------------------------------------------------- /source/Octopus.Manager.Tentacle/Resources/Images/database-up@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OctopusDeploy/OctopusTentacle/ea14d2f07576b34349c2710609e562b56aa33824/source/Octopus.Manager.Tentacle/Resources/Images/database-up@3x.png -------------------------------------------------------------------------------- /source/Octopus.Manager.Tentacle/Resources/Images/database-up@4x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OctopusDeploy/OctopusTentacle/ea14d2f07576b34349c2710609e562b56aa33824/source/Octopus.Manager.Tentacle/Resources/Images/database-up@4x.png -------------------------------------------------------------------------------- /source/Octopus.Manager.Tentacle/Resources/Images/database_restore.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OctopusDeploy/OctopusTentacle/ea14d2f07576b34349c2710609e562b56aa33824/source/Octopus.Manager.Tentacle/Resources/Images/database_restore.png -------------------------------------------------------------------------------- /source/Octopus.Manager.Tentacle/Resources/Images/database_restore@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OctopusDeploy/OctopusTentacle/ea14d2f07576b34349c2710609e562b56aa33824/source/Octopus.Manager.Tentacle/Resources/Images/database_restore@2x.png -------------------------------------------------------------------------------- /source/Octopus.Manager.Tentacle/Resources/Images/database_restore@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OctopusDeploy/OctopusTentacle/ea14d2f07576b34349c2710609e562b56aa33824/source/Octopus.Manager.Tentacle/Resources/Images/database_restore@3x.png -------------------------------------------------------------------------------- /source/Octopus.Manager.Tentacle/Resources/Images/database_restore@4x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OctopusDeploy/OctopusTentacle/ea14d2f07576b34349c2710609e562b56aa33824/source/Octopus.Manager.Tentacle/Resources/Images/database_restore@4x.png -------------------------------------------------------------------------------- /source/Octopus.Manager.Tentacle/Resources/Images/delete.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OctopusDeploy/OctopusTentacle/ea14d2f07576b34349c2710609e562b56aa33824/source/Octopus.Manager.Tentacle/Resources/Images/delete.png -------------------------------------------------------------------------------- /source/Octopus.Manager.Tentacle/Resources/Images/delete@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OctopusDeploy/OctopusTentacle/ea14d2f07576b34349c2710609e562b56aa33824/source/Octopus.Manager.Tentacle/Resources/Images/delete@2x.png -------------------------------------------------------------------------------- /source/Octopus.Manager.Tentacle/Resources/Images/delete@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OctopusDeploy/OctopusTentacle/ea14d2f07576b34349c2710609e562b56aa33824/source/Octopus.Manager.Tentacle/Resources/Images/delete@3x.png -------------------------------------------------------------------------------- /source/Octopus.Manager.Tentacle/Resources/Images/delete@4x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OctopusDeploy/OctopusTentacle/ea14d2f07576b34349c2710609e562b56aa33824/source/Octopus.Manager.Tentacle/Resources/Images/delete@4x.png -------------------------------------------------------------------------------- /source/Octopus.Manager.Tentacle/Resources/Images/help.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OctopusDeploy/OctopusTentacle/ea14d2f07576b34349c2710609e562b56aa33824/source/Octopus.Manager.Tentacle/Resources/Images/help.png -------------------------------------------------------------------------------- /source/Octopus.Manager.Tentacle/Resources/Images/help@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OctopusDeploy/OctopusTentacle/ea14d2f07576b34349c2710609e562b56aa33824/source/Octopus.Manager.Tentacle/Resources/Images/help@2x.png -------------------------------------------------------------------------------- /source/Octopus.Manager.Tentacle/Resources/Images/help@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OctopusDeploy/OctopusTentacle/ea14d2f07576b34349c2710609e562b56aa33824/source/Octopus.Manager.Tentacle/Resources/Images/help@3x.png -------------------------------------------------------------------------------- /source/Octopus.Manager.Tentacle/Resources/Images/help@4x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OctopusDeploy/OctopusTentacle/ea14d2f07576b34349c2710609e562b56aa33824/source/Octopus.Manager.Tentacle/Resources/Images/help@4x.png -------------------------------------------------------------------------------- /source/Octopus.Manager.Tentacle/Resources/Images/history.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OctopusDeploy/OctopusTentacle/ea14d2f07576b34349c2710609e562b56aa33824/source/Octopus.Manager.Tentacle/Resources/Images/history.png -------------------------------------------------------------------------------- /source/Octopus.Manager.Tentacle/Resources/Images/history@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OctopusDeploy/OctopusTentacle/ea14d2f07576b34349c2710609e562b56aa33824/source/Octopus.Manager.Tentacle/Resources/Images/history@2x.png -------------------------------------------------------------------------------- /source/Octopus.Manager.Tentacle/Resources/Images/history@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OctopusDeploy/OctopusTentacle/ea14d2f07576b34349c2710609e562b56aa33824/source/Octopus.Manager.Tentacle/Resources/Images/history@3x.png -------------------------------------------------------------------------------- /source/Octopus.Manager.Tentacle/Resources/Images/history@4x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OctopusDeploy/OctopusTentacle/ea14d2f07576b34349c2710609e562b56aa33824/source/Octopus.Manager.Tentacle/Resources/Images/history@4x.png -------------------------------------------------------------------------------- /source/Octopus.Manager.Tentacle/Resources/Images/internet-edit.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OctopusDeploy/OctopusTentacle/ea14d2f07576b34349c2710609e562b56aa33824/source/Octopus.Manager.Tentacle/Resources/Images/internet-edit.png -------------------------------------------------------------------------------- /source/Octopus.Manager.Tentacle/Resources/Images/internet-edit@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OctopusDeploy/OctopusTentacle/ea14d2f07576b34349c2710609e562b56aa33824/source/Octopus.Manager.Tentacle/Resources/Images/internet-edit@2x.png -------------------------------------------------------------------------------- /source/Octopus.Manager.Tentacle/Resources/Images/internet-edit@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OctopusDeploy/OctopusTentacle/ea14d2f07576b34349c2710609e562b56aa33824/source/Octopus.Manager.Tentacle/Resources/Images/internet-edit@3x.png -------------------------------------------------------------------------------- /source/Octopus.Manager.Tentacle/Resources/Images/internet-edit@4x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OctopusDeploy/OctopusTentacle/ea14d2f07576b34349c2710609e562b56aa33824/source/Octopus.Manager.Tentacle/Resources/Images/internet-edit@4x.png -------------------------------------------------------------------------------- /source/Octopus.Manager.Tentacle/Resources/Images/internet_browse.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OctopusDeploy/OctopusTentacle/ea14d2f07576b34349c2710609e562b56aa33824/source/Octopus.Manager.Tentacle/Resources/Images/internet_browse.png -------------------------------------------------------------------------------- /source/Octopus.Manager.Tentacle/Resources/Images/internet_browse@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OctopusDeploy/OctopusTentacle/ea14d2f07576b34349c2710609e562b56aa33824/source/Octopus.Manager.Tentacle/Resources/Images/internet_browse@2x.png -------------------------------------------------------------------------------- /source/Octopus.Manager.Tentacle/Resources/Images/internet_browse@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OctopusDeploy/OctopusTentacle/ea14d2f07576b34349c2710609e562b56aa33824/source/Octopus.Manager.Tentacle/Resources/Images/internet_browse@3x.png -------------------------------------------------------------------------------- /source/Octopus.Manager.Tentacle/Resources/Images/internet_browse@4x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OctopusDeploy/OctopusTentacle/ea14d2f07576b34349c2710609e562b56aa33824/source/Octopus.Manager.Tentacle/Resources/Images/internet_browse@4x.png -------------------------------------------------------------------------------- /source/Octopus.Manager.Tentacle/Resources/Images/key.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OctopusDeploy/OctopusTentacle/ea14d2f07576b34349c2710609e562b56aa33824/source/Octopus.Manager.Tentacle/Resources/Images/key.png -------------------------------------------------------------------------------- /source/Octopus.Manager.Tentacle/Resources/Images/key@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OctopusDeploy/OctopusTentacle/ea14d2f07576b34349c2710609e562b56aa33824/source/Octopus.Manager.Tentacle/Resources/Images/key@2x.png -------------------------------------------------------------------------------- /source/Octopus.Manager.Tentacle/Resources/Images/key@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OctopusDeploy/OctopusTentacle/ea14d2f07576b34349c2710609e562b56aa33824/source/Octopus.Manager.Tentacle/Resources/Images/key@3x.png -------------------------------------------------------------------------------- /source/Octopus.Manager.Tentacle/Resources/Images/key@4x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OctopusDeploy/OctopusTentacle/ea14d2f07576b34349c2710609e562b56aa33824/source/Octopus.Manager.Tentacle/Resources/Images/key@4x.png -------------------------------------------------------------------------------- /source/Octopus.Manager.Tentacle/Resources/Images/nav_blue_right.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OctopusDeploy/OctopusTentacle/ea14d2f07576b34349c2710609e562b56aa33824/source/Octopus.Manager.Tentacle/Resources/Images/nav_blue_right.png -------------------------------------------------------------------------------- /source/Octopus.Manager.Tentacle/Resources/Images/nav_blue_right@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OctopusDeploy/OctopusTentacle/ea14d2f07576b34349c2710609e562b56aa33824/source/Octopus.Manager.Tentacle/Resources/Images/nav_blue_right@2x.png -------------------------------------------------------------------------------- /source/Octopus.Manager.Tentacle/Resources/Images/nav_blue_right@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OctopusDeploy/OctopusTentacle/ea14d2f07576b34349c2710609e562b56aa33824/source/Octopus.Manager.Tentacle/Resources/Images/nav_blue_right@3x.png -------------------------------------------------------------------------------- /source/Octopus.Manager.Tentacle/Resources/Images/nav_blue_right@4x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OctopusDeploy/OctopusTentacle/ea14d2f07576b34349c2710609e562b56aa33824/source/Octopus.Manager.Tentacle/Resources/Images/nav_blue_right@4x.png -------------------------------------------------------------------------------- /source/Octopus.Manager.Tentacle/Resources/Images/ok.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OctopusDeploy/OctopusTentacle/ea14d2f07576b34349c2710609e562b56aa33824/source/Octopus.Manager.Tentacle/Resources/Images/ok.png -------------------------------------------------------------------------------- /source/Octopus.Manager.Tentacle/Resources/Images/ok@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OctopusDeploy/OctopusTentacle/ea14d2f07576b34349c2710609e562b56aa33824/source/Octopus.Manager.Tentacle/Resources/Images/ok@2x.png -------------------------------------------------------------------------------- /source/Octopus.Manager.Tentacle/Resources/Images/ok@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OctopusDeploy/OctopusTentacle/ea14d2f07576b34349c2710609e562b56aa33824/source/Octopus.Manager.Tentacle/Resources/Images/ok@3x.png -------------------------------------------------------------------------------- /source/Octopus.Manager.Tentacle/Resources/Images/ok@4x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OctopusDeploy/OctopusTentacle/ea14d2f07576b34349c2710609e562b56aa33824/source/Octopus.Manager.Tentacle/Resources/Images/ok@4x.png -------------------------------------------------------------------------------- /source/Octopus.Manager.Tentacle/Resources/Images/ok_button.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OctopusDeploy/OctopusTentacle/ea14d2f07576b34349c2710609e562b56aa33824/source/Octopus.Manager.Tentacle/Resources/Images/ok_button.png -------------------------------------------------------------------------------- /source/Octopus.Manager.Tentacle/Resources/Images/ok_button@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OctopusDeploy/OctopusTentacle/ea14d2f07576b34349c2710609e562b56aa33824/source/Octopus.Manager.Tentacle/Resources/Images/ok_button@2x.png -------------------------------------------------------------------------------- /source/Octopus.Manager.Tentacle/Resources/Images/ok_button@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OctopusDeploy/OctopusTentacle/ea14d2f07576b34349c2710609e562b56aa33824/source/Octopus.Manager.Tentacle/Resources/Images/ok_button@3x.png -------------------------------------------------------------------------------- /source/Octopus.Manager.Tentacle/Resources/Images/ok_button@4x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OctopusDeploy/OctopusTentacle/ea14d2f07576b34349c2710609e562b56aa33824/source/Octopus.Manager.Tentacle/Resources/Images/ok_button@4x.png -------------------------------------------------------------------------------- /source/Octopus.Manager.Tentacle/Resources/Images/server_network-internet.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OctopusDeploy/OctopusTentacle/ea14d2f07576b34349c2710609e562b56aa33824/source/Octopus.Manager.Tentacle/Resources/Images/server_network-internet.png -------------------------------------------------------------------------------- /source/Octopus.Manager.Tentacle/Resources/Images/server_network-internet@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OctopusDeploy/OctopusTentacle/ea14d2f07576b34349c2710609e562b56aa33824/source/Octopus.Manager.Tentacle/Resources/Images/server_network-internet@2x.png -------------------------------------------------------------------------------- /source/Octopus.Manager.Tentacle/Resources/Images/server_network-internet@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OctopusDeploy/OctopusTentacle/ea14d2f07576b34349c2710609e562b56aa33824/source/Octopus.Manager.Tentacle/Resources/Images/server_network-internet@3x.png -------------------------------------------------------------------------------- /source/Octopus.Manager.Tentacle/Resources/Images/server_network-internet@4x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OctopusDeploy/OctopusTentacle/ea14d2f07576b34349c2710609e562b56aa33824/source/Octopus.Manager.Tentacle/Resources/Images/server_network-internet@4x.png -------------------------------------------------------------------------------- /source/Octopus.Manager.Tentacle/Resources/Images/visitor_man-internet.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OctopusDeploy/OctopusTentacle/ea14d2f07576b34349c2710609e562b56aa33824/source/Octopus.Manager.Tentacle/Resources/Images/visitor_man-internet.png -------------------------------------------------------------------------------- /source/Octopus.Manager.Tentacle/Resources/Images/visitor_man-internet@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OctopusDeploy/OctopusTentacle/ea14d2f07576b34349c2710609e562b56aa33824/source/Octopus.Manager.Tentacle/Resources/Images/visitor_man-internet@2x.png -------------------------------------------------------------------------------- /source/Octopus.Manager.Tentacle/Resources/Images/visitor_man-internet@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OctopusDeploy/OctopusTentacle/ea14d2f07576b34349c2710609e562b56aa33824/source/Octopus.Manager.Tentacle/Resources/Images/visitor_man-internet@3x.png -------------------------------------------------------------------------------- /source/Octopus.Manager.Tentacle/Resources/Images/visitor_man-internet@4x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OctopusDeploy/OctopusTentacle/ea14d2f07576b34349c2710609e562b56aa33824/source/Octopus.Manager.Tentacle/Resources/Images/visitor_man-internet@4x.png -------------------------------------------------------------------------------- /source/Octopus.Manager.Tentacle/Resources/Images/warning.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OctopusDeploy/OctopusTentacle/ea14d2f07576b34349c2710609e562b56aa33824/source/Octopus.Manager.Tentacle/Resources/Images/warning.png -------------------------------------------------------------------------------- /source/Octopus.Manager.Tentacle/Resources/Images/warning@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OctopusDeploy/OctopusTentacle/ea14d2f07576b34349c2710609e562b56aa33824/source/Octopus.Manager.Tentacle/Resources/Images/warning@2x.png -------------------------------------------------------------------------------- /source/Octopus.Manager.Tentacle/Resources/Images/warning@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OctopusDeploy/OctopusTentacle/ea14d2f07576b34349c2710609e562b56aa33824/source/Octopus.Manager.Tentacle/Resources/Images/warning@3x.png -------------------------------------------------------------------------------- /source/Octopus.Manager.Tentacle/Resources/Images/warning@4x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OctopusDeploy/OctopusTentacle/ea14d2f07576b34349c2710609e562b56aa33824/source/Octopus.Manager.Tentacle/Resources/Images/warning@4x.png -------------------------------------------------------------------------------- /source/Octopus.Manager.Tentacle/Resources/Logo-Small-White-Text.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OctopusDeploy/OctopusTentacle/ea14d2f07576b34349c2710609e562b56aa33824/source/Octopus.Manager.Tentacle/Resources/Logo-Small-White-Text.png -------------------------------------------------------------------------------- /source/Octopus.Manager.Tentacle/Resources/logo-1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OctopusDeploy/OctopusTentacle/ea14d2f07576b34349c2710609e562b56aa33824/source/Octopus.Manager.Tentacle/Resources/logo-1x.png -------------------------------------------------------------------------------- /source/Octopus.Manager.Tentacle/Resources/logo-2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OctopusDeploy/OctopusTentacle/ea14d2f07576b34349c2710609e562b56aa33824/source/Octopus.Manager.Tentacle/Resources/logo-2x.png -------------------------------------------------------------------------------- /source/Octopus.Manager.Tentacle/Shell/ITab.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.ComponentModel; 3 | using System.Threading.Tasks; 4 | 5 | namespace Octopus.Manager.Tentacle.Shell 6 | { 7 | public interface ITab 8 | { 9 | bool IsNextEnabled { get; } 10 | bool IsSkipEnabled { get; } 11 | event Action OnNavigateNext; 12 | Task OnSkip(CancelEventArgs e); 13 | Task OnNext(CancelEventArgs e); 14 | void OnBack(CancelEventArgs e); 15 | } 16 | } -------------------------------------------------------------------------------- /source/Octopus.Manager.Tentacle/Shell/ITabWithNotifications.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace Octopus.Manager.Tentacle.Shell 4 | { 5 | public interface ITabWithNotifications 6 | { 7 | bool HasNotifications { get; } 8 | event EventHandler HasNotificationsChanged; 9 | } 10 | } -------------------------------------------------------------------------------- /source/Octopus.Manager.Tentacle/Shell/ShellViewModel.cs: -------------------------------------------------------------------------------- 1 | using Octopus.Manager.Tentacle.Infrastructure; 2 | using Octopus.Tentacle.Versioning; 3 | 4 | namespace Octopus.Manager.Tentacle.Shell 5 | { 6 | public class ShellViewModel : ViewModel 7 | { 8 | public ShellViewModel(InstanceSelectionModel instanceSelectionModel) 9 | { 10 | InstanceSelectionModel = instanceSelectionModel; 11 | VersionNumber = TentacleManager.SemanticVersionInfo.NuGetVersion; 12 | ShowEAPVersion = TentacleManager.SemanticVersionInfo.IsEarlyAccessProgram(); 13 | } 14 | 15 | public string VersionNumber { get; } 16 | 17 | public bool ShowEAPVersion { get; set; } 18 | 19 | public InstanceSelectionModel InstanceSelectionModel { get; } 20 | } 21 | } -------------------------------------------------------------------------------- /source/Octopus.Manager.Tentacle/TentacleConfiguration/SetupWizard/Views/TentaclePassiveTab.xaml.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace Octopus.Manager.Tentacle.TentacleConfiguration.SetupWizard.Views 4 | { 5 | /// 6 | /// Interaction logic for TentaclePassiveTab.xaml 7 | /// 8 | public partial class TentaclePassiveTab 9 | { 10 | public TentaclePassiveTab(SetupTentacleWizardModel viewModel) 11 | { 12 | InitializeComponent(); 13 | 14 | DataContext = viewModel; 15 | 16 | // Default to true only when using the UI 17 | viewModel.FirewallException = true; 18 | } 19 | } 20 | } -------------------------------------------------------------------------------- /source/Octopus.Manager.Tentacle/TentacleConfiguration/SetupWizard/Views/WelcomeTab.xaml.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Windows.Navigation; 3 | using Octopus.Manager.Tentacle.Util; 4 | 5 | namespace Octopus.Manager.Tentacle.TentacleConfiguration.SetupWizard.Views 6 | { 7 | /// 8 | /// Interaction logic for WelcomeTab.xaml 9 | /// 10 | public partial class WelcomeTab 11 | { 12 | public WelcomeTab(object model) 13 | { 14 | InitializeComponent(); 15 | 16 | DataContext = model; 17 | } 18 | } 19 | } -------------------------------------------------------------------------------- /source/Octopus.Manager.Tentacle/TentacleManager.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using Octopus.Tentacle.Versioning; 3 | 4 | namespace Octopus.Manager.Tentacle 5 | { 6 | public static class TentacleManager 7 | { 8 | public static readonly Assembly Assembly = typeof(TentacleManager).Assembly; 9 | public static readonly string InformationalVersion = Assembly.GetInformationalVersion() ?? "0.0.0"; 10 | public static readonly SemanticVersionInfo SemanticVersionInfo = new SemanticVersionInfo(Assembly); 11 | } 12 | } -------------------------------------------------------------------------------- /source/Octopus.Manager.Tentacle/Util/BrowserHelper.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.ComponentModel; 3 | using System.Diagnostics; 4 | 5 | namespace Octopus.Manager.Tentacle.Util 6 | { 7 | public static class BrowserHelper 8 | { 9 | public static void Open(Uri uri) 10 | { 11 | try 12 | { 13 | Process.Start(new ProcessStartInfo(uri.AbsoluteUri)); 14 | } 15 | catch (Win32Exception) 16 | { 17 | Process.Start(new ProcessStartInfo("IExplore.exe", uri.AbsoluteUri)); 18 | } 19 | } 20 | } 21 | } -------------------------------------------------------------------------------- /source/Octopus.Manager.Tentacle/Util/StringExtensions.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | 7 | namespace Octopus.Manager.Tentacle.Util 8 | { 9 | public static class StringExtensions 10 | { 11 | public static string FirstCharToUpper(this string input) 12 | { 13 | if (!string.IsNullOrEmpty(input)) 14 | return input.First().ToString().ToUpper() + input.Substring(1); 15 | return input; 16 | } 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /source/Octopus.Tentacle.Client.Tests/ExecuteShellScriptCommandBuilderTests.cs: -------------------------------------------------------------------------------- 1 | using FluentAssertions; 2 | using NUnit.Framework; 3 | using Octopus.Tentacle.Client.Scripts.Models.Builders; 4 | using Octopus.Tentacle.Contracts; 5 | 6 | namespace Octopus.Tentacle.Client.Tests 7 | { 8 | [TestFixture] 9 | public class ExecuteShellScriptCommandBuilderTests 10 | { 11 | [Test] 12 | public void WhenScriptTicket_ItOverridesTheGeneratedSriptTicket() 13 | { 14 | var scriptTicket = new ScriptTicket("arealticket"); 15 | new ExecuteShellScriptCommandBuilder("bob", ScriptIsolationLevel.FullIsolation) 16 | .WithScriptTicket(scriptTicket) 17 | .Build() 18 | .ScriptTicket.Should().Be(scriptTicket); 19 | } 20 | } 21 | } -------------------------------------------------------------------------------- /source/Octopus.Tentacle.Client/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Runtime.CompilerServices; 3 | 4 | [assembly: InternalsVisibleTo("Octopus.Tentacle.Tests")] 5 | [assembly: InternalsVisibleTo("Octopus.Tentacle.Client.Tests")] 6 | [assembly: InternalsVisibleTo("Octopus.Tentacle.Tests.Integration")] 7 | [assembly: InternalsVisibleTo("Octopus.Tentacle.Tests.Integration.Common")] 8 | [assembly: InternalsVisibleTo("Octopus.Tentacle.Kubernetes.Tests.Integration")] 9 | [assembly: InternalsVisibleTo("DynamicProxyGenAssembly2")] -------------------------------------------------------------------------------- /source/Octopus.Tentacle.Client/Capabilities/CapabilitiesResponseV2ExtensionMethods.cs: -------------------------------------------------------------------------------- 1 | using System.Linq; 2 | using Octopus.Tentacle.Contracts.Capabilities; 3 | using Octopus.Tentacle.Contracts.ScriptServiceV2; 4 | 5 | namespace Octopus.Tentacle.Client.Capabilities 6 | { 7 | internal static class CapabilitiesResponseV2ExtensionMethods 8 | { 9 | public static bool HasScriptServiceV2(this CapabilitiesResponseV2 capabilities) 10 | { 11 | if (capabilities?.SupportedCapabilities?.Any() != true) 12 | { 13 | return false; 14 | } 15 | 16 | return capabilities.SupportedCapabilities.Contains(nameof(IScriptServiceV2)); 17 | } 18 | } 19 | } -------------------------------------------------------------------------------- /source/Octopus.Tentacle.Client/ExceptionExtensionMethods.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using Halibut; 3 | using Halibut.Exceptions; 4 | using Halibut.Transport; 5 | 6 | namespace Octopus.Tentacle.Client 7 | { 8 | public static class ExceptionExtensionMethods 9 | { 10 | public static bool IsConnectionException(this Exception exception) 11 | { 12 | return exception is ConnectingRequestCancelledException 13 | || exception is HalibutClientException {ConnectionState: ConnectionState.Connecting}; 14 | } 15 | } 16 | } -------------------------------------------------------------------------------- /source/Octopus.Tentacle.Client/Execution/RpcCallExecutorFactory.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using Octopus.Tentacle.Client.Retries; 3 | using Octopus.Tentacle.Contracts.Observability; 4 | 5 | namespace Octopus.Tentacle.Client.Execution 6 | { 7 | internal static class RpcCallExecutorFactory 8 | { 9 | internal static RpcCallExecutor Create(TimeSpan retryDuration, ITentacleClientObserver tentacleClientObserver) 10 | { 11 | var rpcCallRetryHandler = new RpcCallRetryHandler(retryDuration); 12 | var rpcCallExecutor = new RpcCallExecutor(rpcCallRetryHandler, tentacleClientObserver); 13 | 14 | return rpcCallExecutor; 15 | } 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /source/Octopus.Tentacle.Client/ITentacleServiceDecoratorFactory.cs: -------------------------------------------------------------------------------- 1 | using Octopus.Tentacle.Contracts.ClientServices; 2 | 3 | namespace Octopus.Tentacle.Client 4 | { 5 | interface ITentacleServiceDecoratorFactory 6 | { 7 | public IAsyncClientScriptService Decorate(IAsyncClientScriptService scriptService); 8 | 9 | public IAsyncClientScriptServiceV2 Decorate(IAsyncClientScriptServiceV2 scriptService); 10 | 11 | public IAsyncClientFileTransferService Decorate(IAsyncClientFileTransferService service); 12 | 13 | public IAsyncClientCapabilitiesServiceV2 Decorate(IAsyncClientCapabilitiesServiceV2 service); 14 | 15 | public IAsyncClientKubernetesScriptServiceV1 Decorate(IAsyncClientKubernetesScriptServiceV1 service); 16 | } 17 | } -------------------------------------------------------------------------------- /source/Octopus.Tentacle.Client/Kubernetes/KubernetesCapabilitiesResponseV2ExtensionMethods.cs: -------------------------------------------------------------------------------- 1 | using System.Linq; 2 | using Octopus.Tentacle.Contracts.Capabilities; 3 | using Octopus.Tentacle.Contracts.KubernetesScriptServiceV1; 4 | 5 | namespace Octopus.Tentacle.Client.Kubernetes 6 | { 7 | public static class KubernetesCapabilitiesResponseV2ExtensionMethods 8 | { 9 | public static bool HasAnyKubernetesScriptService(this CapabilitiesResponseV2 capabilities) 10 | { 11 | if (capabilities?.SupportedCapabilities?.Any() != true) 12 | { 13 | return false; 14 | } 15 | 16 | return capabilities.SupportedCapabilities.Any(c => c.Contains("KubernetesScriptService")); 17 | } 18 | } 19 | } -------------------------------------------------------------------------------- /source/Octopus.Tentacle.Client/Observability/TentacleClientObserverExtensionMethods.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using Octopus.Tentacle.Contracts.Observability; 3 | 4 | namespace Octopus.Tentacle.Client.Observability 5 | { 6 | public static class TentacleClientObserverExtensionMethods 7 | { 8 | public static ITentacleClientObserver DecorateWithNonThrowingTentacleClientObserver(this ITentacleClientObserver tentacleClientObserver) 9 | { 10 | return new NonThrowingTentacleClientObserverDecorator(tentacleClientObserver); 11 | } 12 | } 13 | } -------------------------------------------------------------------------------- /source/Octopus.Tentacle.Client/Retries/RpcRetrySettings.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace Octopus.Tentacle.Client.Retries 4 | { 5 | public record RpcRetrySettings(bool RetriesEnabled, TimeSpan RetryDuration) 6 | { 7 | public bool RetriesEnabled { get; } = RetriesEnabled; 8 | public TimeSpan RetryDuration { get; } = RetryDuration; 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /source/Octopus.Tentacle.Client/Retries/TaskCompletionResult.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace Octopus.Tentacle.Client.Retries 4 | { 5 | public enum TaskCompletionResult 6 | { 7 | Completed, 8 | Abandoned 9 | } 10 | } -------------------------------------------------------------------------------- /source/Octopus.Tentacle.Client/Scripts/HalibutClientExceptionExtensionMethods.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using Halibut.Exceptions; 3 | 4 | namespace Octopus.Tentacle.Client.Scripts 5 | { 6 | public static class HalibutClientExceptionExtensionMethods 7 | { 8 | public static bool IsConnectingOrTransferringRequestCancelledException(this Exception ex) 9 | { 10 | return ex is ConnectingRequestCancelledException or TransferringRequestCancelledException; 11 | } 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /source/Octopus.Tentacle.Client/Scripts/IScriptObserverBackoffStrategy.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace Octopus.Tentacle.Client.Scripts 4 | { 5 | public interface IScriptObserverBackoffStrategy 6 | { 7 | TimeSpan GetBackoff(int iteration); 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /source/Octopus.Tentacle.Client/Scripts/Models/KubernetesImageConfiguration.cs: -------------------------------------------------------------------------------- 1 | namespace Octopus.Tentacle.Client.Scripts.Models 2 | { 3 | public class KubernetesImageConfiguration 4 | { 5 | public KubernetesImageConfiguration(string image, string? feedUrl, string? feedUsername, string? feedPassword) 6 | { 7 | Image = image; 8 | FeedUrl = feedUrl; 9 | FeedUsername = feedUsername; 10 | FeedPassword = feedPassword; 11 | } 12 | 13 | public string Image { get; } 14 | public string? FeedUrl { get; } 15 | public string? FeedUsername { get; } 16 | public string? FeedPassword { get; } 17 | } 18 | } -------------------------------------------------------------------------------- /source/Octopus.Tentacle.Client/Scripts/Models/ScriptExecutionResult.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using Octopus.Tentacle.Contracts; 3 | 4 | namespace Octopus.Tentacle.Client.Scripts.Models 5 | { 6 | public class ScriptExecutionResult 7 | { 8 | public ScriptExecutionResult(ProcessState state, int exitCode) 9 | { 10 | State = state; 11 | ExitCode = exitCode; 12 | } 13 | 14 | public ProcessState State { get; } 15 | 16 | public int ExitCode { get; } 17 | } 18 | } -------------------------------------------------------------------------------- /source/Octopus.Tentacle.Client/Scripts/Models/ScriptExecutionStatus.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using Octopus.Tentacle.Contracts; 4 | 5 | namespace Octopus.Tentacle.Client.Scripts.Models 6 | { 7 | public class ScriptExecutionStatus 8 | { 9 | public ScriptExecutionStatus(List logs) 10 | { 11 | Logs = logs; 12 | } 13 | 14 | public List Logs { get; } 15 | } 16 | } -------------------------------------------------------------------------------- /source/Octopus.Tentacle.Client/Scripts/Models/ScriptIsolationConfiguration.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using Octopus.Tentacle.Contracts; 3 | 4 | namespace Octopus.Tentacle.Client.Scripts.Models 5 | { 6 | public record ScriptIsolationConfiguration( 7 | ScriptIsolationLevel IsolationLevel, 8 | string MutexName, 9 | TimeSpan MutexTimeout) 10 | { 11 | public static readonly TimeSpan NoTimeout= TimeSpan.FromMilliseconds(int.MaxValue); 12 | } 13 | } -------------------------------------------------------------------------------- /source/Octopus.Tentacle.Client/Scripts/OnScriptCompleted.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Threading; 3 | using System.Threading.Tasks; 4 | 5 | namespace Octopus.Tentacle.Client.Scripts 6 | { 7 | public delegate Task OnScriptCompleted(CancellationToken cancellationToken); 8 | } -------------------------------------------------------------------------------- /source/Octopus.Tentacle.Client/Scripts/OnScriptStatusResponseReceived.cs: -------------------------------------------------------------------------------- 1 | using Octopus.Tentacle.Client.Scripts.Models; 2 | 3 | namespace Octopus.Tentacle.Client.Scripts 4 | { 5 | public delegate void OnScriptStatusResponseReceived(ScriptExecutionStatus status); 6 | } -------------------------------------------------------------------------------- /source/Octopus.Tentacle.Client/Scripts/ScriptObserverBackoffStrategy.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace Octopus.Tentacle.Client.Scripts 4 | { 5 | public abstract class ScriptObserverBackoffStrategy : IScriptObserverBackoffStrategy 6 | { 7 | readonly ExponentialBackoff exponentialBackoff; 8 | 9 | public ScriptObserverBackoffStrategy( 10 | TimeSpan minimumBackoffDelay, 11 | TimeSpan maximumBackoffDelay, 12 | double backoffBase) 13 | { 14 | exponentialBackoff = new ExponentialBackoff(minimumBackoffDelay, maximumBackoffDelay, backoffBase); 15 | } 16 | 17 | public TimeSpan GetBackoff(int iteration) => exponentialBackoff.Get(iteration++); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /source/Octopus.Tentacle.Client/Scripts/ScriptServiceVersion.cs: -------------------------------------------------------------------------------- 1 | namespace Octopus.Tentacle.Client.Scripts 2 | { 3 | public record ScriptServiceVersion(string Value) 4 | { 5 | public static ScriptServiceVersion ScriptServiceVersion1 = new(nameof(ScriptServiceVersion1)); 6 | public static ScriptServiceVersion ScriptServiceVersion2 = new(nameof(ScriptServiceVersion2)); 7 | public static ScriptServiceVersion KubernetesScriptServiceVersion1 = new(nameof(KubernetesScriptServiceVersion1)); 8 | 9 | public override string ToString() => Value; 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /source/Octopus.Tentacle.Client/Scripts/TaskExtensionMethods.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Threading.Tasks; 3 | 4 | namespace Octopus.Tentacle.Client.Scripts 5 | { 6 | internal static class TaskExtensionMethods 7 | { 8 | public static async Task SuppressOperationCanceledException(this Task task) 9 | { 10 | try 11 | { 12 | await task; 13 | } 14 | catch (OperationCanceledException) { } 15 | } 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /source/Octopus.Tentacle.Client/StartScriptIsBeingReAttempted.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace Octopus.Tentacle.Client 4 | { 5 | public enum StartScriptIsBeingReAttempted 6 | { 7 | FirstAttempt, 8 | PossiblyBeingReAttempted 9 | } 10 | } -------------------------------------------------------------------------------- /source/Octopus.Tentacle.Client/TentacleClientOptions.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using Octopus.Tentacle.Client.Retries; 3 | 4 | namespace Octopus.Tentacle.Client 5 | { 6 | public class TentacleClientOptions 7 | { 8 | public RpcRetrySettings RpcRetrySettings { get; } 9 | 10 | public TentacleClientOptions(RpcRetrySettings rpcRetrySettings) 11 | { 12 | RpcRetrySettings = rpcRetrySettings; 13 | } 14 | } 15 | } -------------------------------------------------------------------------------- /source/Octopus.Tentacle.CommonTestUtils/Builders/StartScriptCommandV2BuilderExtensionMethods.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Text; 3 | 4 | namespace Octopus.Tentacle.CommonTestUtils.Builders 5 | { 6 | public static class StartScriptCommandV2BuilderExtensionMethods 7 | { 8 | public static StartScriptCommandV2Builder WithScriptBodyForCurrentOs(this StartScriptCommandV2Builder builder, string windowsScript, string bashScript) 9 | { 10 | var scriptBody = new StringBuilder(PlatformDetection.IsRunningOnWindows ? windowsScript : bashScript); 11 | 12 | builder.WithScriptBody(scriptBody.ToString()); 13 | 14 | return builder; 15 | } 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /source/Octopus.Tentacle.CommonTestUtils/Certificates/Server.pfx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OctopusDeploy/OctopusTentacle/ea14d2f07576b34349c2710609e562b56aa33824/source/Octopus.Tentacle.CommonTestUtils/Certificates/Server.pfx -------------------------------------------------------------------------------- /source/Octopus.Tentacle.CommonTestUtils/Certificates/Tentacle.pfx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OctopusDeploy/OctopusTentacle/ea14d2f07576b34349c2710609e562b56aa33824/source/Octopus.Tentacle.CommonTestUtils/Certificates/Tentacle.pfx -------------------------------------------------------------------------------- /source/Octopus.Tentacle.CommonTestUtils/LoggingUtils.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Security.Cryptography; 3 | using System.Text; 4 | using NUnit.Framework; 5 | 6 | namespace Octopus.Tentacle.CommonTestUtils 7 | { 8 | public static class LoggingUtils 9 | { 10 | public static string CurrentTestHash() 11 | { 12 | using var sha256 = SHA256.Create(); 13 | return Convert.ToBase64String(sha256.ComputeHash(Encoding.UTF8.GetBytes(TestContext.CurrentContext.Test.FullName))) 14 | .Replace("=", "") 15 | .Replace("+", "") 16 | .Replace("/", "") 17 | .Substring(0, 10); // 64 ^ 10 is a big number, most likely we wont have collisions. 18 | } 19 | } 20 | } -------------------------------------------------------------------------------- /source/Octopus.Tentacle.CommonTestUtils/PlatformDetection.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Runtime.InteropServices; 3 | 4 | namespace Octopus.Tentacle.CommonTestUtils 5 | { 6 | public static class PlatformDetection 7 | { 8 | public static bool IsRunningOnNix => RuntimeInformation.IsOSPlatform(OSPlatform.Linux); 9 | public static bool IsRunningOnWindows => RuntimeInformation.IsOSPlatform(OSPlatform.Windows); 10 | public static bool IsRunningOnMac => RuntimeInformation.IsOSPlatform(OSPlatform.OSX); 11 | } 12 | } -------------------------------------------------------------------------------- /source/Octopus.Tentacle.Contracts/Builders/UniqueScriptTicketBuilder.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Linq; 3 | 4 | namespace Octopus.Tentacle.Contracts.Builders 5 | { 6 | public class UniqueScriptTicketBuilder 7 | { 8 | public ScriptTicket Build() 9 | { 10 | var e = Convert.ToBase64String(Guid.NewGuid().ToByteArray()); 11 | 12 | // Sanitise any non alpha or numeric characters 13 | e = string.Join("", e.Where(char.IsLetterOrDigit)); 14 | 15 | return new ScriptTicket(e); 16 | } 17 | } 18 | } -------------------------------------------------------------------------------- /source/Octopus.Tentacle.Contracts/CancelScriptCommand.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace Octopus.Tentacle.Contracts 4 | { 5 | public class CancelScriptCommand 6 | { 7 | public CancelScriptCommand(ScriptTicket ticket, long lastLogSequence) 8 | { 9 | Ticket = ticket; 10 | LastLogSequence = lastLogSequence; 11 | } 12 | 13 | public ScriptTicket Ticket { get; } 14 | 15 | public long LastLogSequence { get; } 16 | } 17 | } -------------------------------------------------------------------------------- /source/Octopus.Tentacle.Contracts/Capabilities/CapabilitiesResponseV2.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | 4 | namespace Octopus.Tentacle.Contracts.Capabilities 5 | { 6 | public class CapabilitiesResponseV2 7 | { 8 | public List SupportedCapabilities { get; } 9 | 10 | public CapabilitiesResponseV2(List supportedCapabilities) 11 | { 12 | this.SupportedCapabilities = supportedCapabilities; 13 | } 14 | } 15 | } -------------------------------------------------------------------------------- /source/Octopus.Tentacle.Contracts/Capabilities/ICapabilitiesServiceV2.cs: -------------------------------------------------------------------------------- 1 | using Halibut.Transport.Caching; 2 | 3 | namespace Octopus.Tentacle.Contracts.Capabilities 4 | { 5 | public interface ICapabilitiesServiceV2 6 | { 7 | [CacheResponse(600)] 8 | CapabilitiesResponseV2 GetCapabilities(); 9 | } 10 | } -------------------------------------------------------------------------------- /source/Octopus.Tentacle.Contracts/Capabilities/ICapabilitiesServiceV2ExtensionMethods.cs: -------------------------------------------------------------------------------- 1 | using Octopus.Tentacle.Contracts.ClientServices; 2 | 3 | namespace Octopus.Tentacle.Contracts.Capabilities 4 | { 5 | public static class ICapabilitiesServiceV2ExtensionMethods 6 | { 7 | public static ICapabilitiesServiceV2 WithBackwardsCompatability(this ICapabilitiesServiceV2 capabilitiesService) 8 | { 9 | return new BackwardsCompatibleCapabilitiesV2Decorator(capabilitiesService); 10 | } 11 | 12 | public static IAsyncClientCapabilitiesServiceV2 WithBackwardsCompatability(this IAsyncClientCapabilitiesServiceV2 capabilitiesService) 13 | { 14 | return new BackwardsCompatibleAsyncClientCapabilitiesV2Decorator(capabilitiesService); 15 | } 16 | } 17 | } -------------------------------------------------------------------------------- /source/Octopus.Tentacle.Contracts/ClientServices/IAsyncClientCapabilitiesServiceV2.cs: -------------------------------------------------------------------------------- 1 | using System.Threading.Tasks; 2 | using Halibut.ServiceModel; 3 | using Halibut.Transport.Caching; 4 | using Octopus.Tentacle.Contracts.Capabilities; 5 | 6 | namespace Octopus.Tentacle.Contracts.ClientServices 7 | { 8 | public interface IAsyncClientCapabilitiesServiceV2 9 | { 10 | [CacheResponse(600)] 11 | Task GetCapabilitiesAsync(HalibutProxyRequestOptions halibutProxyRequestOptions); 12 | } 13 | } -------------------------------------------------------------------------------- /source/Octopus.Tentacle.Contracts/ClientServices/IAsyncClientFileTransferService.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Threading.Tasks; 3 | using Halibut; 4 | using Halibut.ServiceModel; 5 | 6 | namespace Octopus.Tentacle.Contracts.ClientServices 7 | { 8 | public interface IAsyncClientFileTransferService 9 | { 10 | Task UploadFileAsync(string remotePath, DataStream upload, HalibutProxyRequestOptions halibutProxyRequestOptions); 11 | Task DownloadFileAsync(string remotePath, HalibutProxyRequestOptions halibutProxyRequestOptions); 12 | } 13 | } -------------------------------------------------------------------------------- /source/Octopus.Tentacle.Contracts/CompleteScriptCommand.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace Octopus.Tentacle.Contracts 4 | { 5 | public class CompleteScriptCommand 6 | { 7 | public CompleteScriptCommand(ScriptTicket ticket, long lastLogSequence) 8 | { 9 | Ticket = ticket; 10 | LastLogSequence = lastLogSequence; 11 | } 12 | 13 | public ScriptTicket Ticket { get; } 14 | 15 | public long LastLogSequence { get; } 16 | } 17 | } -------------------------------------------------------------------------------- /source/Octopus.Tentacle.Contracts/IFileTransferService.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using Halibut; 3 | 4 | namespace Octopus.Tentacle.Contracts 5 | { 6 | public interface IFileTransferService 7 | { 8 | UploadResult UploadFile(string remotePath, DataStream upload); 9 | DataStream DownloadFile(string remotePath); 10 | } 11 | } -------------------------------------------------------------------------------- /source/Octopus.Tentacle.Contracts/IScriptService.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace Octopus.Tentacle.Contracts 4 | { 5 | public interface IScriptService 6 | { 7 | ScriptTicket StartScript(StartScriptCommand command); 8 | ScriptStatusResponse GetStatus(ScriptStatusRequest request); 9 | ScriptStatusResponse CancelScript(CancelScriptCommand command); 10 | ScriptStatusResponse CompleteScript(CompleteScriptCommand command); 11 | } 12 | } -------------------------------------------------------------------------------- /source/Octopus.Tentacle.Contracts/KubernetesScriptServiceV1/CancelKubernetesScriptCommandV1.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace Octopus.Tentacle.Contracts.KubernetesScriptServiceV1 4 | { 5 | public class CancelKubernetesScriptCommandV1 6 | { 7 | public CancelKubernetesScriptCommandV1(ScriptTicket scriptTicket, long lastLogSequence) 8 | { 9 | ScriptTicket = scriptTicket; 10 | LastLogSequence = lastLogSequence; 11 | } 12 | 13 | public ScriptTicket ScriptTicket { get; } 14 | public long LastLogSequence { get; } 15 | } 16 | } -------------------------------------------------------------------------------- /source/Octopus.Tentacle.Contracts/KubernetesScriptServiceV1/CompleteKubernetesScriptCommandV1.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace Octopus.Tentacle.Contracts.KubernetesScriptServiceV1 4 | { 5 | public class CompleteKubernetesScriptCommandV1 6 | { 7 | public ScriptTicket ScriptTicket { get; } 8 | 9 | public CompleteKubernetesScriptCommandV1(ScriptTicket scriptTicket) 10 | { 11 | ScriptTicket = scriptTicket; 12 | } 13 | } 14 | } -------------------------------------------------------------------------------- /source/Octopus.Tentacle.Contracts/KubernetesScriptServiceV1/IKubernetesScriptServiceV1.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace Octopus.Tentacle.Contracts.KubernetesScriptServiceV1 4 | { 5 | public interface IKubernetesScriptServiceV1 6 | { 7 | KubernetesScriptStatusResponseV1 StartScript(StartKubernetesScriptCommandV1 command); 8 | KubernetesScriptStatusResponseV1 GetStatus(KubernetesScriptStatusRequestV1 request); 9 | KubernetesScriptStatusResponseV1 CancelScript(CancelKubernetesScriptCommandV1 command); 10 | void CompleteScript(CompleteKubernetesScriptCommandV1 command); 11 | } 12 | } -------------------------------------------------------------------------------- /source/Octopus.Tentacle.Contracts/KubernetesScriptServiceV1/KubernetesScriptStatusRequestV1.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace Octopus.Tentacle.Contracts.KubernetesScriptServiceV1 4 | { 5 | public class KubernetesScriptStatusRequestV1 6 | { 7 | public KubernetesScriptStatusRequestV1(ScriptTicket scriptTicket, long lastLogSequence) 8 | { 9 | ScriptTicket = scriptTicket; 10 | LastLogSequence = lastLogSequence; 11 | } 12 | 13 | public ScriptTicket ScriptTicket { get; } 14 | public long LastLogSequence { get; } 15 | } 16 | } -------------------------------------------------------------------------------- /source/Octopus.Tentacle.Contracts/Legacy/HalibutRuntimeExtensionMethods.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using Halibut; 3 | 4 | namespace Octopus.Tentacle.Contracts.Legacy 5 | { 6 | public static class HalibutRuntimeExtensionMethods 7 | { 8 | public static HalibutRuntimeBuilder WithLegacyContractSupport(this HalibutRuntimeBuilder builder) 9 | { 10 | return builder.WithMessageSerializer(s => s.WithLegacyContractSupport()); 11 | } 12 | } 13 | } -------------------------------------------------------------------------------- /source/Octopus.Tentacle.Contracts/Logging/ITentacleClientTaskLog.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace Octopus.Tentacle.Contracts.Logging 4 | { 5 | public interface ITentacleClientTaskLog 6 | { 7 | void Info(string message); 8 | void Verbose(string message); 9 | void Verbose(Exception exception); 10 | void Warn(string message); 11 | void Warn(Exception exception, string message); 12 | } 13 | } -------------------------------------------------------------------------------- /source/Octopus.Tentacle.Contracts/Observability/ITentacleClientObserver.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using Octopus.Tentacle.Contracts.Logging; 3 | 4 | namespace Octopus.Tentacle.Contracts.Observability 5 | { 6 | public interface ITentacleClientObserver 7 | { 8 | void RpcCallCompleted(RpcCallMetrics rpcCallMetrics, ITentacleClientTaskLog logger); 9 | void UploadFileCompleted(ClientOperationMetrics clientOperationMetrics, ITentacleClientTaskLog logger); 10 | void DownloadFileCompleted(ClientOperationMetrics clientOperationMetrics, ITentacleClientTaskLog logger); 11 | void ExecuteScriptCompleted(ClientOperationMetrics clientOperationMetrics, ITentacleClientTaskLog logger); 12 | } 13 | } -------------------------------------------------------------------------------- /source/Octopus.Tentacle.Contracts/Observability/RpcCall.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace Octopus.Tentacle.Contracts.Observability 4 | { 5 | public class RpcCall 6 | { 7 | public string Service { get; } 8 | public string Name { get; } 9 | 10 | public RpcCall(string service, string name) 11 | { 12 | Service = service; 13 | Name = name; 14 | } 15 | 16 | public override string ToString() => $"{Service}.{Name}"; 17 | 18 | public static RpcCall Create(string name) => new(typeof(T).Name, name); 19 | } 20 | } -------------------------------------------------------------------------------- /source/Octopus.Tentacle.Contracts/ScriptExitCodes.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace Octopus.Tentacle.Contracts 4 | { 5 | public static class ScriptExitCodes 6 | { 7 | public const int RunningExitCode = 0; 8 | public const int FatalExitCode = -41; 9 | public const int PowershellInvocationErrorExitCode = -42; 10 | public const int CanceledExitCode = -43; 11 | public const int TimeoutExitCode = -44; 12 | public const int UnknownScriptExitCode = -45; 13 | public const int UnknownResultExitCode = -46; 14 | 15 | //Kubernetes Agent 16 | public const int KubernetesScriptPodNotFound = -81; 17 | 18 | } 19 | } -------------------------------------------------------------------------------- /source/Octopus.Tentacle.Contracts/ScriptFile.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using Halibut; 3 | using Newtonsoft.Json; 4 | 5 | namespace Octopus.Tentacle.Contracts 6 | { 7 | public class ScriptFile 8 | { 9 | [JsonConstructor] 10 | public ScriptFile(string name, DataStream contents, string? encryptionPassword) 11 | { 12 | Name = name; 13 | Contents = contents; 14 | EncryptionPassword = encryptionPassword; 15 | } 16 | 17 | public ScriptFile(string name, DataStream contents) : this(name, contents, null) 18 | { 19 | } 20 | 21 | public string Name { get; } 22 | 23 | public DataStream Contents { get; } 24 | 25 | public string? EncryptionPassword { get; } 26 | } 27 | } -------------------------------------------------------------------------------- /source/Octopus.Tentacle.Contracts/ScriptIsolationLevel.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace Octopus.Tentacle.Contracts 4 | { 5 | public enum ScriptIsolationLevel 6 | { 7 | NoIsolation, 8 | FullIsolation 9 | } 10 | } -------------------------------------------------------------------------------- /source/Octopus.Tentacle.Contracts/ScriptServiceV2/CancelScriptCommandV2.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace Octopus.Tentacle.Contracts.ScriptServiceV2 4 | { 5 | public class CancelScriptCommandV2 6 | { 7 | public CancelScriptCommandV2(ScriptTicket ticket, long lastLogSequence) 8 | { 9 | Ticket = ticket; 10 | LastLogSequence = lastLogSequence; 11 | } 12 | 13 | public ScriptTicket Ticket { get; } 14 | 15 | public long LastLogSequence { get; } 16 | } 17 | } -------------------------------------------------------------------------------- /source/Octopus.Tentacle.Contracts/ScriptServiceV2/CompleteScriptCommandV2.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace Octopus.Tentacle.Contracts.ScriptServiceV2 4 | { 5 | public class CompleteScriptCommandV2 6 | { 7 | public CompleteScriptCommandV2(ScriptTicket ticket) 8 | { 9 | Ticket = ticket; 10 | } 11 | 12 | public ScriptTicket Ticket { get; } 13 | } 14 | } -------------------------------------------------------------------------------- /source/Octopus.Tentacle.Contracts/ScriptServiceV2/IScriptServiceV2.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace Octopus.Tentacle.Contracts.ScriptServiceV2 4 | { 5 | public interface IScriptServiceV2 6 | { 7 | ScriptStatusResponseV2 StartScript(StartScriptCommandV2 command); 8 | ScriptStatusResponseV2 GetStatus(ScriptStatusRequestV2 request); 9 | ScriptStatusResponseV2 CancelScript(CancelScriptCommandV2 command); 10 | void CompleteScript(CompleteScriptCommandV2 command); 11 | } 12 | } -------------------------------------------------------------------------------- /source/Octopus.Tentacle.Contracts/ScriptServiceV2/ScriptStatusRequestV2.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace Octopus.Tentacle.Contracts.ScriptServiceV2 4 | { 5 | public class ScriptStatusRequestV2 6 | { 7 | public ScriptStatusRequestV2(ScriptTicket ticket, long lastLogSequence) 8 | { 9 | Ticket = ticket; 10 | LastLogSequence = lastLogSequence; 11 | } 12 | 13 | public ScriptTicket Ticket { get; } 14 | 15 | public long LastLogSequence { get; } 16 | } 17 | } -------------------------------------------------------------------------------- /source/Octopus.Tentacle.Contracts/ScriptStatus.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | 3 | namespace Octopus.Tentacle.Contracts 4 | { 5 | public class ScriptStatus 6 | { 7 | public ProcessState State { get; } 8 | public int ExitCode { get; } 9 | public List Logs { get; } 10 | 11 | public ScriptStatus(ProcessState state, int exitCode, List logs) 12 | { 13 | State = state; 14 | ExitCode = exitCode; 15 | Logs = logs; 16 | } 17 | } 18 | } -------------------------------------------------------------------------------- /source/Octopus.Tentacle.Contracts/ScriptStatusRequest.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace Octopus.Tentacle.Contracts 4 | { 5 | public class ScriptStatusRequest 6 | { 7 | public ScriptStatusRequest(ScriptTicket ticket, long lastLogSequence) 8 | { 9 | Ticket = ticket; 10 | LastLogSequence = lastLogSequence; 11 | } 12 | 13 | public ScriptTicket Ticket { get; } 14 | 15 | public long LastLogSequence { get; } 16 | } 17 | } -------------------------------------------------------------------------------- /source/Octopus.Tentacle.Contracts/ScriptType.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace Octopus.Tentacle.Contracts 4 | { 5 | public enum ScriptType 6 | { 7 | PowerShell, 8 | Bash 9 | } 10 | } -------------------------------------------------------------------------------- /source/Octopus.Tentacle.Contracts/Services/Capabilities/IAsyncCapabilitiesServiceV2.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Threading; 3 | using System.Threading.Tasks; 4 | using Halibut.Transport.Caching; 5 | using Octopus.Tentacle.Contracts.Capabilities; 6 | 7 | // Don't "fix" this namespace, this is what we originally did and perhaps 8 | // what we need to keep doing. 9 | namespace Octopus.Tentacle.Services.Capabilities 10 | { 11 | public interface IAsyncCapabilitiesServiceV2 12 | { 13 | 14 | [CacheResponse(600)] 15 | Task GetCapabilitiesAsync(CancellationToken cancellationToken); 16 | } 17 | } -------------------------------------------------------------------------------- /source/Octopus.Tentacle.Contracts/Services/FileTransfer/IAsyncFileTransferService.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Threading; 3 | using System.Threading.Tasks; 4 | using Halibut; 5 | 6 | namespace Octopus.Tentacle.Contracts.Services.FileTransfer 7 | { 8 | public interface IAsyncFileTransferService 9 | { 10 | Task UploadFileAsync(string remotePath, DataStream upload, CancellationToken cancellationToken); 11 | Task DownloadFileAsync(string remotePath, CancellationToken cancellationToken); 12 | } 13 | } -------------------------------------------------------------------------------- /source/Octopus.Tentacle.Contracts/TentacleContracts.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace Octopus.Tentacle.Contracts 4 | { 5 | internal static class TentacleContracts 6 | { 7 | public static string AssemblyName => typeof(TentacleContracts).Assembly.FullName ?? throw new InvalidOperationException(); 8 | public static string Namespace => typeof(TentacleContracts).Namespace ?? throw new InvalidOperationException(); 9 | } 10 | } -------------------------------------------------------------------------------- /source/Octopus.Tentacle.Contracts/UploadResult.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace Octopus.Tentacle.Contracts 4 | { 5 | public class UploadResult 6 | { 7 | public UploadResult(string fullPath, string hash, long length) 8 | { 9 | FullPath = fullPath; 10 | Hash = hash; 11 | Length = length; 12 | } 13 | 14 | public string FullPath { get; } 15 | 16 | public string Hash { get; } 17 | 18 | public long Length { get; } 19 | } 20 | } -------------------------------------------------------------------------------- /source/Octopus.Tentacle.Core/Configuration/IHomeDirectoryProvider.cs: -------------------------------------------------------------------------------- 1 | namespace Octopus.Tentacle.Configuration 2 | { 3 | public interface IHomeDirectoryProvider 4 | { 5 | string? HomeDirectory { get; } 6 | string? ApplicationSpecificHomeDirectory { get; } 7 | } 8 | } -------------------------------------------------------------------------------- /source/Octopus.Tentacle.Core/Diagnostics/ISystemLog.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace Octopus.Tentacle.Core.Diagnostics 4 | { 5 | public interface ISystemLog : ILog, IDisposable 6 | { 7 | ISystemLog ChildContext(string[] sensitiveValues); 8 | } 9 | } -------------------------------------------------------------------------------- /source/Octopus.Tentacle.Core/Diagnostics/LogCategory.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace Octopus.Tentacle.Core.Diagnostics 4 | { 5 | public enum LogCategory 6 | { 7 | Trace = 1, 8 | Verbose = 100, 9 | Info = 200, 10 | Planned = 201, 11 | Highlight = 210, 12 | Abandoned = 220, 13 | Wait = 225, 14 | Progress = 230, 15 | Finished = 240, 16 | Warning = 300, 17 | Error = 400, 18 | Fatal = 500 19 | } 20 | } -------------------------------------------------------------------------------- /source/Octopus.Tentacle.Core/Maintenance/IRunningScriptReporter.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using Octopus.Tentacle.Contracts; 3 | 4 | namespace Octopus.Tentacle.Core.Maintenance 5 | { 6 | public interface IRunningScriptReporter 7 | { 8 | bool IsRunningScript(ScriptTicket ticket); 9 | } 10 | } -------------------------------------------------------------------------------- /source/Octopus.Tentacle.Core/Services/IServiceAttribute.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace Octopus.Tentacle.Core.Services 4 | { 5 | public interface IServiceAttribute 6 | { 7 | Type ContractType { get; } 8 | } 9 | } -------------------------------------------------------------------------------- /source/Octopus.Tentacle.Core/Services/Scripts/IRunningScript.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Threading; 3 | using System.Threading.Tasks; 4 | using Octopus.Tentacle.Contracts; 5 | using Octopus.Tentacle.Core.Services.Scripts.Logging; 6 | 7 | namespace Octopus.Tentacle.Core.Services.Scripts 8 | { 9 | public interface IRunningScript 10 | { 11 | int ExitCode { get; } 12 | ProcessState State { get; } 13 | IScriptLog ScriptLog { get; } 14 | 15 | Task Cleanup(CancellationToken cancellationToken); 16 | } 17 | } -------------------------------------------------------------------------------- /source/Octopus.Tentacle.Core/Services/Scripts/Logging/IScriptLog.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using Octopus.Tentacle.Contracts; 4 | 5 | namespace Octopus.Tentacle.Core.Services.Scripts.Logging 6 | { 7 | public interface IScriptLog 8 | { 9 | IScriptLogWriter CreateWriter(); 10 | List GetOutput(long afterSequenceNumber, out long nextSequenceNumber); 11 | } 12 | } -------------------------------------------------------------------------------- /source/Octopus.Tentacle.Core/Services/Scripts/Logging/IScriptLogWriter.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using Octopus.Tentacle.Contracts; 3 | 4 | namespace Octopus.Tentacle.Core.Services.Scripts.Logging 5 | { 6 | public interface IScriptLogWriter : IDisposable 7 | { 8 | void WriteOutput(ProcessOutputSource source, string message); 9 | void WriteOutput(ProcessOutputSource source, string message, DateTimeOffset occurred); 10 | } 11 | } -------------------------------------------------------------------------------- /source/Octopus.Tentacle.Core/Services/Scripts/ScriptTicketFactory.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Threading; 3 | using Octopus.Tentacle.Contracts; 4 | 5 | namespace Octopus.Tentacle.Core.Services.Scripts 6 | { 7 | public static class ScriptTicketFactory 8 | { 9 | static long nextTaskId; 10 | public static ScriptTicket Create(string? serverTaskId) 11 | { 12 | serverTaskId = serverTaskId?.Replace("ServerTasks-", string.Empty); 13 | return new ScriptTicket($"{DateTimeOffset.UtcNow:yyyyMMddHHmmss}-{serverTaskId}-{Interlocked.Increment(ref nextTaskId)}"); 14 | } 15 | } 16 | } -------------------------------------------------------------------------------- /source/Octopus.Tentacle.Core/Services/Scripts/Shell/IShell.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace Octopus.Tentacle.Core.Services.Scripts.Shell 4 | { 5 | public interface IShell 6 | { 7 | string Name { get; } 8 | string GetFullPath(); 9 | 10 | string FormatCommandArguments(string bootstrapFile, string[]? scriptArguments, bool allowInteractive); 11 | } 12 | } -------------------------------------------------------------------------------- /source/Octopus.Tentacle.Core/Services/Scripts/StateStore/IScriptStateStore.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using Octopus.Tentacle.Scripts; 3 | 4 | namespace Octopus.Tentacle.Core.Services.Scripts.StateStore 5 | { 6 | public interface IScriptStateStore 7 | { 8 | bool Exists(); 9 | ScriptState Create(); 10 | void Save(ScriptState state); 11 | ScriptState Load(); 12 | } 13 | } -------------------------------------------------------------------------------- /source/Octopus.Tentacle.Core/Services/Scripts/StateStore/IScriptStateStoreFactory.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using Octopus.Tentacle.Scripts; 3 | 4 | namespace Octopus.Tentacle.Core.Services.Scripts.StateStore 5 | { 6 | public interface IScriptStateStoreFactory 7 | { 8 | ScriptStateStore Create(IScriptWorkspace workspace); 9 | } 10 | } -------------------------------------------------------------------------------- /source/Octopus.Tentacle.Core/Services/Scripts/StateStore/ScriptStateStoreFactory.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using Octopus.Tentacle.Scripts; 3 | using Octopus.Tentacle.Util; 4 | 5 | namespace Octopus.Tentacle.Core.Services.Scripts.StateStore 6 | { 7 | public class ScriptStateStoreFactory : IScriptStateStoreFactory 8 | { 9 | readonly IOctopusFileSystem fileSystem; 10 | 11 | public ScriptStateStoreFactory(IOctopusFileSystem fileSystem) 12 | { 13 | this.fileSystem = fileSystem; 14 | } 15 | 16 | public ScriptStateStore Create(IScriptWorkspace workspace) 17 | { 18 | return new ScriptStateStore(workspace, fileSystem); 19 | } 20 | } 21 | } -------------------------------------------------------------------------------- /source/Octopus.Tentacle.Core/Services/ServiceAttribute.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace Octopus.Tentacle.Core.Services 4 | { 5 | [AttributeUsage(AttributeTargets.Class)] 6 | public class ServiceAttribute : Attribute, IServiceAttribute 7 | { 8 | public Type ContractType { get; } 9 | 10 | public ServiceAttribute(Type contractType) 11 | { 12 | ContractType = contractType; 13 | } 14 | } 15 | } -------------------------------------------------------------------------------- /source/Octopus.Tentacle.Core/Util/HashCalculator.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.IO; 3 | using System.Security.Cryptography; 4 | 5 | namespace Octopus.Tentacle.Util 6 | { 7 | public static class HashCalculator 8 | { 9 | public static string Hash(Stream stream) 10 | { 11 | using var hasher = SHA1.Create(); 12 | return Sanitize(hasher.ComputeHash(stream)); 13 | } 14 | 15 | static string Sanitize(byte[] hash) 16 | => BitConverter.ToString(hash).Replace("-", "").ToLowerInvariant(); 17 | } 18 | } -------------------------------------------------------------------------------- /source/Octopus.Tentacle.Core/Util/Locking/SemaphoreSlimReleaser.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Threading; 3 | 4 | namespace Octopus.Tentacle.Util 5 | { 6 | internal class SemaphoreSlimReleaser : IDisposable 7 | { 8 | private readonly SemaphoreSlim semaphore; 9 | 10 | public SemaphoreSlimReleaser(SemaphoreSlim semaphore) 11 | { 12 | this.semaphore = semaphore; 13 | } 14 | 15 | public void Dispose() 16 | { 17 | semaphore.Release(); 18 | } 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /source/Octopus.Tentacle.Core/Util/PlatformDetection.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Runtime.InteropServices; 3 | 4 | namespace Octopus.Tentacle.Util 5 | { 6 | public static class PlatformDetection 7 | { 8 | public static bool IsRunningOnNix => RuntimeInformation.IsOSPlatform(OSPlatform.Linux); 9 | public static bool IsRunningOnWindows => RuntimeInformation.IsOSPlatform(OSPlatform.Windows); 10 | public static bool IsRunningOnMac => RuntimeInformation.IsOSPlatform(OSPlatform.OSX); 11 | } 12 | } -------------------------------------------------------------------------------- /source/Octopus.Tentacle.Core/Util/ProcessIdentity.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Security.Principal; 3 | 4 | namespace Octopus.Tentacle.Util 5 | { 6 | public static class ProcessIdentity 7 | { 8 | public static string CurrentUserName => PlatformDetection.IsRunningOnWindows 9 | ? 10 | #pragma warning disable CA1416 11 | WindowsIdentity.GetCurrent().Name 12 | #pragma warning restore CA1416 13 | : 14 | Environment.UserName; 15 | } 16 | } -------------------------------------------------------------------------------- /source/Octopus.Tentacle.Kubernetes.Tests.Integration/Setup/KindConfiguration/kind-config-v1-28.yaml: -------------------------------------------------------------------------------- 1 | kind: Cluster 2 | apiVersion: kind.x-k8s.io/v1alpha4 3 | 4 | nodes: 5 | - role: control-plane 6 | image: kindest/node:v1.28.15@sha256:a7c05c7ae043a0b8c818f5a06188bc2c4098f6cb59ca7d1856df00375d839251 7 | - role: worker 8 | image: kindest/node:v1.28.15@sha256:a7c05c7ae043a0b8c818f5a06188bc2c4098f6cb59ca7d1856df00375d839251 9 | -------------------------------------------------------------------------------- /source/Octopus.Tentacle.Kubernetes.Tests.Integration/Setup/KindConfiguration/kind-config-v1-29.yaml: -------------------------------------------------------------------------------- 1 | kind: Cluster 2 | apiVersion: kind.x-k8s.io/v1alpha4 3 | 4 | nodes: 5 | - role: control-plane 6 | image: kindest/node:v1.29.12@sha256:62c0672ba99a4afd7396512848d6fc382906b8f33349ae68fb1dbfe549f70dec 7 | - role: worker 8 | image: kindest/node:v1.29.12@sha256:62c0672ba99a4afd7396512848d6fc382906b8f33349ae68fb1dbfe549f70dec 9 | -------------------------------------------------------------------------------- /source/Octopus.Tentacle.Kubernetes.Tests.Integration/Setup/KindConfiguration/kind-config-v1-30.yaml: -------------------------------------------------------------------------------- 1 | kind: Cluster 2 | apiVersion: kind.x-k8s.io/v1alpha4 3 | 4 | nodes: 5 | - role: control-plane 6 | image: kindest/node:v1.30.6@sha256:b6d08db72079ba5ae1f4a88a09025c0a904af3b52387643c285442afb05ab994 7 | - role: worker 8 | image: kindest/node:v1.30.6@sha256:b6d08db72079ba5ae1f4a88a09025c0a904af3b52387643c285442afb05ab994 9 | -------------------------------------------------------------------------------- /source/Octopus.Tentacle.Kubernetes.Tests.Integration/Setup/KindConfiguration/kind-config-v1-31.yaml: -------------------------------------------------------------------------------- 1 | kind: Cluster 2 | apiVersion: kind.x-k8s.io/v1alpha4 3 | 4 | nodes: 5 | - role: control-plane 6 | image: kindest/node:v1.31.0@sha256:25a3504b2b340954595fa7a6ed1575ef2edadf5abd83c0776a4308b64bf47c93 7 | - role: worker 8 | image: kindest/node:v1.31.0@sha256:25a3504b2b340954595fa7a6ed1575ef2edadf5abd83c0776a4308b64bf47c93 9 | -------------------------------------------------------------------------------- /source/Octopus.Tentacle.Kubernetes.Tests.Integration/Setup/Tooling/IToolDownloader.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace Octopus.Tentacle.Kubernetes.Tests.Integration.Setup.Tooling; 4 | 5 | public interface IToolDownloader 6 | { 7 | Task Download(string targetDirectory, CancellationToken cancellationToken); 8 | } -------------------------------------------------------------------------------- /source/Octopus.Tentacle.Kubernetes.Tests.Integration/Setup/docker-desktop-network-routing.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Service 3 | metadata: 4 | name: dockerhost 5 | namespace: default 6 | spec: 7 | type: ExternalName 8 | externalName: host.docker.internal -------------------------------------------------------------------------------- /source/Octopus.Tentacle.Kubernetes.Tests.Integration/Setup/linux-network-routing.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Endpoints 3 | metadata: 4 | name: dockerhost 5 | namespace: default 6 | subsets: 7 | - addresses: 8 | - ip: 172.17.0.1 # this is the gateway IP in the "bridge" docker network 9 | --- 10 | apiVersion: v1 11 | kind: Service 12 | metadata: 13 | name: dockerhost 14 | namespace: default 15 | spec: 16 | clusterIP: None -------------------------------------------------------------------------------- /source/Octopus.Tentacle.Kubernetes.Tests.Integration/Support/AssemblyExtensions.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | 3 | namespace Octopus.Tentacle.Kubernetes.Tests.Integration.Support; 4 | 5 | public static class AssemblyExtensions 6 | { 7 | public static Stream GetManifestResourceStreamFromPartialName(this Assembly assembly, string filename) 8 | { 9 | var valuesFileName = assembly.GetManifestResourceNames().Single(n => n.Contains(filename, StringComparison.OrdinalIgnoreCase)); 10 | return assembly.GetManifestResourceStream(valuesFileName)!; 11 | } 12 | } -------------------------------------------------------------------------------- /source/Octopus.Tentacle.Kubernetes.Tests.Integration/Support/kind.ps1: -------------------------------------------------------------------------------- 1 | param( 2 | [Parameter(Mandatory = $true)] 3 | [string] 4 | $ClusterName, 5 | 6 | [Parameter(Mandatory = $true)] 7 | [string] 8 | $KindConfigPath 9 | ) 10 | 11 | $allClusters = & kind get clusters 12 | 13 | # if the cluster is not already created 14 | if($allClusters -notcontains $ClusterName) { 15 | & kind create cluster --name $ClusterName --config="$KindConfigPath" --kubeconfig="$ClusterName.config" 16 | } -------------------------------------------------------------------------------- /source/Octopus.Tentacle.Kubernetes.Tests.Integration/Support/kind.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | set -o errexit 3 | 4 | kind_cluster_name="$1" 5 | kind_config_path="$2" 6 | 7 | # if the cluster is not already created 8 | if kind get clusters | ! grep -q "$kind_cluster_name"; then 9 | kind create cluster --name="$kind_cluster_name" --config="$kind_config_path" --kubeconfig="$kind_cluster_name.config" 10 | fi -------------------------------------------------------------------------------- /source/Octopus.Tentacle.Kubernetes.Tests.Integration/Usings.cs: -------------------------------------------------------------------------------- 1 | global using NUnit.Framework; 2 | global using Serilog; -------------------------------------------------------------------------------- /source/Octopus.Tentacle.Tests.Integration.Common/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Runtime.CompilerServices; 3 | 4 | [assembly: InternalsVisibleTo("Octopus.Tentacle.Tests.Integration")] 5 | [assembly: InternalsVisibleTo("Octopus.Tentacle.Kubernetes.Tests.Integration")] -------------------------------------------------------------------------------- /source/Octopus.Tentacle.Tests.Integration.Common/Logging/TestContextLogCreator.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using Halibut.Diagnostics; 3 | using Halibut.Diagnostics.LogCreators; 4 | using Halibut.Logging; 5 | 6 | namespace Octopus.Tentacle.Tests.Integration.Common.Logging; 7 | 8 | public class TestContextLogCreator : ICreateNewILog 9 | { 10 | readonly string name; 11 | readonly LogLevel logLevel; 12 | 13 | public TestContextLogCreator(string name, LogLevel logLevel) 14 | { 15 | this.name = name; 16 | this.logLevel = logLevel; 17 | } 18 | 19 | public ILog CreateNewForPrefix(string prefix) 20 | { 21 | return new TestContextConnectionLog(prefix, name, logLevel); 22 | } 23 | } -------------------------------------------------------------------------------- /source/Octopus.Tentacle.Tests.Integration/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using NUnit.Framework; 2 | 3 | [assembly: Parallelizable(ParallelScope.All)] -------------------------------------------------------------------------------- /source/Octopus.Tentacle.Tests.Integration/Startup/Packages/Acme.Service/Acme.Service.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OctopusDeploy/OctopusTentacle/ea14d2f07576b34349c2710609e562b56aa33824/source/Octopus.Tentacle.Tests.Integration/Startup/Packages/Acme.Service/Acme.Service.exe -------------------------------------------------------------------------------- /source/Octopus.Tentacle.Tests.Integration/Support/EnumerableExtensionMethods.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections; 3 | using System.Collections.Generic; 4 | 5 | namespace Octopus.Tentacle.Tests.Integration.Support 6 | { 7 | public static class EnumerableExtensionMethods 8 | { 9 | public static object[] ToArrayOfObjects(this IEnumerable enumerable) 10 | { 11 | var enumerator = enumerable.GetEnumerator(); 12 | var list = new List(); 13 | 14 | while (enumerator.MoveNext()) 15 | { 16 | list.Add(enumerator.Current); 17 | } 18 | 19 | return list.ToArray(); 20 | } 21 | } 22 | } -------------------------------------------------------------------------------- /source/Octopus.Tentacle.Tests.Integration/Support/ExtensionMethods/ServiceEndPointExtensionMethods.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using Halibut; 3 | 4 | namespace Octopus.Tentacle.Tests.Integration.Support.ExtensionMethods 5 | { 6 | public static class ServiceEndPointExtensionMethods 7 | { 8 | public static void TryAndConnectForALongTime(this ServiceEndPoint point) 9 | { 10 | point.RetryCountLimit = 1000000; 11 | point.ConnectionErrorRetryTimeout = TimeSpan.FromDays(1); 12 | point.PollingRequestQueueTimeout = TimeSpan.FromDays(1); 13 | point.TcpClientConnectTimeout = TimeSpan.FromDays(1); 14 | } 15 | } 16 | } -------------------------------------------------------------------------------- /source/Octopus.Tentacle.Tests.Integration/Support/FailureScenario.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace Octopus.Tentacle.Tests.Integration.Support 4 | { 5 | public enum FailureScenario 6 | { 7 | ConnectionFaulted, 8 | ScriptExecutionCancelled 9 | } 10 | } -------------------------------------------------------------------------------- /source/Octopus.Tentacle.Tests.Integration/Support/HalibutTimeoutsAndLimitsForTestBuilder.cs: -------------------------------------------------------------------------------- 1 | using Halibut.Diagnostics; 2 | 3 | namespace Octopus.Tentacle.Tests.Integration.Support 4 | { 5 | public class HalibutTimeoutsAndLimitsForTestBuilder 6 | { 7 | 8 | public HalibutTimeoutsAndLimits Build() 9 | { 10 | var halibutTimeoutAndLimits = HalibutTimeoutsAndLimits.RecommendedValues(); 11 | // Lets dogfood this in our tests. 12 | halibutTimeoutAndLimits.TcpNoDelay = true; 13 | halibutTimeoutAndLimits.UseAsyncListener = true; 14 | return halibutTimeoutAndLimits; 15 | } 16 | } 17 | } -------------------------------------------------------------------------------- /source/Octopus.Tentacle.Tests.Integration/Support/Logging/TestContextLogCreator.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using Halibut.Diagnostics.LogCreators; 3 | using Halibut.Logging; 4 | using ILog = Halibut.Diagnostics.ILog; 5 | 6 | namespace Octopus.Tentacle.Tests.Integration.Support.Logging 7 | { 8 | public class TestContextLogCreator : ICreateNewILog 9 | { 10 | readonly string name; 11 | readonly LogLevel logLevel; 12 | 13 | public TestContextLogCreator(string name, LogLevel logLevel) 14 | { 15 | this.name = name; 16 | this.logLevel = logLevel; 17 | } 18 | 19 | public ILog CreateNewForPrefix(string prefix) 20 | { 21 | return new TestContextConnectionLog(prefix, name, logLevel); 22 | } 23 | } 24 | } -------------------------------------------------------------------------------- /source/Octopus.Tentacle.Tests.Integration/Support/RetryHelper.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Threading.Tasks; 3 | using Polly; 4 | 5 | namespace Octopus.Tentacle.Tests.Integration.Support 6 | { 7 | public class RetryHelper 8 | { 9 | public static async Task RetryAsync(Func> command, int retryCount = 10, int retryBackoffDurationMilliseconds = 100) 10 | where TException : Exception 11 | { 12 | return await Policy 13 | .Handle() 14 | .WaitAndRetryAsync(retryCount, rc => TimeSpan.FromMilliseconds(retryBackoffDurationMilliseconds * rc)) 15 | .ExecuteAsync(command); 16 | } 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /source/Octopus.Tentacle.Tests.Integration/Support/RpcCallStage.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace Octopus.Tentacle.Tests.Integration.Support 4 | { 5 | public enum RpcCallStage 6 | { 7 | // Server is trying to connect to a Listening Tentacle or Polling Tentacle is trying to connect to Server / has not yet dequeued a pending request 8 | Connecting, 9 | // The RPC Request has been sent by Server for Listening / the pending request has been dequeued for polling by no response has been received 10 | InFlight 11 | } 12 | 13 | public enum RpcCall 14 | { 15 | FirstCall, 16 | RetryingCall 17 | } 18 | } -------------------------------------------------------------------------------- /source/Octopus.Tentacle.Tests.Integration/Support/SetupFixtures/ISetupFixture.cs: -------------------------------------------------------------------------------- 1 | using Serilog; 2 | 3 | namespace Octopus.Tentacle.Tests.Integration.Support.SetupFixtures 4 | { 5 | public interface ISetupFixture 6 | { 7 | public void OneTimeSetUp(ILogger logger); 8 | 9 | public void OneTimeTearDown(ILogger logger); 10 | } 11 | } -------------------------------------------------------------------------------- /source/Octopus.Tentacle.Tests.Integration/Support/TaskHelper.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Threading.Tasks; 3 | 4 | namespace Octopus.Tentacle.Tests.Integration.Support 5 | { 6 | public static class TaskHelper 7 | { 8 | public static Task AsTask(this T result) 9 | { 10 | return Task.FromResult(result); 11 | } 12 | } 13 | } -------------------------------------------------------------------------------- /source/Octopus.Tentacle.Tests.Integration/Support/TentacleBuilderExtensionMethods.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using Octopus.Tentacle.Maintenance; 3 | 4 | namespace Octopus.Tentacle.Tests.Integration.Support 5 | { 6 | public static class TentacleBuilderExtensionMethods 7 | { 8 | public static ITentacleBuilder WithWorkspaceCleaningSettings(this ITentacleBuilder builder, TimeSpan cleanerDelay, TimeSpan deleteWorkspacesOlderThan) 9 | { 10 | return builder 11 | .WithRunTentacleEnvironmentVariable(WorkspaceCleanerConfiguration.CleanerDelayEnvironmentVariableName, cleanerDelay) 12 | .WithRunTentacleEnvironmentVariable(WorkspaceCleanerConfiguration.DeleteWorkspacesOlderThanTimeSpanEnvironmentVariableName, deleteWorkspacesOlderThan); 13 | } 14 | } 15 | } -------------------------------------------------------------------------------- /source/Octopus.Tentacle.Tests.Integration/Support/TentacleFetchers/TentacleFetcherFactory.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using Serilog; 3 | 4 | namespace Octopus.Tentacle.Tests.Integration.Support.TentacleFetchers 5 | { 6 | public class TentacleFetcherFactory 7 | { 8 | private ITentacleFetcher GetBase(ILogger logger) 9 | { 10 | return new VersionDependentTentacleFetcher(logger); 11 | } 12 | 13 | public ITentacleFetcher Create(ILogger logger) 14 | { 15 | return new TentacleBinaryCache(GetBase(logger), logger); 16 | } 17 | } 18 | } -------------------------------------------------------------------------------- /source/Octopus.Tentacle.Tests.Integration/Support/TentacleRuntime.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.ComponentModel; 3 | 4 | namespace Octopus.Tentacle.Tests.Integration.Support 5 | { 6 | public static class DefaultTentacleRuntime 7 | { 8 | public const TentacleRuntime Value = 9 | #if NETFRAMEWORK 10 | TentacleRuntime.Framework48; 11 | #else 12 | TentacleRuntime.DotNet8; 13 | #endif 14 | } 15 | 16 | public enum TentacleRuntime 17 | { 18 | [Description(RuntimeDetection.Framework48)] 19 | Framework48, 20 | 21 | [Description(RuntimeDetection.DotNet8)] 22 | DotNet8, 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /source/Octopus.Tentacle.Tests.Integration/Support/TentacleType.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace Octopus.Tentacle.Tests.Integration.Support 4 | { 5 | public enum TentacleType 6 | { 7 | Polling, 8 | Listening 9 | } 10 | } -------------------------------------------------------------------------------- /source/Octopus.Tentacle.Tests.Integration/Support/TestAttributes/RequiresAdminOnWindowsAttribute.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using NUnit.Framework; 3 | 4 | namespace Octopus.Tentacle.Tests.Integration.Support.TestAttributes 5 | { 6 | [AttributeUsage(AttributeTargets.Method)] 7 | public class RequiresAdminOnWindowsAttribute : CategoryAttribute 8 | { } 9 | } 10 | -------------------------------------------------------------------------------- /source/Octopus.Tentacle.Tests.Integration/Support/TestAttributes/RequiresSudoOnLinuxAttribute.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using NUnit.Framework; 3 | 4 | namespace Octopus.Tentacle.Tests.Integration.Support.TestAttributes 5 | { 6 | [AttributeUsage(AttributeTargets.Method)] 7 | public class RequiresSudoOnLinuxAttribute : CategoryAttribute 8 | { } 9 | } 10 | -------------------------------------------------------------------------------- /source/Octopus.Tentacle.Tests.Integration/Support/ValuesOf.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections; 3 | 4 | namespace Octopus.Tentacle.Tests.Integration.Support 5 | { 6 | public static class ValuesOf 7 | { 8 | public static object[] CreateValues(Type sourceType) 9 | { 10 | var enumerable = ((IEnumerable) Activator.CreateInstance(sourceType)); 11 | return enumerable.ToArrayOfObjects(); 12 | } 13 | } 14 | } -------------------------------------------------------------------------------- /source/Octopus.Tentacle.Tests.Integration/Util/Builders/TestExecuteShellScriptCommandBuilder.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using Octopus.Tentacle.Client.Scripts.Models.Builders; 3 | using Octopus.Tentacle.Contracts; 4 | 5 | namespace Octopus.Tentacle.Tests.Integration.Util.Builders 6 | { 7 | public class TestExecuteShellScriptCommandBuilder : ExecuteShellScriptCommandBuilder 8 | { 9 | public TestExecuteShellScriptCommandBuilder() 10 | : base(Guid.NewGuid().ToString(), ScriptIsolationLevel.NoIsolation) 11 | { 12 | WithDurationStartScriptCanWaitForScriptToFinish(null); 13 | } 14 | } 15 | } -------------------------------------------------------------------------------- /source/Octopus.Tentacle.Tests.Integration/Util/FuncScriptObserverBackoffStrategy.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using Octopus.Tentacle.Client.Scripts; 3 | 4 | namespace Octopus.Tentacle.Tests.Integration.Util 5 | { 6 | public class FuncScriptObserverBackoffStrategy : IScriptObserverBackoffStrategy 7 | { 8 | private Func GetBackoffFunc; 9 | 10 | public FuncScriptObserverBackoffStrategy(Func getBackoffFunc) 11 | { 12 | GetBackoffFunc = getBackoffFunc; 13 | } 14 | 15 | public TimeSpan GetBackoff(int iteration) 16 | { 17 | return GetBackoffFunc(iteration); 18 | } 19 | } 20 | } -------------------------------------------------------------------------------- /source/Octopus.Tentacle.Tests.Integration/Util/ListProcessOutputExtensionMethods.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using Octopus.Tentacle.Contracts; 5 | 6 | namespace Octopus.Tentacle.Tests.Integration.Util 7 | { 8 | public static class ListProcessOutputExtensionMethods 9 | { 10 | public static string JoinLogs(this List logs) 11 | { 12 | return String.Join("\n", logs.Select(l => l.Text).ToArray()); 13 | } 14 | } 15 | } -------------------------------------------------------------------------------- /source/Octopus.Tentacle.Tests.Integration/Util/PendingRequestQueueHelpers/CancellationObservingPendingRequestQueueFactory.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using Halibut.Diagnostics; 3 | using Halibut.ServiceModel; 4 | using Octopus.Tentacle.Tests.Integration.Support; 5 | 6 | namespace Octopus.Tentacle.Tests.Integration.Util.PendingRequestQueueHelpers 7 | { 8 | public class CancellationObservingPendingRequestQueueFactory : IPendingRequestQueueFactory 9 | { 10 | public IPendingRequestQueue CreateQueue(Uri endpoint) 11 | { 12 | return new CancellationTokenObservingPendingRequestQueueDecorator(new PendingRequestQueueAsync(new HalibutTimeoutsAndLimitsForTestBuilder().Build(), new LogFactory().ForEndpoint(endpoint))); 13 | } 14 | } 15 | } -------------------------------------------------------------------------------- /source/Octopus.Tentacle.Tests.Integration/Util/Reference.cs: -------------------------------------------------------------------------------- 1 | namespace Octopus.Tentacle.Tests.Integration.Util 2 | { 3 | public class Reference 4 | { 5 | public Reference() 6 | { 7 | } 8 | 9 | public Reference(T value) 10 | { 11 | Value = value; 12 | } 13 | 14 | public T Value { get; set; } 15 | } 16 | } -------------------------------------------------------------------------------- /source/Octopus.Tentacle.Tests/App.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /source/Octopus.Tentacle.Tests/ArgsParsing.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using FluentAssertions; 3 | using NUnit.Framework; 4 | using Octopus.Tentacle.Startup; 5 | 6 | namespace Octopus.Tentacle.Tests 7 | { 8 | [TestFixture] 9 | class ArgsParsing 10 | { 11 | [Test] 12 | public void Test() 13 | { 14 | var options = OctopusProgram.ParseCommandHostArgumentsFromCommandLineArguments( 15 | new[] { "--noninteractive" }, 16 | out var console, 17 | out var noninteractive, 18 | out _); 19 | noninteractive.Should().BeTrue(); 20 | options.Should().BeEmpty(); 21 | } 22 | } 23 | } -------------------------------------------------------------------------------- /source/Octopus.Tentacle.Tests/Commands/CommandFixture.cs: -------------------------------------------------------------------------------- 1 | using NSubstitute; 2 | using NUnit.Framework; 3 | using Octopus.Tentacle.Internals.Options; 4 | using Octopus.Tentacle.Startup; 5 | 6 | namespace Octopus.Tentacle.Tests.Commands 7 | { 8 | public class CommandFixture where TCommand : ICommand 9 | { 10 | protected TCommand Command { get; set; } = default!; 11 | 12 | [SetUp] 13 | public virtual void SetUp() 14 | { 15 | } 16 | 17 | protected void Start(params string[] args) 18 | { 19 | Command.Start(args, Substitute.For(), new OptionSet()); 20 | } 21 | 22 | protected void Stop() 23 | { 24 | Command.Stop(); 25 | } 26 | } 27 | } -------------------------------------------------------------------------------- /source/Octopus.Tentacle.Tests/Configuration/Crypto/WindowsMachineKeyEncryptorFixture.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using NUnit.Framework; 3 | using Octopus.Tentacle.Configuration; 4 | using Octopus.Tentacle.Tests.Support; 5 | 6 | namespace Octopus.Tentacle.Tests.Configuration.Crypto 7 | { 8 | [TestFixture] 9 | [Support.TestAttributes.WindowsTest] 10 | public class WindowsMachineKeyEncryptorFixture 11 | { 12 | [Test] 13 | public void EncryptsAndDecrypts() 14 | { 15 | var wme = new WindowsMachineKeyEncryptor(); 16 | var encrypted = wme.Encrypt("FooBar"); 17 | var decrypted = wme.Decrypt(encrypted); 18 | Assert.AreNotEqual(encrypted, "FooBar"); 19 | Assert.AreEqual(decrypted, "FooBar"); 20 | } 21 | } 22 | } -------------------------------------------------------------------------------- /source/Octopus.Tentacle.Tests/Contracts/FileTransferFixture.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using Halibut.Transport.Protocol; 3 | using NUnit.Framework; 4 | using Octopus.Tentacle.Contracts; 5 | 6 | namespace Octopus.Tentacle.Tests.Contracts 7 | { 8 | public class FileTransferFixture 9 | { 10 | [Test] 11 | public void IFileTransferService_HasValidTypes() 12 | { 13 | // Constructing binder verifies that the interface does not have any disallowed types 14 | var binder = new RegisteredSerializationBinder(); 15 | binder.Register(typeof(IFileTransferService)); 16 | } 17 | } 18 | } -------------------------------------------------------------------------------- /source/Octopus.Tentacle.Tests/Contracts/Legacy/RecordingSerializationBinder.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using Newtonsoft.Json.Serialization; 3 | 4 | namespace Octopus.Tentacle.Tests.Communications 5 | { 6 | internal class RecordingSerializationBinder : DefaultSerializationBinder 7 | { 8 | public string? AssemblyName { get; private set; } 9 | public string TypeName { get; private set; } 10 | public override Type BindToType(string? assemblyName, string typeName) 11 | { 12 | AssemblyName = assemblyName; 13 | TypeName = typeName; 14 | return null; 15 | } 16 | } 17 | } -------------------------------------------------------------------------------- /source/Octopus.Tentacle.Tests/Contracts/ServiceFixture.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using Halibut.Transport.Protocol; 3 | using NUnit.Framework; 4 | using Octopus.Tentacle.Contracts; 5 | 6 | namespace Octopus.Tentacle.Tests.Contracts 7 | { 8 | public class ServiceFixture 9 | { 10 | [Test] 11 | public void IScriptService_HasValidTypes() 12 | { 13 | // Constructing binder verifies that the interface does not have any disallowed types 14 | var binder = new RegisteredSerializationBinder(); 15 | binder.Register(typeof(IScriptService)); 16 | } 17 | } 18 | } -------------------------------------------------------------------------------- /source/Octopus.Tentacle.Tests/DependenciesTest.cs: -------------------------------------------------------------------------------- 1 | using FluentAssertions; 2 | using NUnit.Framework; 3 | 4 | namespace Octopus.Tentacle.Tests 5 | { 6 | public class DependenciesTest 7 | { 8 | [Test] 9 | public void FluentAssertionsIsVersion7() 10 | { 11 | typeof(AssertionOptions).Assembly.GetName().Version!.Major 12 | .Should() 13 | .Be( 14 | 7, 15 | "We want to keep using the FOSS version of FluentAssertions, which changed in v8." 16 | ); 17 | } 18 | } 19 | } -------------------------------------------------------------------------------- /source/Octopus.Tentacle.Tests/Diagnostics/AbstractLogFixture.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using FluentAssertions; 3 | using NUnit.Framework; 4 | using Octopus.Tentacle.Tests.Support; 5 | 6 | namespace Octopus.Tentacle.Tests.Diagnostics 7 | { 8 | [TestFixture] 9 | public class AbstractLogFixture 10 | { 11 | [Test] 12 | public void InvalidFormatStringsDoNotResultInExceptions() 13 | { 14 | var log = new InMemoryLog(); 15 | log.InfoFormat("I'm {0} this parameter: {1}", "missing"); 16 | var text = log.GetLog(); 17 | 18 | text.Should().Contain("I'm {0} this parameter: {1}"); 19 | text.Should().Contain("missing"); 20 | text.Should().Contain("=> Index"); 21 | } 22 | } 23 | } -------------------------------------------------------------------------------- /source/Octopus.Tentacle.Tests/Kubernetes/KubernetesUtilitiesFixture.cs: -------------------------------------------------------------------------------- 1 | using FluentAssertions; 2 | using NUnit.Framework; 3 | using Octopus.Tentacle.Kubernetes; 4 | 5 | namespace Octopus.Tentacle.Tests.Kubernetes 6 | { 7 | public class KubernetesUtilitiesFixture 8 | { 9 | const ulong Megabyte = 1000 * 1000; 10 | const ulong Mebibyte = 1024 * 1024; 11 | const ulong Gibibyte = 1024 * 1024 * 1024; 12 | 13 | [TestCase("1Gi", 1 * Gibibyte)] 14 | [TestCase("10Gi", 10 * Gibibyte)] 15 | [TestCase("10Mi", 10 * Mebibyte)] 16 | [TestCase("1M", 1 * Megabyte)] 17 | public void CorrectlyParsesTotalSize(string sizeString, ulong expected) 18 | { 19 | KubernetesUtilities.GetResourceBytes(sizeString).Should().Be(expected); 20 | } 21 | } 22 | } -------------------------------------------------------------------------------- /source/Octopus.Tentacle.Tests/Octopus.Tentacle.Tests.csproj.DotSettings: -------------------------------------------------------------------------------- 1 |  2 | No -------------------------------------------------------------------------------- /source/Octopus.Tentacle.Tests/Resources/TestCertificateNoPassword.pfx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OctopusDeploy/OctopusTentacle/ea14d2f07576b34349c2710609e562b56aa33824/source/Octopus.Tentacle.Tests/Resources/TestCertificateNoPassword.pfx -------------------------------------------------------------------------------- /source/Octopus.Tentacle.Tests/Resources/TestCertificateNoPrivateKey.pfx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OctopusDeploy/OctopusTentacle/ea14d2f07576b34349c2710609e562b56aa33824/source/Octopus.Tentacle.Tests/Resources/TestCertificateNoPrivateKey.pfx -------------------------------------------------------------------------------- /source/Octopus.Tentacle.Tests/Resources/TestCertificateWithPassword.pfx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OctopusDeploy/OctopusTentacle/ea14d2f07576b34349c2710609e562b56aa33824/source/Octopus.Tentacle.Tests/Resources/TestCertificateWithPassword.pfx -------------------------------------------------------------------------------- /source/Octopus.Tentacle.Tests/Security/AesEncryptionFixture.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using NUnit.Framework; 3 | using Octopus.Tentacle.Security; 4 | 5 | namespace Octopus.Tentacle.Tests.Security 6 | { 7 | [TestFixture] 8 | public class AesEncryptionFixture 9 | { 10 | [Test] 11 | public void EncryptionIsSymmetrical() 12 | { 13 | var password = "purple-monkey-dishwasher"; 14 | var encryptor = new AesEncryption(password); 15 | var encrypted = encryptor.Encrypt("FooBar"); 16 | var decrypted = encryptor.Decrypt(encrypted); 17 | Assert.AreEqual("FooBar", decrypted); 18 | } 19 | } 20 | } -------------------------------------------------------------------------------- /source/Octopus.Tentacle.Tests/Setup.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Globalization; 3 | using System.Threading; 4 | using NUnit.Framework; 5 | 6 | namespace Octopus.Tentacle.Tests 7 | { 8 | [SetUpFixture] 9 | public class Setup 10 | { 11 | [OneTimeSetUp] 12 | public void RunBeforeAnyTests() 13 | { 14 | Thread.CurrentThread.CurrentCulture = CultureInfo.GetCultureInfo("en-AU"); 15 | CultureInfo.DefaultThreadCurrentCulture = CultureInfo.GetCultureInfo("en-AU"); 16 | } 17 | } 18 | } -------------------------------------------------------------------------------- /source/Octopus.Tentacle.Tests/Startup/Packages/Acme.Service/Acme.Service.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | A sample project containing a Windows service. 5 | en-US 6 | ACME Corporation 7 | netstandard1.0 8 | Acme.Service 9 | Acme.Service 10 | https://github.com/OctopusDeploy/Calamari/ 11 | https://github.com/OctopusDeploy/Calamari/blob/master/LICENSE.txt 12 | Acme.Service.nuspec 13 | Version=$(Version) 14 | 15 | 16 | -------------------------------------------------------------------------------- /source/Octopus.Tentacle.Tests/Startup/Packages/Acme.Service/Acme.Service.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OctopusDeploy/OctopusTentacle/ea14d2f07576b34349c2710609e562b56aa33824/source/Octopus.Tentacle.Tests/Startup/Packages/Acme.Service/Acme.Service.exe -------------------------------------------------------------------------------- /source/Octopus.Tentacle.Tests/Support/TaskHelper.cs: -------------------------------------------------------------------------------- 1 |  2 | using System; 3 | using System.Threading.Tasks; 4 | 5 | namespace Octopus.Tentacle.Tests.Support 6 | { 7 | public static class TaskHelper 8 | { 9 | public static Task AsTask(this T result) 10 | { 11 | return Task.FromResult(result); 12 | } 13 | } 14 | } -------------------------------------------------------------------------------- /source/Octopus.Tentacle.Tests/TestExecutionContext.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace Octopus.Tentacle.Tests 4 | { 5 | public static class TestExecutionContext 6 | { 7 | public static bool IsRunningInTeamCity 8 | { 9 | get 10 | { 11 | var environmentVariableValue = Environment.GetEnvironmentVariable("TEAMCITY_VERSION"); 12 | return !string.IsNullOrEmpty(environmentVariableValue); 13 | } 14 | } 15 | } 16 | } -------------------------------------------------------------------------------- /source/Octopus.Tentacle.Tests/Util/Approved/AssentRunner.PrettyPrint_AsyncException.approved.txt: -------------------------------------------------------------------------------- 1 | The method or operation is not implemented. 2 | System.NotImplementedException 3 | at Octopus.Shared.Tests.Util.ExceptionExtensionsFixture.GenerateException1 in ExceptionExtensionsFixture.cs:line 4 | at Octopus.Shared.Tests.Util.ExceptionExtensionsFixture.GenerateException in ExceptionExtensionsFixture.cs:line 5 | at Octopus.Shared.Tests.Util.ExceptionExtensionsFixture.PrettyPrint_AsyncException in ExceptionExtensionsFixture.cs:line -------------------------------------------------------------------------------- /source/Octopus.Tentacle.Tests/Util/ProcessIdentity.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace Octopus.Tentacle.Tests.Util 4 | { 5 | public static class ProcessIdentity 6 | { 7 | 8 | } 9 | } -------------------------------------------------------------------------------- /source/Octopus.Tentacle.Upgrader/GlobalSuppressions.cs: -------------------------------------------------------------------------------- 1 | // This file is used by Code Analysis to maintain SuppressMessage 2 | // attributes that are applied to this project. 3 | // Project-level suppressions either have no target or are given 4 | // a specific target and scoped to a namespace, type, member, etc. 5 | 6 | using System.Diagnostics.CodeAnalysis; 7 | 8 | [assembly: SuppressMessage("Interoperability", "CA1416:Validate platform compatibility", Justification = "Upgrader only supports Windows", Scope = "module")] 9 | -------------------------------------------------------------------------------- /source/Octopus.Tentacle.Upgrader/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Reflection; 3 | using System.Runtime.InteropServices; 4 | 5 | [assembly: AssemblyTitle("Octopus Deploy: Upgrader")] 6 | [assembly: Guid("becc59c3-a1d9-4b25-968e-93864c3a7e97")] 7 | -------------------------------------------------------------------------------- /source/Octopus.Tentacle/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Runtime.CompilerServices; 2 | 3 | [assembly: InternalsVisibleTo("Octopus.Tentacle.Tests")] 4 | [assembly: InternalsVisibleTo("Octopus.Tentacle.Tests.Integration")] 5 | [assembly: InternalsVisibleTo("DynamicProxyGenAssembly2")] 6 | [assembly: InternalsVisibleTo("Octopus.Tentacle.Kubernetes.Tests.Integration")] -------------------------------------------------------------------------------- /source/Octopus.Tentacle/Certificates/CertificatesModule.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using Autofac; 3 | 4 | namespace Octopus.Tentacle.Certificates 5 | { 6 | public class CertificatesModule: Module 7 | { 8 | protected override void Load(ContainerBuilder builder) 9 | { 10 | base.Load(builder); 11 | 12 | builder.RegisterType().As(); 13 | } 14 | } 15 | } -------------------------------------------------------------------------------- /source/Octopus.Tentacle/Commands/OptionSets/IOctopusClientInitializer.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Net; 3 | using System.Threading.Tasks; 4 | using Octopus.Client; 5 | 6 | namespace Octopus.Tentacle.Commands.OptionSets 7 | { 8 | public interface IOctopusClientInitializer 9 | { 10 | Task CreateClient(ApiEndpointOptions apiEndpointOptions, IWebProxy? overrideProxy); 11 | Task CreateClient(ApiEndpointOptions apiEndpointOptions, bool useDefaultProxy); 12 | } 13 | } -------------------------------------------------------------------------------- /source/Octopus.Tentacle/Commands/OptionSets/OctopusClientInitializerModule.cs: -------------------------------------------------------------------------------- 1 | using Autofac; 2 | 3 | namespace Octopus.Tentacle.Commands.OptionSets 4 | { 5 | public class OctopusClientInitializerModule : Module 6 | { 7 | protected override void Load(ContainerBuilder builder) 8 | { 9 | base.Load(builder); 10 | 11 | builder.RegisterType().As().SingleInstance(); 12 | } 13 | } 14 | } -------------------------------------------------------------------------------- /source/Octopus.Tentacle/Commands/PollingProxyConfigurationCommand.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using Octopus.Tentacle.Configuration; 3 | using Octopus.Tentacle.Configuration.Instances; 4 | using Octopus.Tentacle.Core.Diagnostics; 5 | using Octopus.Tentacle.Startup; 6 | 7 | namespace Octopus.Tentacle.Commands 8 | { 9 | public class PollingProxyConfigurationCommand : ProxyConfigurationCommand 10 | { 11 | public PollingProxyConfigurationCommand(Lazy proxyConfiguration, IApplicationInstanceSelector instanceSelector, ISystemLog log, ILogFileOnlyLogger logFileOnlyLogger) 12 | : base(new Lazy(() => proxyConfiguration.Value), instanceSelector, log, logFileOnlyLogger) 13 | { 14 | } 15 | } 16 | } -------------------------------------------------------------------------------- /source/Octopus.Tentacle/Communications/IAutofacServiceSource.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | 4 | namespace Octopus.Tentacle.Communications 5 | { 6 | public interface IAutofacServiceSource 7 | { 8 | IEnumerable KnownServices { get; } 9 | } 10 | } -------------------------------------------------------------------------------- /source/Octopus.Tentacle/Communications/IHalibutInitializer.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace Octopus.Tentacle.Communications 4 | { 5 | public interface IHalibutInitializer 6 | { 7 | void Start(); 8 | void Stop(); 9 | } 10 | } -------------------------------------------------------------------------------- /source/Octopus.Tentacle/Communications/IOctopusServerChecker.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Net; 3 | 4 | namespace Octopus.Tentacle.Communications 5 | { 6 | public interface IOctopusServerChecker 7 | { 8 | string CheckServerCommunicationsIsOpen(Uri serverAddress, IWebProxy? proxyOverride); 9 | } 10 | } -------------------------------------------------------------------------------- /source/Octopus.Tentacle/Communications/KnownServiceSource.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | 4 | namespace Octopus.Tentacle.Communications 5 | { 6 | public class KnownServiceSource : IAutofacServiceSource 7 | { 8 | public KnownServiceSource(params KnownService[] serviceTypes) 9 | { 10 | KnownServices = serviceTypes; 11 | } 12 | 13 | public IEnumerable KnownServices { get; } 14 | } 15 | } -------------------------------------------------------------------------------- /source/Octopus.Tentacle/Communications/UnknownServiceNameException.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace Octopus.Tentacle.Communications 4 | { 5 | public class UnknownServiceNameException : Exception 6 | { 7 | public UnknownServiceNameException(string serviceName) 8 | : base($"Error: {serviceName} has not been registered through an IAutofacServiceSource") 9 | { 10 | ServiceName = serviceName; 11 | } 12 | 13 | public string ServiceName { get; } 14 | } 15 | } -------------------------------------------------------------------------------- /source/Octopus.Tentacle/Configuration/ApplicationName.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.ComponentModel; 3 | 4 | namespace Octopus.Tentacle.Configuration 5 | { 6 | public enum ApplicationName 7 | { 8 | [Description("Tentacle")] 9 | Tentacle 10 | } 11 | } -------------------------------------------------------------------------------- /source/Octopus.Tentacle/Configuration/Crypto/ICryptoKeyNixSource.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace Octopus.Tentacle.Configuration.Crypto 4 | { 5 | public interface ICryptoKeyNixSource 6 | { 7 | (byte[] Key, byte[] IV) Load(); 8 | } 9 | } -------------------------------------------------------------------------------- /source/Octopus.Tentacle/Configuration/Crypto/IMachineKeyEncryptor.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace Octopus.Tentacle.Configuration.Crypto 4 | { 5 | public interface IMachineKeyEncryptor 6 | { 7 | string Encrypt(string raw); 8 | string Decrypt(string encrypted); 9 | } 10 | } -------------------------------------------------------------------------------- /source/Octopus.Tentacle/Configuration/EnvironmentVariableMappings/EnvironmentVariableReader.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace Octopus.Tentacle.Configuration.EnvironmentVariableMappings 4 | { 5 | public class EnvironmentVariableReader : IEnvironmentVariableReader 6 | { 7 | public string? Get(string variableName) => Environment.GetEnvironmentVariable(variableName); 8 | 9 | public TimeSpan GetOrDefault(string variableName, TimeSpan defaultValue) 10 | { 11 | var environmentVariableValue = Get(variableName); 12 | if (TimeSpan.TryParse(environmentVariableValue, out var timeSpan)) return timeSpan; 13 | 14 | return defaultValue; 15 | } 16 | } 17 | } -------------------------------------------------------------------------------- /source/Octopus.Tentacle/Configuration/EnvironmentVariableMappings/IEnvironmentVariableReader.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace Octopus.Tentacle.Configuration.EnvironmentVariableMappings 4 | { 5 | public interface IEnvironmentVariableReader 6 | { 7 | string? Get(string variableName); 8 | TimeSpan GetOrDefault(string variableName, TimeSpan defaultValue); 9 | } 10 | } -------------------------------------------------------------------------------- /source/Octopus.Tentacle/Configuration/EnvironmentVariableMappings/IMapEnvironmentValuesToConfigItems.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | 4 | namespace Octopus.Tentacle.Configuration.EnvironmentVariableMappings 5 | { 6 | public interface IMapEnvironmentValuesToConfigItems 7 | { 8 | HashSet SupportedEnvironmentVariables { get; } 9 | 10 | void SetEnvironmentValues(Dictionary variableNamesToValues); 11 | 12 | string? GetConfigurationValue(string configurationSettingName); 13 | } 14 | } -------------------------------------------------------------------------------- /source/Octopus.Tentacle/Configuration/IHomeConfiguration.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace Octopus.Tentacle.Configuration 4 | { 5 | public interface IHomeConfiguration : IHomeDirectoryProvider 6 | { 7 | void WriteTo(IWritableKeyValueStore outputStore); 8 | } 9 | 10 | public interface IWritableHomeConfiguration : IHomeConfiguration 11 | { 12 | bool SetHomeDirectory(string? homeDirectory); 13 | } 14 | } -------------------------------------------------------------------------------- /source/Octopus.Tentacle/Configuration/IKeyValueStore.cs: -------------------------------------------------------------------------------- 1 | using System.Diagnostics.CodeAnalysis; 2 | 3 | namespace Octopus.Tentacle.Configuration 4 | { 5 | public interface IKeyValueStore 6 | { 7 | string? Get(string name, ProtectionLevel protectionLevel = ProtectionLevel.None); 8 | 9 | [return: NotNullIfNotNull("defaultValue")] 10 | TData? Get(string name, TData? defaultValue = default, ProtectionLevel protectionLevel = ProtectionLevel.None); 11 | } 12 | } -------------------------------------------------------------------------------- /source/Octopus.Tentacle/Configuration/ILoggingConfiguration.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace Octopus.Tentacle.Configuration 4 | { 5 | public interface ILoggingConfiguration 6 | { 7 | string LogsDirectory { get; } 8 | } 9 | } -------------------------------------------------------------------------------- /source/Octopus.Tentacle/Configuration/IPollingProxyConfiguration.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace Octopus.Tentacle.Configuration 4 | { 5 | /// 6 | /// Tentacle settings for the proxy that is used to communicate with Octopus. 7 | /// 8 | public interface IPollingProxyConfiguration : IProxyConfiguration 9 | { } 10 | 11 | public interface IWritablePollingProxyConfiguration : IWritableProxyConfiguration 12 | { } 13 | } -------------------------------------------------------------------------------- /source/Octopus.Tentacle/Configuration/IProxyInitializer.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace Octopus.Tentacle.Configuration 4 | { 5 | public interface IProxyInitializer 6 | { 7 | void InitializeProxy(); 8 | } 9 | } -------------------------------------------------------------------------------- /source/Octopus.Tentacle/Configuration/IRegistryApplicationInstanceStore.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using Octopus.Tentacle.Configuration.Instances; 4 | 5 | namespace Octopus.Tentacle.Configuration 6 | { 7 | interface IRegistryApplicationInstanceStore 8 | { 9 | ApplicationInstanceRecord? GetInstanceFromRegistry(string instanceName); 10 | 11 | IEnumerable GetListFromRegistry(); 12 | 13 | void DeleteFromRegistry(string instanceName); 14 | } 15 | } -------------------------------------------------------------------------------- /source/Octopus.Tentacle/Configuration/IWritableKeyValueStore.cs: -------------------------------------------------------------------------------- 1 | namespace Octopus.Tentacle.Configuration 2 | { 3 | public interface IWritableKeyValueStore : IKeyValueStore 4 | { 5 | bool Set(string name, string? value, ProtectionLevel protectionLevel = ProtectionLevel.None); 6 | 7 | bool Set(string name, TData value, ProtectionLevel protectionLevel = ProtectionLevel.None); 8 | 9 | bool Remove(string name); 10 | 11 | bool Save(); 12 | } 13 | } -------------------------------------------------------------------------------- /source/Octopus.Tentacle/Configuration/Instances/ApplicationConfigurationContributionFlag.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace Octopus.Tentacle.Configuration.Instances 4 | { 5 | public static class ApplicationConfigurationContributionFlag 6 | { 7 | public const string ContributeSettingsFlag = "OCTOPUS_CONTRIBUTE_ENV_SETTINGS"; 8 | 9 | public static bool CanContributeSettings => bool.TryParse(Environment.GetEnvironmentVariable(ContributeSettingsFlag), out var contribute) && contribute; 10 | } 11 | } -------------------------------------------------------------------------------- /source/Octopus.Tentacle/Configuration/Instances/ApplicationInstanceRecord.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace Octopus.Tentacle.Configuration.Instances 4 | { 5 | public class ApplicationInstanceRecord 6 | { 7 | public ApplicationInstanceRecord(string instanceName, string configurationFilePath) 8 | { 9 | InstanceName = instanceName; 10 | ConfigurationFilePath = configurationFilePath; 11 | } 12 | 13 | public string InstanceName { get; } 14 | 15 | public string ConfigurationFilePath { get; } 16 | 17 | public static string GetDefaultInstance(ApplicationName application) => application.ToString(); 18 | } 19 | } -------------------------------------------------------------------------------- /source/Octopus.Tentacle/Configuration/Instances/IAggregatableKeyValueStore.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace Octopus.Tentacle.Configuration.Instances 4 | { 5 | public interface IAggregatableKeyValueStore 6 | { 7 | (bool foundResult, TData? value) TryGet(string name, ProtectionLevel protectionLevel = ProtectionLevel.None); 8 | } 9 | } -------------------------------------------------------------------------------- /source/Octopus.Tentacle/Configuration/Instances/IApplicationConfigurationContributor.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace Octopus.Tentacle.Configuration.Instances 4 | { 5 | /// 6 | /// Allows additional contribution of configuration to extend the configuration provided by the "primary" configuration 7 | /// 8 | public interface IApplicationConfigurationContributor 9 | { 10 | int Priority { get; } 11 | IAggregatableKeyValueStore? LoadContributedConfiguration(); 12 | } 13 | } -------------------------------------------------------------------------------- /source/Octopus.Tentacle/Configuration/Instances/IApplicationInstanceManager.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace Octopus.Tentacle.Configuration.Instances 4 | { 5 | /// 6 | /// Coordinates creation and deletion of an instance 7 | /// 8 | public interface IApplicationInstanceManager 9 | { 10 | void CreateDefaultInstance(string configurationFile, string? homeDirectory = null); 11 | void CreateInstance(string instanceName, string configurationFile, string? homeDirectory = null); 12 | void DeleteInstance(string instanceName); 13 | } 14 | } -------------------------------------------------------------------------------- /source/Octopus.Tentacle/Configuration/Instances/NullRegistryApplicationInstanceStore.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | 5 | namespace Octopus.Tentacle.Configuration.Instances 6 | { 7 | public class NullRegistryApplicationInstanceStore : IRegistryApplicationInstanceStore 8 | { 9 | public ApplicationInstanceRecord? GetInstanceFromRegistry(string instanceName) 10 | => null; 11 | 12 | public IEnumerable GetListFromRegistry() 13 | => Enumerable.Empty(); 14 | 15 | public void DeleteFromRegistry(string instanceName) 16 | { 17 | } 18 | } 19 | } -------------------------------------------------------------------------------- /source/Octopus.Tentacle/Configuration/JsonSerialization.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using Newtonsoft.Json; 3 | using Newtonsoft.Json.Converters; 4 | 5 | namespace Octopus.Tentacle.Configuration 6 | { 7 | public static class JsonSerialization 8 | { 9 | public static JsonSerializerSettings GetDefaultSerializerSettings() 10 | => new JsonSerializerSettings 11 | { 12 | Converters = new JsonConverterCollection 13 | { 14 | new StringEnumConverter() 15 | } 16 | }; 17 | } 18 | } -------------------------------------------------------------------------------- /source/Octopus.Tentacle/Configuration/LoggingConfiguration.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.IO; 3 | using Octopus.Tentacle.Diagnostics; 4 | 5 | namespace Octopus.Tentacle.Configuration 6 | { 7 | public class LoggingConfiguration : ILoggingConfiguration 8 | { 9 | readonly IHomeConfiguration home; 10 | 11 | public LoggingConfiguration(IHomeConfiguration home) 12 | { 13 | this.home = home; 14 | } 15 | 16 | public string LogsDirectory => home.HomeDirectory == null ? OctopusLogsDirectoryRenderer.LogsDirectory : Path.Combine(home.HomeDirectory, "Logs"); 17 | } 18 | } -------------------------------------------------------------------------------- /source/Octopus.Tentacle/Configuration/ProtectionLevel.cs: -------------------------------------------------------------------------------- 1 | namespace Octopus.Tentacle.Configuration 2 | { 3 | public enum ProtectionLevel 4 | { 5 | None, 6 | MachineKey, 7 | } 8 | } -------------------------------------------------------------------------------- /source/Octopus.Tentacle/Configuration/StartUpConfigFileInstanceRequest.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace Octopus.Tentacle.Configuration 4 | { 5 | public class StartUpConfigFileInstanceRequest : StartUpInstanceRequest 6 | { 7 | public StartUpConfigFileInstanceRequest(string configFile) 8 | { 9 | ConfigFile = configFile; 10 | } 11 | 12 | public string ConfigFile { get; } 13 | } 14 | } -------------------------------------------------------------------------------- /source/Octopus.Tentacle/Configuration/StartUpDynamicInstanceRequest.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace Octopus.Tentacle.Configuration 4 | { 5 | public class StartUpDynamicInstanceRequest : StartUpInstanceRequest 6 | { 7 | public StartUpDynamicInstanceRequest() 8 | { 9 | } 10 | } 11 | } -------------------------------------------------------------------------------- /source/Octopus.Tentacle/Configuration/StartUpInstanceRequest.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace Octopus.Tentacle.Configuration 4 | { 5 | public abstract class StartUpInstanceRequest 6 | { 7 | } 8 | } -------------------------------------------------------------------------------- /source/Octopus.Tentacle/Configuration/StartUpKubernetesConfigMapInstanceRequest.cs: -------------------------------------------------------------------------------- 1 | namespace Octopus.Tentacle.Configuration 2 | { 3 | public class StartUpKubernetesConfigMapInstanceRequest : StartUpRegistryInstanceRequest 4 | { 5 | public StartUpKubernetesConfigMapInstanceRequest(string instanceName) : base(instanceName) 6 | { 7 | } 8 | } 9 | } -------------------------------------------------------------------------------- /source/Octopus.Tentacle/Configuration/WindowsMachineKeyEncryptor.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Security.Cryptography; 3 | using System.Text; 4 | using Octopus.Tentacle.Configuration.Crypto; 5 | 6 | namespace Octopus.Tentacle.Configuration 7 | { 8 | public class WindowsMachineKeyEncryptor : IMachineKeyEncryptor 9 | { 10 | #pragma warning disable CA1416 11 | public string Encrypt(string raw) 12 | => Convert.ToBase64String(ProtectedData.Protect(Encoding.UTF8.GetBytes(raw), null, DataProtectionScope.LocalMachine)); 13 | 14 | public string Decrypt(string encrypted) 15 | => Encoding.UTF8.GetString(ProtectedData.Unprotect(Convert.FromBase64String(encrypted), null, DataProtectionScope.LocalMachine)); 16 | #pragma warning restore CA1416 17 | } 18 | } -------------------------------------------------------------------------------- /source/Octopus.Tentacle/Configuration/XmlSetting.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Xml.Serialization; 3 | 4 | namespace Octopus.Tentacle.Configuration 5 | { 6 | public class XmlSetting 7 | { 8 | [XmlAttribute("key")] 9 | public string Key { get; set; } = string.Empty; 10 | 11 | [XmlText] 12 | public string? Value { get; set; } 13 | } 14 | } -------------------------------------------------------------------------------- /source/Octopus.Tentacle/Configuration/XmlSettingsRoot.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Xml.Serialization; 4 | 5 | namespace Octopus.Tentacle.Configuration 6 | { 7 | [XmlRoot("octopus-settings")] 8 | public class XmlSettingsRoot 9 | { 10 | public XmlSettingsRoot() 11 | { 12 | Settings = new List(); 13 | } 14 | 15 | [XmlElement("set")] 16 | public List Settings { get; set; } 17 | } 18 | } -------------------------------------------------------------------------------- /source/Octopus.Tentacle/Diagnostics/ILogAppender.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace Octopus.Tentacle.Diagnostics 4 | { 5 | public interface ILogAppender 6 | { 7 | void WriteEvent(LogEvent logEvent); 8 | void Flush(); 9 | } 10 | } -------------------------------------------------------------------------------- /source/Octopus.Tentacle/Diagnostics/SystemLog.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Linq; 3 | using Octopus.Tentacle.Core.Diagnostics; 4 | 5 | namespace Octopus.Tentacle.Diagnostics 6 | { 7 | public class SystemLog : Log, ISystemLog 8 | { 9 | public SystemLog(string[]? sensitiveValues = null) : base(sensitiveValues) 10 | { 11 | } 12 | 13 | public ISystemLog ChildContext(string[] sensitiveValues) 14 | { 15 | // creates a child context that will mask the given values. 16 | return new SystemLog(SensitiveValueMasker.SensitiveValues.Concat(sensitiveValues).ToArray()); 17 | } 18 | 19 | public override string CorrelationId => "system/" + Environment.MachineName; 20 | } 21 | } -------------------------------------------------------------------------------- /source/Octopus.Tentacle/ExternalInit.cs: -------------------------------------------------------------------------------- 1 | namespace System.Runtime.CompilerServices 2 | { 3 | //This is needed to support `record` types in .NET 4.8 4 | internal static class IsExternalInit {} 5 | } -------------------------------------------------------------------------------- /source/Octopus.Tentacle/Internals/CertificateGeneration/KeyExchangeKey.cs: -------------------------------------------------------------------------------- 1 | #if NETFRAMEWORK 2 | using System; 3 | 4 | namespace Octopus.Tentacle.Internals.CertificateGeneration 5 | { 6 | public class KeyExchangeKey : CryptKey 7 | { 8 | internal KeyExchangeKey(CryptContext ctx, IntPtr handle) : base(ctx, handle) 9 | { 10 | } 11 | 12 | public virtual KeyType Type => KeyType.Exchange; 13 | } 14 | } 15 | #endif -------------------------------------------------------------------------------- /source/Octopus.Tentacle/Internals/CertificateGeneration/KeyType.cs: -------------------------------------------------------------------------------- 1 | #if NETFRAMEWORK 2 | using System; 3 | 4 | namespace Octopus.Tentacle.Internals.CertificateGeneration 5 | { 6 | public enum KeyType 7 | { 8 | Exchange = 1, 9 | Signature = 2 10 | } 11 | } 12 | #endif -------------------------------------------------------------------------------- /source/Octopus.Tentacle/Internals/CertificateGeneration/_Readme.txt: -------------------------------------------------------------------------------- 1 | All classes in this namespace are under the following license: 2 | -------------------------------------------------------------------- 3 | 4 | http://blog.pluralsight.com/2012/02/13/selfcert-create-a-self-signed-certificate-interactively-gui-or-programmatically-in-net/ 5 | 6 | "Download the project here, which includes binaries and sources. Feel free to use Pluralsight.Crypto in your own projects if you find it useful. Enjoy!" -------------------------------------------------------------------------------- /source/Octopus.Tentacle/Internals/Options/OptionAction.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace Octopus.Tentacle.Internals.Options 4 | { 5 | public delegate void OptionAction(TKey key, TValue value); 6 | } -------------------------------------------------------------------------------- /source/Octopus.Tentacle/Internals/Options/OptionContext.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace Octopus.Tentacle.Internals.Options 4 | { 5 | public class OptionContext 6 | { 7 | public OptionContext(OptionSet set) 8 | { 9 | OptionSet = set; 10 | OptionValues = new OptionValueCollection(this); 11 | } 12 | 13 | public Option? Option { get; set; } 14 | public string? OptionName { get; set; } 15 | public int OptionIndex { get; set; } 16 | 17 | public OptionSet OptionSet { get; } 18 | 19 | public OptionValueCollection OptionValues { get; } 20 | } 21 | } -------------------------------------------------------------------------------- /source/Octopus.Tentacle/Internals/Options/OptionValueType.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace Octopus.Tentacle.Internals.Options 4 | { 5 | public enum OptionValueType 6 | { 7 | None, 8 | Optional, 9 | Required 10 | } 11 | } -------------------------------------------------------------------------------- /source/Octopus.Tentacle/Kubernetes/ConfigMapNames.cs: -------------------------------------------------------------------------------- 1 | namespace Octopus.Tentacle.Kubernetes 2 | { 3 | public static class ConfigMapNames 4 | { 5 | public const string AgentMetrics = "kubernetes-agent-metrics"; 6 | public const string AgentMetricsConfigMapKey = "metrics"; 7 | } 8 | } -------------------------------------------------------------------------------- /source/Octopus.Tentacle/Kubernetes/IKubernetesClientConfigProvider.cs: -------------------------------------------------------------------------------- 1 | using k8s; 2 | 3 | namespace Octopus.Tentacle.Kubernetes 4 | { 5 | public interface IKubernetesClientConfigProvider 6 | { 7 | KubernetesClientConfiguration Get(); 8 | } 9 | } -------------------------------------------------------------------------------- /source/Octopus.Tentacle/Kubernetes/InClusterKubernetesClientConfigProvider.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using k8s; 3 | 4 | namespace Octopus.Tentacle.Kubernetes 5 | { 6 | class InClusterKubernetesClientConfigProvider : IKubernetesClientConfigProvider 7 | { 8 | public KubernetesClientConfiguration Get() 9 | { 10 | return KubernetesClientConfiguration.InClusterConfig(); 11 | } 12 | } 13 | } -------------------------------------------------------------------------------- /source/Octopus.Tentacle/Kubernetes/KubernetesScriptPodNameExtensions.cs: -------------------------------------------------------------------------------- 1 | using Octopus.Tentacle.Contracts; 2 | using Octopus.Tentacle.Util; 3 | 4 | namespace Octopus.Tentacle.Kubernetes 5 | { 6 | public static class KubernetesScriptPodNameExtensions 7 | { 8 | public const string OctopusScriptPodNamePrefix = "octopus-script"; 9 | public static string ToKubernetesScriptPodName(this ScriptTicket scriptTicket) => $"{OctopusScriptPodNamePrefix}-{scriptTicket.TaskId}".ToLowerInvariant().Truncate(63); 10 | } 11 | } -------------------------------------------------------------------------------- /source/Octopus.Tentacle/Kubernetes/KubernetesUtilities.cs: -------------------------------------------------------------------------------- 1 | namespace Octopus.Tentacle.Kubernetes 2 | { 3 | public static class KubernetesUtilities 4 | { 5 | public static ulong GetResourceBytes(string sizeString) 6 | { 7 | var persistentVolumeSize = new k8s.Models.ResourceQuantity(sizeString); 8 | return persistentVolumeSize.ToUInt64(); 9 | } 10 | } 11 | } -------------------------------------------------------------------------------- /source/Octopus.Tentacle/Kubernetes/OctopusLabels.cs: -------------------------------------------------------------------------------- 1 | namespace Octopus.Tentacle.Kubernetes 2 | { 3 | public static class OctopusLabels 4 | { 5 | public const string ScriptTicketId = "octopus.com/scriptTicketId"; 6 | } 7 | } -------------------------------------------------------------------------------- /source/Octopus.Tentacle/Kubernetes/Synchronisation/Internal/SemaphoreSlimReleaser.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Threading; 3 | 4 | namespace Octopus.Tentacle.Kubernetes.Synchronisation.Internal 5 | { 6 | class SemaphoreSlimReleaser : IDisposable where T : SemaphoreSlim 7 | { 8 | readonly Action onDispose; 9 | 10 | public SemaphoreSlimReleaser(T semaphoreSlim, Action onDispose) 11 | { 12 | Semaphore = semaphoreSlim; 13 | this.onDispose = onDispose; 14 | } 15 | 16 | public T Semaphore { get; } 17 | 18 | public void Dispose() 19 | { 20 | Semaphore.Release(); 21 | onDispose.Invoke(); 22 | } 23 | } 24 | } -------------------------------------------------------------------------------- /source/Octopus.Tentacle/Kubernetes/UnimplementedKubernetesClientConfigProvider.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using k8s; 3 | 4 | namespace Octopus.Tentacle.Kubernetes 5 | { 6 | class UnimplementedKubernetesConfigProvider : IKubernetesClientConfigProvider 7 | { 8 | public KubernetesClientConfiguration Get() 9 | { 10 | throw new NotImplementedException("This provider is not implemented when running outside of the Kubernetes Agent."); 11 | } 12 | } 13 | } -------------------------------------------------------------------------------- /source/Octopus.Tentacle/Maintenance/MaintenanceModule.cs: -------------------------------------------------------------------------------- 1 | using Autofac; 2 | using Octopus.Tentacle.Background; 3 | 4 | namespace Octopus.Tentacle.Maintenance 5 | { 6 | public class MaintenanceModule : Module 7 | { 8 | protected override void Load(ContainerBuilder builder) 9 | { 10 | base.Load(builder); 11 | 12 | builder.RegisterType().SingleInstance(); 13 | builder.RegisterType().SingleInstance(); 14 | builder.RegisterType().As().As().SingleInstance(); 15 | } 16 | } 17 | } -------------------------------------------------------------------------------- /source/Octopus.Tentacle/Packages/IPackageInstaller.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.IO; 3 | using Octopus.Tentacle.Core.Diagnostics; 4 | 5 | namespace Octopus.Tentacle.Packages 6 | { 7 | public interface IPackageInstaller 8 | { 9 | int Install(string packageFile, string directory, ILog log, bool suppressNestedScriptWarning); 10 | int Install(Stream packageStream, string directory, ILog log, bool suppressNestedScriptWarning); 11 | } 12 | } -------------------------------------------------------------------------------- /source/Octopus.Tentacle/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Reflection; 3 | using System.Runtime.CompilerServices; 4 | 5 | [assembly: AssemblyTitle("Octopus Deploy: Tentacle")] 6 | [assembly: InternalsVisibleTo("Octopus.Manager.Tentacle")] 7 | [assembly: InternalsVisibleTo("Octopus.Tentacle.Tests")] -------------------------------------------------------------------------------- /source/Octopus.Tentacle/Properties/Icon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OctopusDeploy/OctopusTentacle/ea14d2f07576b34349c2710609e562b56aa33824/source/Octopus.Tentacle/Properties/Icon.ico -------------------------------------------------------------------------------- /source/Octopus.Tentacle/Security/CertificateExpectations.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace Octopus.Tentacle.Security 4 | { 5 | public class CertificateExpectations 6 | { 7 | public const string TentacleCertificateName = "Octopus Tentacle"; 8 | public const string TentacleCertificateFullName = "cn=" + TentacleCertificateName; 9 | } 10 | } -------------------------------------------------------------------------------- /source/Octopus.Tentacle/Security/CertificateValidationDirection.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace Octopus.Tentacle.Security 4 | { 5 | public enum CertificateValidationDirection 6 | { 7 | TheyCalledUs, 8 | WeCalledThem 9 | } 10 | } -------------------------------------------------------------------------------- /source/Octopus.Tentacle/Services/KubernetesServiceAttribute.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using Octopus.Tentacle.Core.Services; 3 | 4 | namespace Octopus.Tentacle.Services 5 | { 6 | [AttributeUsage(AttributeTargets.Class, AllowMultiple = true)] 7 | public class KubernetesServiceAttribute : Attribute, IServiceAttribute 8 | { 9 | public KubernetesServiceAttribute(Type contractType) 10 | { 11 | ContractType = contractType; 12 | } 13 | 14 | public Type ContractType { get; } 15 | } 16 | } -------------------------------------------------------------------------------- /source/Octopus.Tentacle/Services/Scripts/IAsyncScriptService.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Threading; 3 | using System.Threading.Tasks; 4 | using Octopus.Tentacle.Contracts; 5 | 6 | namespace Octopus.Tentacle.Services.Scripts 7 | { 8 | public interface IAsyncScriptService 9 | { 10 | Task StartScriptAsync(StartScriptCommand command, CancellationToken cancellationToken); 11 | Task GetStatusAsync(ScriptStatusRequest request, CancellationToken cancellationToken); 12 | Task CancelScriptAsync(CancelScriptCommand command, CancellationToken cancellationToken); 13 | Task CompleteScriptAsync(CompleteScriptCommand command, CancellationToken cancellationToken); 14 | } 15 | } -------------------------------------------------------------------------------- /source/Octopus.Tentacle/Startup/CommandMetadata.cs: -------------------------------------------------------------------------------- 1 | #nullable disable 2 | using System; 3 | 4 | namespace Octopus.Tentacle.Startup 5 | { 6 | public class CommandMetadata 7 | { 8 | public string Name { get; set; } 9 | public string[] Aliases { get; set; } 10 | public string Description { get; set; } 11 | } 12 | } -------------------------------------------------------------------------------- /source/Octopus.Tentacle/Startup/CommandModule.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using Autofac; 3 | 4 | namespace Octopus.Tentacle.Startup 5 | { 6 | public class CommandModule : Module 7 | { 8 | protected override void Load(ContainerBuilder builder) 9 | { 10 | base.Load(builder); 11 | 12 | builder.RegisterCommand("help", "Prints this help text", "h", "?"); 13 | builder.RegisterType().As().SingleInstance(); 14 | } 15 | } 16 | } -------------------------------------------------------------------------------- /source/Octopus.Tentacle/Startup/ICommandHost.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace Octopus.Tentacle.Startup 4 | { 5 | public interface ICommandHost 6 | { 7 | void Run(Action start, Action shutdown); 8 | void Stop(Action shutdown); 9 | void OnExit(int exitCode); 10 | } 11 | } -------------------------------------------------------------------------------- /source/Octopus.Tentacle/Startup/ICommandLocator.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace Octopus.Tentacle.Startup 4 | { 5 | public interface ICommandLocator 6 | { 7 | CommandMetadata[] List(); 8 | Lazy? Find(string name); 9 | } 10 | } -------------------------------------------------------------------------------- /source/Octopus.Tentacle/Startup/ICommandOptions.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace Octopus.Tentacle.Startup 4 | { 5 | public interface ICommandOptions 6 | { 7 | void Validate(); 8 | } 9 | } -------------------------------------------------------------------------------- /source/Octopus.Tentacle/Startup/ICommandRuntime.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace Octopus.Tentacle.Startup 4 | { 5 | public interface ICommandRuntime 6 | { 7 | void WaitForUserToExit(); 8 | } 9 | } -------------------------------------------------------------------------------- /source/Octopus.Tentacle/Startup/IServiceConfigurator.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace Octopus.Tentacle.Startup 4 | { 5 | public interface IServiceConfigurator 6 | { 7 | void ConfigureServiceByInstanceName(string thisServiceName, 8 | string exePath, 9 | string instance, 10 | string serviceDescription, 11 | ServiceConfigurationState serviceConfigurationState); 12 | 13 | void ConfigureServiceByConfigPath(string thisServiceName, 14 | string exePath, 15 | string configPath, 16 | string serviceDescription, 17 | ServiceConfigurationState serviceConfigurationState); 18 | } 19 | } -------------------------------------------------------------------------------- /source/Octopus.Tentacle/Startup/ServiceConfigurationState.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace Octopus.Tentacle.Startup 4 | { 5 | public class ServiceConfigurationState 6 | { 7 | public bool Start { get; set; } 8 | public bool Stop { get; set; } 9 | public bool Restart { get; set; } 10 | public bool Reconfigure { get; set; } 11 | public bool Install { get; set; } 12 | public bool Uninstall { get; set; } 13 | public string? Username { get; set; } 14 | public string? Password { get; set; } 15 | public string? DependOn { get; set; } 16 | } 17 | } -------------------------------------------------------------------------------- /source/Octopus.Tentacle/Tentacle.Binaries.targets: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | %(RecursiveDir)%(FileName)%(Extension) 6 | PreserveNewest 7 | 8 | 9 | -------------------------------------------------------------------------------- /source/Octopus.Tentacle/Tentacle.Packages.targets: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | %(RecursiveDir)%(FileName)%(Extension) 6 | Always 7 | 8 | 9 | 10 | 11 | 12 | %(RecursiveDir)%(FileName)%(Extension) 13 | Always 14 | 15 | 16 | -------------------------------------------------------------------------------- /source/Octopus.Tentacle/Time/ExponentialBackoff.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace Octopus.Tentacle.Time 4 | { 5 | public static class ExponentialBackoff 6 | { 7 | //retryAttempt is 1 for the first retry 8 | public static int GetDuration(int retryAttempt, int maxDuration) 9 | { 10 | return (int)Math.Min(maxDuration, Math.Pow(2, retryAttempt-1)); 11 | } 12 | } 13 | } -------------------------------------------------------------------------------- /source/Octopus.Tentacle/Time/Sleep.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Threading; 3 | using Octopus.Time; 4 | 5 | namespace Octopus.Tentacle.Time 6 | { 7 | public class Sleep : ISleep 8 | { 9 | public void For(int milliseconds) 10 | { 11 | Thread.Sleep(milliseconds); 12 | } 13 | } 14 | } -------------------------------------------------------------------------------- /source/Octopus.Tentacle/Time/TimeModule.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using Autofac; 3 | using Octopus.Time; 4 | 5 | namespace Octopus.Tentacle.Time 6 | { 7 | public class TimeModule : Module 8 | { 9 | protected override void Load(ContainerBuilder builder) 10 | { 11 | base.Load(builder); 12 | 13 | builder.RegisterType().AsSelf().As().SingleInstance(); 14 | builder.RegisterType().As().SingleInstance(); 15 | } 16 | } 17 | } -------------------------------------------------------------------------------- /source/Octopus.Tentacle/Util/ExceptionExtensions.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Reflection; 3 | 4 | namespace Octopus.Tentacle.Util 5 | { 6 | public static class ExceptionExtensions 7 | { 8 | public static Exception UnpackFromContainers(this Exception error) 9 | { 10 | if (error is AggregateException aggregateException && aggregateException.InnerExceptions.Count == 1) 11 | return UnpackFromContainers(aggregateException.InnerExceptions[0]); 12 | 13 | if (error is TargetInvocationException && error.InnerException != null) 14 | return UnpackFromContainers(error.InnerException); 15 | 16 | return error; 17 | } 18 | } 19 | } -------------------------------------------------------------------------------- /source/Octopus.Tentacle/Util/KubernetesSupportDetection.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using Octopus.Tentacle.Kubernetes; 3 | 4 | namespace Octopus.Tentacle.Util 5 | { 6 | public static class KubernetesSupportDetection 7 | { 8 | /// 9 | /// Indicates if the Tentacle is running inside a Kubernetes cluster as the Kubernetes Agent. This is done by checking if the namespace environment variable is set 10 | /// 11 | public static bool IsRunningAsKubernetesAgent => !string.IsNullOrWhiteSpace(Environment.GetEnvironmentVariable(KubernetesConfig.NamespaceVariableName)); 12 | } 13 | } -------------------------------------------------------------------------------- /source/Octopus.Tentacle/Util/ObjectFormatter.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using Newtonsoft.Json; 3 | 4 | namespace Octopus.Tentacle.Util 5 | { 6 | public static class ObjectFormatter 7 | { 8 | public static string Format(object o) 9 | => JsonConvert.SerializeObject(o); 10 | } 11 | } -------------------------------------------------------------------------------- /source/Octopus.Tentacle/Util/OctopusFileSystemModule.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using Autofac; 3 | using Octopus.Tentacle.Kubernetes; 4 | 5 | namespace Octopus.Tentacle.Util 6 | { 7 | public class OctopusFileSystemModule : Module 8 | { 9 | protected override void Load(ContainerBuilder builder) 10 | { 11 | base.Load(builder); 12 | if (KubernetesSupportDetection.IsRunningAsKubernetesAgent) 13 | { 14 | builder.RegisterType().AsSelf().As(); 15 | } 16 | else 17 | { 18 | builder.RegisterType().As(); 19 | } 20 | } 21 | } 22 | } -------------------------------------------------------------------------------- /source/Octopus.Tentacle/Util/PollingSubscriptionId.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace Octopus.Tentacle.Util 4 | { 5 | public class PollingSubscriptionId 6 | { 7 | public static Uri Generate() 8 | { 9 | return new Uri("poll://" + RandomStringGenerator.Generate(20).ToLowerInvariant() + "/"); 10 | } 11 | } 12 | } -------------------------------------------------------------------------------- /source/Octopus.Tentacle/Util/ScriptsModule.cs: -------------------------------------------------------------------------------- 1 | using Autofac; 2 | using Octopus.Tentacle.Core.Services.Scripts.Locking; 3 | using Octopus.Tentacle.Scripts; 4 | 5 | namespace Octopus.Tentacle.Util 6 | { 7 | public class ScriptsModule : Module 8 | { 9 | protected override void Load(ContainerBuilder builder) 10 | { 11 | base.Load(builder); 12 | builder.RegisterType().SingleInstance(); 13 | } 14 | } 15 | } -------------------------------------------------------------------------------- /source/Octopus.Tentacle/Util/ShellModule.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using Autofac; 3 | using Octopus.Tentacle.Core.Services.Scripts.Shell; 4 | using Octopus.Tentacle.Scripts; 5 | 6 | namespace Octopus.Tentacle.Util 7 | { 8 | public class ShellModule : Module 9 | { 10 | protected override void Load(ContainerBuilder builder) 11 | { 12 | base.Load(builder); 13 | 14 | builder.RegisterType().As().SingleInstance(); 15 | 16 | if (PlatformDetection.IsRunningOnWindows) 17 | builder.RegisterType().As(); 18 | else 19 | builder.RegisterType().As(); 20 | } 21 | } 22 | } -------------------------------------------------------------------------------- /source/Octopus.Tentacle/Util/StringExtensions.cs: -------------------------------------------------------------------------------- 1 | namespace Octopus.Tentacle.Util 2 | { 3 | public static class StringExtensions 4 | { 5 | public static string Truncate(this string value, int maxLength) 6 | { 7 | if (string.IsNullOrEmpty(value)) return value; 8 | return value.Length <= maxLength ? value : value.Substring(0, maxLength); 9 | } 10 | } 11 | } -------------------------------------------------------------------------------- /source/Octopus.Tentacle/Versioning/AppVersion.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | 3 | namespace Octopus.Tentacle.Versioning 4 | { 5 | public class AppVersion 6 | { 7 | readonly SemanticVersionInfo semanticVersionInfo; 8 | 9 | public AppVersion(Assembly assembly) 10 | : this(assembly.GetSemanticVersionInfo()) 11 | { 12 | } 13 | 14 | public AppVersion(SemanticVersionInfo semanticVersionInfo) 15 | { 16 | this.semanticVersionInfo = semanticVersionInfo; 17 | } 18 | 19 | public override string ToString() 20 | { 21 | return semanticVersionInfo.NuGetVersion; 22 | } 23 | } 24 | } -------------------------------------------------------------------------------- /source/Octopus.Tentacle/Versioning/SemanticVersionInfoExtensions.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace Octopus.Tentacle.Versioning 4 | { 5 | public static class SemanticVersionInfoExtensions 6 | { 7 | public static bool IsEarlyAccessProgram(this SemanticVersionInfo semanticVersionInfo) 8 | { 9 | return semanticVersionInfo.SemanticVersion.IsPrerelease && 10 | // Exclude local dev builds 11 | semanticVersionInfo.SemanticVersion.Major != 0; 12 | } 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /source/Octopus.Tentacle/Versioning/VersioningModule.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using Autofac; 3 | using Module = Autofac.Module; 4 | 5 | namespace Octopus.Tentacle.Versioning 6 | { 7 | public class VersioningModule : Module 8 | { 9 | readonly Assembly versionedAssembly; 10 | 11 | public VersioningModule(Assembly versionedAssembly) 12 | { 13 | this.versionedAssembly = versionedAssembly; 14 | } 15 | 16 | protected override void Load(ContainerBuilder builder) 17 | { 18 | builder.Register(c => new AppVersion(versionedAssembly)); 19 | } 20 | } 21 | } -------------------------------------------------------------------------------- /source/Octopus.Tentacle/Watchdog/IWatchdog.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using Octopus.Tentacle.Configuration; 3 | 4 | namespace Octopus.Tentacle.Watchdog 5 | { 6 | public interface IWatchdog 7 | { 8 | void Delete(); 9 | void Create(string instanceNames, int interval); 10 | WatchdogConfiguration GetConfiguration(); 11 | } 12 | } -------------------------------------------------------------------------------- /source/Octopus.Tentacle/app.netcore.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /source/Solution Items/SolutionInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.InteropServices; 3 | 4 | [assembly: AssemblyDescription("Octopus Deploy is a user-friendly release automation solution for professional .NET developers.")] 5 | [assembly: AssemblyCompany("Octopus Deploy Pty. Ltd.")] 6 | [assembly: AssemblyProduct("Octopus Deploy")] 7 | [assembly: AssemblyCopyright("Copyright © Octopus Deploy Pty. Ltd. 2022")] 8 | [assembly: AssemblyCulture("")] 9 | #if DEBUG 10 | 11 | [assembly: AssemblyConfiguration("Debug")] 12 | #else 13 | [assembly: AssemblyConfiguration("Release")] 14 | #endif 15 | 16 | [assembly: ComVisible(false)] 17 | -------------------------------------------------------------------------------- /testing/.gitignore: -------------------------------------------------------------------------------- 1 | .vs 2 | .vagrant 3 | .env 4 | compatibility/docker/config.generated.json 5 | compatibility/docker/docker-compose.yml 6 | compatibility/docker/config.json -------------------------------------------------------------------------------- /testing/compatibility/docker/example.config.json: -------------------------------------------------------------------------------- 1 | { 2 | "pollingDeploymentTargets": true, 3 | "listeningDeploymentTargets": true, 4 | "pollingWorkers": true, 5 | "listeningWorkers": true, 6 | "tentacleVersions": "6.1.1531,6.2.277,6.3.417,6.3.605,latest" 7 | } 8 | -------------------------------------------------------------------------------- /testing/compatibility/docker/example.env: -------------------------------------------------------------------------------- 1 | serverUrl=http://host.docker.internal:8066 2 | serverPollingPort=10943 3 | serverApiKey=API-APIKEY01 4 | environment=Development 5 | pollingRole=polling 6 | listeningRole=listen 7 | space=Default 8 | workerPool=Default Worker Pool 9 | customPublicHostName=MyMachine.local -------------------------------------------------------------------------------- /testing/compatibility/docker/run.ps1: -------------------------------------------------------------------------------- 1 | .\generate.ps1 2 | 3 | docker-compose up --remove-orphans -------------------------------------------------------------------------------- /testing/compatibility/vagrant/Linux/example.env: -------------------------------------------------------------------------------- 1 | serverUrl=http://MyMachine:8066 2 | serverThumbprint=ABCDEF123456 3 | serverPollingPort=10943 4 | serverApiKey=API-APIKEY01 5 | environment=Development 6 | pollingRole=pollingBreadRoll 7 | listeningRole=listeningBreadRoll 8 | space=Default 9 | tentacleVersions=5.0.15,6.0.645,6.1.1531,6.2.277,6.3.417,6.3.605 10 | polling=True 11 | listening=True 12 | deploymentTargets=True 13 | workers=True 14 | workerPool=Default Worker Pool -------------------------------------------------------------------------------- /testing/compatibility/vagrant/Linux/install.ps1: -------------------------------------------------------------------------------- 1 | param ([string] $version) 2 | 3 | $path = "/opt/octopus/tentacle$version/" 4 | 5 | If(!(test-path -PathType container $path)) 6 | { 7 | apt-get install tentacle=$version 8 | cp -R "/opt/octopus/tentacle/" $path 9 | } -------------------------------------------------------------------------------- /testing/compatibility/vagrant/Windows/example.env: -------------------------------------------------------------------------------- 1 | serverUrl=http://MyMachine.local:8066 2 | serverThumbprint=ABCDEF123456 3 | serverPollingPort=10943 4 | serverApiKey=API-APIKEY01 5 | environment=Development 6 | pollingRole=pollingBreadRoll 7 | listeningRole=listeningBreadRoll 8 | space=Default 9 | 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 10 | polling=True 11 | listening=True 12 | deploymentTargets=True 13 | workers=True 14 | workerPool=Default Worker Pool -------------------------------------------------------------------------------- /testing/compatibility/vagrant/Windows/install.ps1: -------------------------------------------------------------------------------- 1 | param ([string] $version) 2 | 3 | $path = "C:\Program Files\Octopus Deploy\Tentacle$version\" 4 | 5 | If(!(test-path -PathType container $path)) 6 | { 7 | choco install octopusdeploy.tentacle --version=$version --force -y 8 | xcopy /E /I "C:\Program Files\Octopus Deploy\Tentacle\" $path 9 | } --------------------------------------------------------------------------------