diff --git a/README.md b/README.md index f917540..b6bdd0e 100644 --- a/README.md +++ b/README.md @@ -12,9 +12,6 @@ provs provides cli-based tools for Tasks can be run locally or remotely. -## Status - -under development - though we already set up a few IDEs and servers with provs. ## Try out ### Prerequisites @@ -28,8 +25,9 @@ under development - though we already set up a few IDEs and servers with provs. * Download the latest `provs-desktop.jar`,`provs-server.jar` and/or `provs-syspec.jar` from: https://gitlab.com/domaindrivenarchitecture/provs/-/releases * Preferably into `/usr/local/bin` or any other folder where executables can be found by the system * Make the jar-file executable e.g. by `chmod +x provs-desktop.jar` +* Check with `provs-desktop.jar -h` to show help information -#### Build the binaries +###### Build the binaries Instead of downloading the binaries you can build them yourself diff --git a/doc/README.md b/doc/README.md index 08199e6..24f3849 100644 --- a/doc/README.md +++ b/doc/README.md @@ -2,8 +2,6 @@ This repository holds the documentation of the provs framework. # Design principles -For usage examples it is recommended to have a look at [provs-scripts](https://gitlab.com/domaindrivenarchitecture/provs-scripts) or [provs-ubuntu-extensions](https://gitlab.com/domaindrivenarchitecture/provs-ubuntu-extensions). - ## "Implarative" Configuration management tools are usually classified as either **imperative** or **declarative**. diff --git a/src/main/kotlin/org/domaindrivenarchitecture/provs/desktop/domain/DesktopService.kt b/src/main/kotlin/org/domaindrivenarchitecture/provs/desktop/domain/DesktopService.kt index a0939a4..b7b3327 100644 --- a/src/main/kotlin/org/domaindrivenarchitecture/provs/desktop/domain/DesktopService.kt +++ b/src/main/kotlin/org/domaindrivenarchitecture/provs/desktop/domain/DesktopService.kt @@ -134,7 +134,7 @@ fun Prov.provisionOfficeDesktop() { installDeltaChat() aptInstall(OFFICE_SUITE) installZimWiki() - installNextcloudClient() + // installNextcloudClient() might not install - might need fix and working test aptInstall(COMPARE_TOOLS) // optional, as installation of these tools often fail and as they are not considered mandatory diff --git a/src/main/kotlin/org/domaindrivenarchitecture/provs/desktop/infrastructure/DevOps.kt b/src/main/kotlin/org/domaindrivenarchitecture/provs/desktop/infrastructure/DevOps.kt index cee8b10..aaf5f1b 100644 --- a/src/main/kotlin/org/domaindrivenarchitecture/provs/desktop/infrastructure/DevOps.kt +++ b/src/main/kotlin/org/domaindrivenarchitecture/provs/desktop/infrastructure/DevOps.kt @@ -15,8 +15,37 @@ fun Prov.installDevOps() = task { installTerraform() installKubectlAndTools() installYq() + installGraalVM() } +fun Prov.installGraalVM():ProvResult = task{ + val version = "21.0.2" + val tmpDir = "~/tmp" + val filename = "graalvm-community-jdk-" + val additionalPartFilename = "_linux-x64_bin" + val packedFilename = "$filename$version$additionalPartFilename.tar.gz" + val extractedFilenameHunch = "graalvm-community-openjdk-" + val installationPath = "/usr/lib/jvm/" + + if ( !chk("/usr/local/bin/native-image --version") || version != cmd("/usr/local/bin/native-image --version|awk 'NR==1 {print $2}").out?.trim() || !chk("ls -d $installationPath$extractedFilenameHunch$version*")) { + downloadFromURL( + "https://github.com/graalvm/graalvm-ce-builds/releases/download/jdk-$version/$packedFilename", + path = tmpDir, + sha256sum = "b048069aaa3a99b84f5b957b162cc181a32a4330cbc35402766363c5be76ae48" + ) + if (!chk("ls -d $installationPath")) + cmd("sudo mkdir $installationPath") + else { + ProvResult(true, out = "$installationPath just exists, mkdir not necessary.") + } + cmd("sudo tar -C $installationPath -xzf $packedFilename", tmpDir) + val graalInstPath = installationPath + (cmd("ls /usr/lib/jvm/|grep -e graalvm-community-openjdk-$version").out?.replace("\n", "")) + cmd("sudo ln -s $graalInstPath/lib/svm/bin/native-image /usr/local/bin/native-image") + cmd("/usr/local/bin/native-image --version") + } else { + ProvResult(true, out = "GraalVM $version already installed") + } +} fun Prov.installYq( version: String = "4.13.2", @@ -91,8 +120,8 @@ fun Prov.installKubectl(): ProvResult = task { downloadFromURL( "https://dl.k8s.io/release/v$kubectlVersion/bin/linux/amd64/kubectl", path = tmpDir, - // from https://dl.k8s.io/v1.23.0/bin/linux/amd64/kubectl.sha256 - sha256sum = "2d0f5ba6faa787878b642c151ccb2c3390ce4c1e6c8e2b59568b3869ba407c4f" + // from https://dl.k8s.io/v1.27.4/bin/linux/amd64/kubectl.sha256 + sha256sum = "4685bfcf732260f72fce58379e812e091557ef1dfc1bc8084226c7891dd6028f" ) cmd("sudo install -o root -g root -m 0755 kubectl /usr/local/bin/kubectl", dir = tmpDir) } @@ -158,34 +187,3 @@ fun Prov.installTerraform(): ProvResult = task { cmd("tfenv install latest:^1.4.6", sudo = true) cmd("tfenv use latest:^1.4.6", sudo = true) } - - -// -------------------------------------------- AWS credentials file ----------------------------------------------- -fun Prov.installAwsCredentials(id: String = "REPLACE_WITH_YOUR_ID", key: String = "REPLACE_WITH_YOUR_KEY"): ProvResult = - task { - val dir = "~/.aws" - - if (!checkDir(dir)) { - createDirs(dir) - createFile("~/.aws/config", awsConfig()) - createFile("~/.aws/credentials", awsCredentials(id, key)) - } else { - ProvResult(true, "aws credential folder already installed") - } - } - -fun awsConfig(): String { - return """ - [default] - region = eu-central-1 - output = json - """.trimIndent() -} - -fun awsCredentials(id: String, key: String): String { - return """ - [default] - aws_access_key_id = $id - aws_secret_access_key = $key - """.trimIndent() -} diff --git a/src/main/kotlin/org/domaindrivenarchitecture/provs/desktop/infrastructure/Gopass.kt b/src/main/kotlin/org/domaindrivenarchitecture/provs/desktop/infrastructure/Gopass.kt index 84ab597..3ba0783 100644 --- a/src/main/kotlin/org/domaindrivenarchitecture/provs/desktop/infrastructure/Gopass.kt +++ b/src/main/kotlin/org/domaindrivenarchitecture/provs/desktop/infrastructure/Gopass.kt @@ -11,9 +11,10 @@ import org.domaindrivenarchitecture.provs.framework.ubuntu.web.base.downloadFrom fun Prov.installGopass( - version: String = "1.15.5", + version: String = "1.15.13", // NOTE: when adjusting, pls also adjust checksum below and version of gopass bridge json api enforceVersion: Boolean = false, - sha256sum: String = "23ec10015c2643f22cb305859eb36d671094d463d2eb1798cc675e7bb06f4b39" + // from https://github.com/gopasspw/gopass/releases/tag/v1.15.13 + sha256sum: String = "409ed5617e64fa2c781d5e2807ba7fcd65bc383a4e110f410f90b590e51aec55" ) = taskWithResult { if (isPackageInstalled("gopass") && !enforceVersion) { diff --git a/src/main/kotlin/org/domaindrivenarchitecture/provs/desktop/infrastructure/GopassBridge.kt b/src/main/kotlin/org/domaindrivenarchitecture/provs/desktop/infrastructure/GopassBridge.kt index 00d1d68..25cb60c 100644 --- a/src/main/kotlin/org/domaindrivenarchitecture/provs/desktop/infrastructure/GopassBridge.kt +++ b/src/main/kotlin/org/domaindrivenarchitecture/provs/desktop/infrastructure/GopassBridge.kt @@ -22,10 +22,10 @@ fun Prov.downloadGopassBridge() = task { } fun Prov.installGopassJsonApi() = taskWithResult { - // see https://github.com/gopasspw/gopass-jsonapi - val sha256sum = "ec9976e39a468428ae2eb1e2e0b9ceccba7f60d66b8097e2425b0c07f4fed108" - val gopassJsonApiVersion = "1.15.5" - val requiredGopassVersion = "1.15.5" + // from https://github.com/gopasspw/gopass-jsonapi/releases/tag/v1.15.13 + val sha256sum = "3162ab558301645024325ce2e419c1d67900e1faf95dc1774a36f1ebfc76389f" + val gopassJsonApiVersion = "1.15.13" + val requiredGopassVersion = "1.15.13" val filename = "gopass-jsonapi_${gopassJsonApiVersion}_linux_amd64.deb" val downloadUrl = "-L https://github.com/gopasspw/gopass-jsonapi/releases/download/v$gopassJsonApiVersion/$filename" val downloadDir = "${userHome()}Downloads" diff --git a/src/main/kotlin/org/domaindrivenarchitecture/provs/desktop/infrastructure/PackageBundles.kt b/src/main/kotlin/org/domaindrivenarchitecture/provs/desktop/infrastructure/PackageBundles.kt index 039cb1e..7699485 100644 --- a/src/main/kotlin/org/domaindrivenarchitecture/provs/desktop/infrastructure/PackageBundles.kt +++ b/src/main/kotlin/org/domaindrivenarchitecture/provs/desktop/infrastructure/PackageBundles.kt @@ -30,7 +30,7 @@ val OPENCONNECT = "openconnect network-manager-openconnect network-manager-openc val VPNC = "vpnc network-manager-vpnc network-manager-vpnc-gnome vpnc-scripts" -val JAVA = "openjdk-8-jdk openjdk-11-jdk openjdk-17-jdk jarwrapper" +val JAVA = "openjdk-17-jdk jarwrapper" val DRAWING_TOOLS = "inkscape dia openboard graphviz" diff --git a/src/test/kotlin/org/domaindrivenarchitecture/provs/configuration/application/ProvWithSudoKtTest.kt b/src/test/kotlin/org/domaindrivenarchitecture/provs/configuration/application/ProvWithSudoKtTest.kt index 8337d66..5100050 100644 --- a/src/test/kotlin/org/domaindrivenarchitecture/provs/configuration/application/ProvWithSudoKtTest.kt +++ b/src/test/kotlin/org/domaindrivenarchitecture/provs/configuration/application/ProvWithSudoKtTest.kt @@ -24,7 +24,7 @@ class ProvWithSudoKtTest { fun test_ensureSudoWithoutPassword_local_Prov() { mockkStatic(::getPasswordToConfigureSudoWithoutPassword) - every { getPasswordToConfigureSudoWithoutPassword() } returns Secret("testuserpw") + every { getPasswordToConfigureSudoWithoutPassword() } returns Secret("testuser") // given val containerName = "prov-test-sudo-no-pw" @@ -58,7 +58,7 @@ class ProvWithSudoKtTest { // given val containerName = "prov-test-sudo-no-pw-ssh" - val password = Secret("testuserpw") + val password = Secret("testuser") val prov = Prov.newInstance( ContainerUbuntuHostProcessor( diff --git a/src/test/kotlin/org/domaindrivenarchitecture/provs/desktop/domain/DesktopServiceKtTest.kt b/src/test/kotlin/org/domaindrivenarchitecture/provs/desktop/domain/DesktopServiceKtTest.kt index 852084a..af68164 100644 --- a/src/test/kotlin/org/domaindrivenarchitecture/provs/desktop/domain/DesktopServiceKtTest.kt +++ b/src/test/kotlin/org/domaindrivenarchitecture/provs/desktop/domain/DesktopServiceKtTest.kt @@ -1,6 +1,7 @@ package org.domaindrivenarchitecture.provs.desktop.domain import io.mockk.* +import org.domaindrivenarchitecture.provs.configuration.domain.TargetCliCommand import org.domaindrivenarchitecture.provs.desktop.infrastructure.installPpaFirefox import org.domaindrivenarchitecture.provs.desktop.infrastructure.verifyIdeSetup import org.domaindrivenarchitecture.provs.desktop.infrastructure.verifyOfficeSetup @@ -37,10 +38,8 @@ internal class DesktopServiceKtTest { // when Assertions.assertThrows(Exception::class.java) { - prov.provisionDesktop( - DesktopType.BASIC, - gitUserName = "testuser", - gitEmail = "testuser@test.org", + prov.provisionDesktopCommand( + DesktopCliCommand(DesktopType.BASIC, TargetCliCommand("testuser@somehost"), null), DesktopConfig() // dummy data ) } } diff --git a/src/test/kotlin/org/domaindrivenarchitecture/provs/desktop/infrastructure/DevOpsKtTest.kt b/src/test/kotlin/org/domaindrivenarchitecture/provs/desktop/infrastructure/DevOpsKtTest.kt index b18acfe..8248ea5 100644 --- a/src/test/kotlin/org/domaindrivenarchitecture/provs/desktop/infrastructure/DevOpsKtTest.kt +++ b/src/test/kotlin/org/domaindrivenarchitecture/provs/desktop/infrastructure/DevOpsKtTest.kt @@ -1,10 +1,7 @@ package org.domaindrivenarchitecture.provs.desktop.infrastructure import org.domaindrivenarchitecture.provs.framework.core.getResourceAsText -import org.domaindrivenarchitecture.provs.framework.ubuntu.filesystem.base.checkFile -import org.domaindrivenarchitecture.provs.framework.ubuntu.filesystem.base.createDir -import org.domaindrivenarchitecture.provs.framework.ubuntu.filesystem.base.createDirs -import org.domaindrivenarchitecture.provs.framework.ubuntu.filesystem.base.fileContainsText +import org.domaindrivenarchitecture.provs.framework.ubuntu.filesystem.base.* import org.domaindrivenarchitecture.provs.test.defaultTestContainer import org.domaindrivenarchitecture.provs.test.tags.ContainerTest import org.domaindrivenarchitecture.provs.test.tags.ExtensiveContainerTest @@ -62,4 +59,17 @@ internal class DevOpsKtTest { assertTrue(res.success) assertTrue(prov.checkFile("/usr/local/bin/kubeconform")) } + + @ContainerTest + fun installGraalVM() { + // given + val prov = defaultTestContainer() + + // when + val res = prov.installGraalVM() + + // then + assertTrue(res.success) + assertTrue(prov.checkFile("/usr/local/bin/native-image")) + } } diff --git a/src/test/kotlin/org/domaindrivenarchitecture/provs/desktop/infrastructure/GopassKtTest.kt b/src/test/kotlin/org/domaindrivenarchitecture/provs/desktop/infrastructure/GopassKtTest.kt index f192823..f1c35fb 100644 --- a/src/test/kotlin/org/domaindrivenarchitecture/provs/desktop/infrastructure/GopassKtTest.kt +++ b/src/test/kotlin/org/domaindrivenarchitecture/provs/desktop/infrastructure/GopassKtTest.kt @@ -1,17 +1,21 @@ package org.domaindrivenarchitecture.provs.desktop.infrastructure +import org.domaindrivenarchitecture.provs.framework.core.Secret import org.domaindrivenarchitecture.provs.framework.core.remote import org.domaindrivenarchitecture.provs.test.defaultTestContainer import org.domaindrivenarchitecture.provs.test.tags.ContainerTest import org.domaindrivenarchitecture.provs.framework.ubuntu.keys.KeyPair import org.domaindrivenarchitecture.provs.framework.ubuntu.keys.base.configureGpgKeys import org.domaindrivenarchitecture.provs.framework.ubuntu.keys.base.gpgFingerprint -import org.domaindrivenarchitecture.provs.framework.ubuntu.secret.secretSources.GopassSecretSource import org.junit.jupiter.api.Assertions.assertTrue import org.junit.jupiter.api.Disabled import org.junit.jupiter.api.Test import org.domaindrivenarchitecture.provs.framework.ubuntu.filesystem.base.* +import org.domaindrivenarchitecture.provs.framework.ubuntu.keys.privateGPGSnakeoilKey +import org.domaindrivenarchitecture.provs.framework.ubuntu.secret.secretSources.PromptSecretSource +import org.domaindrivenarchitecture.provs.framework.ubuntu.user.base.makeCurrentUserSudoerWithoutPasswordRequired import org.domaindrivenarchitecture.provs.test.tags.ExtensiveContainerTest +import org.domaindrivenarchitecture.provs.test_keys.publicGPGSnakeoilKey import org.junit.jupiter.api.Assertions.assertFalse @@ -56,24 +60,32 @@ internal class GopassKtTest { } @Test - @Disabled // Integrationtest; change user, host and keys, then remove this line to run this test + @Disabled // This is an integration test, which needs preparation: + // Pls change user, host and remote connection (choose connection either by password or by ssh key) + // then remove tag @Disabled to be able to run this test. + // PREREQUISITE: remote machine needs openssh-server installed fun test_install_and_configure_Gopass_and_GopassBridgeJsonApi() { - // settings to change - val host = "192.168.56.135" + // host and user + val host = "192.168.56.154" val user = "xxx" - val pubKey = GopassSecretSource("path-to/pub.key").secret() - val privateKey = GopassSecretSource("path-to/priv.key").secret() - // given - val prov = remote(host, user) + // connection by password + val pw = PromptSecretSource("Pw for $user").secret() + val prov = remote(host, user, pw) + prov.makeCurrentUserSudoerWithoutPasswordRequired(pw) // may be commented out if user can already sudo without password + + // or alternatively use connection by ssh key if the public key is already available remotely + // val prov = remote(host, user) + + + val pubKey = Secret(publicGPGSnakeoilKey()) + val privateKey = Secret(privateGPGSnakeoilKey()) + // when val res = prov.task { configureGpgKeys( - KeyPair( - pubKey, - privateKey - ), + KeyPair(pubKey, privateKey), trust = true, skipIfExistin = true ) diff --git a/src/test/kotlin/org/domaindrivenarchitecture/provs/desktop/infrastructure/NextcloudClientTest.kt b/src/test/kotlin/org/domaindrivenarchitecture/provs/desktop/infrastructure/NextcloudClientTest.kt index f93358d..b3133e4 100644 --- a/src/test/kotlin/org/domaindrivenarchitecture/provs/desktop/infrastructure/NextcloudClientTest.kt +++ b/src/test/kotlin/org/domaindrivenarchitecture/provs/desktop/infrastructure/NextcloudClientTest.kt @@ -3,8 +3,10 @@ package org.domaindrivenarchitecture.provs.desktop.infrastructure import org.domaindrivenarchitecture.provs.test.defaultTestContainer import org.domaindrivenarchitecture.provs.test.tags.ExtensiveContainerTest import org.junit.jupiter.api.Assertions.assertTrue +import org.junit.jupiter.api.Disabled internal class NextcloudClientTest { + @Disabled // test is hanging sometimes @ExtensiveContainerTest fun test_installNextcloudClient() { // when diff --git a/src/test/kotlin/org/domaindrivenarchitecture/provs/framework/core/processors/ContainerUbuntuHostProcessorTest.kt b/src/test/kotlin/org/domaindrivenarchitecture/provs/framework/core/processors/ContainerUbuntuHostProcessorTest.kt index c813c34..81568f9 100644 --- a/src/test/kotlin/org/domaindrivenarchitecture/provs/framework/core/processors/ContainerUbuntuHostProcessorTest.kt +++ b/src/test/kotlin/org/domaindrivenarchitecture/provs/framework/core/processors/ContainerUbuntuHostProcessorTest.kt @@ -34,7 +34,7 @@ class ContainerUbuntuHostProcessorTest { // given val containerName = "prov-test-ssh-with-container" - val password = Secret("testuserpw") + val password = Secret("testuser") val prov = Prov.newInstance( ContainerUbuntuHostProcessor( @@ -57,8 +57,8 @@ class ContainerUbuntuHostProcessorTest { val remoteProvBySsh = remote(ipOfContainer, "testuser", password) // when - val firstSessionResult = remoteProvBySsh.cmd("echo 1") - val secondSessionResult = remoteProvBySsh.cmd("echo 1") + val firstSessionResult = remoteProvBySsh.cmd("echo 1") // connect (to container) by ssh via ip + val secondSessionResult = remoteProvBySsh.cmd("echo 2") // second connect after first connection has been closed // then assertTrue(firstSessionResult.success)