Compare commits
8 commits
79b0c811c2
...
76549e997a
Author | SHA1 | Date | |
---|---|---|---|
76549e997a | |||
deab0f5484 | |||
8c5579a42c | |||
4f79f933b5 | |||
c1ceff0f94 | |||
|
e8fcdae778 | ||
|
32840cdd46 | ||
9d66a17a1b |
7 changed files with 162 additions and 39 deletions
|
@ -144,3 +144,11 @@ Or to get help for subcommands e.g.
|
||||||
provs-desktop.jar ide -h
|
provs-desktop.jar ide -h
|
||||||
provs-server.jar k3s -h
|
provs-server.jar k3s -h
|
||||||
```
|
```
|
||||||
|
## Development & mirrors
|
||||||
|
Development happens at: https://repo.prod.meissa.de/meissa/provs
|
||||||
|
|
||||||
|
Mirrors are:
|
||||||
|
* https://gitlab.com/domaindrivenarchitecture/provs (CI issues and PR)
|
||||||
|
* https://github.com/DomainDrivenArchitecture/provs
|
||||||
|
|
||||||
|
For more details about our repository model see: https://repo.prod.meissa.de/meissa/federate-your-repos
|
||||||
|
|
|
@ -0,0 +1,68 @@
|
||||||
|
|
||||||
|
## Initialization
|
||||||
|
|
||||||
|
```mermaid
|
||||||
|
sequenceDiagram
|
||||||
|
actor user
|
||||||
|
participant app as Application
|
||||||
|
participant ds as DesktopService
|
||||||
|
participant gtr as GitTrustFactory
|
||||||
|
participant pa as CliArgumentsParser
|
||||||
|
participant cr as DesktopConfigRepository
|
||||||
|
participant ut as CliUtils
|
||||||
|
participant su as ProvsWithSudo
|
||||||
|
|
||||||
|
user ->> app: main
|
||||||
|
activate app
|
||||||
|
app ->> pa: parseCommands
|
||||||
|
app ->> cr: getConfig(configFileName)
|
||||||
|
app ->> ut: createProvInstance(cmd.target)
|
||||||
|
app ->> su: ensureSudoWithoutPassword(cmd.target.remoteTarget()?.password)
|
||||||
|
app ->> ds: provisionDesktopCommand(cmd, config)
|
||||||
|
activate ds
|
||||||
|
ds ->> gtr : get("github", "gitlab")
|
||||||
|
gtr -->> ds: GitTrust
|
||||||
|
deactivate ds
|
||||||
|
deactivate app
|
||||||
|
```
|
||||||
|
|
||||||
|
## Domain
|
||||||
|
|
||||||
|
```mermaid
|
||||||
|
classDiagram
|
||||||
|
namespace configuration {
|
||||||
|
class TargetCliCommand {
|
||||||
|
val target: String,
|
||||||
|
val passwordInteractive: Boolean = false
|
||||||
|
}
|
||||||
|
class ConfigFileName {
|
||||||
|
fileName: String
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace desktop {
|
||||||
|
class DesktopCliCommand {
|
||||||
|
}
|
||||||
|
|
||||||
|
class DesktopConfig {
|
||||||
|
val ssh: SshKeyPairSource? = null,
|
||||||
|
val gpg: KeyPairSource? = null,
|
||||||
|
val gitUserName: String? = null,
|
||||||
|
val gitEmail: String? = null,
|
||||||
|
}
|
||||||
|
|
||||||
|
class DesktopType {
|
||||||
|
val name: String
|
||||||
|
}
|
||||||
|
class DesktopOnlyModule {
|
||||||
|
<<enum>>
|
||||||
|
FIREFOX, VERIFY
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
DesktopCliCommand "1" *-- "1" DesktopType: type
|
||||||
|
DesktopCliCommand "1" *-- "1" TargetCliCommand: target
|
||||||
|
DesktopCliCommand "1" *-- "1" ConfigFileName: configFile
|
||||||
|
DesktopCliCommand "1" *-- "..n" DesktopOnlyModule: onlyModules
|
||||||
|
|
||||||
|
```
|
|
@ -86,7 +86,7 @@ fun Prov.provisionIdeDesktop(onlyModules: List<String>? = null) {
|
||||||
} else if (onlyModules.contains(DesktopOnlyModule.VERIFY.name.lowercase())) {
|
} else if (onlyModules.contains(DesktopOnlyModule.VERIFY.name.lowercase())) {
|
||||||
verifyIdeSetup()
|
verifyIdeSetup()
|
||||||
} else if (onlyModules.contains(DesktopOnlyModule.FIREFOX.name.lowercase())) {
|
} else if (onlyModules.contains(DesktopOnlyModule.FIREFOX.name.lowercase())) {
|
||||||
installFirefox()
|
installPpaFirefox()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -109,7 +109,7 @@ fun Prov.provisionOfficeDesktop(onlyModules: List<String>? = null) {
|
||||||
} else if (onlyModules.contains(DesktopOnlyModule.VERIFY.name.lowercase())) {
|
} else if (onlyModules.contains(DesktopOnlyModule.VERIFY.name.lowercase())) {
|
||||||
verifyOfficeSetup()
|
verifyOfficeSetup()
|
||||||
} else if (onlyModules.contains(DesktopOnlyModule.FIREFOX.name.lowercase())) {
|
} else if (onlyModules.contains(DesktopOnlyModule.FIREFOX.name.lowercase())) {
|
||||||
installFirefox()
|
installPpaFirefox()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -140,7 +140,7 @@ fun Prov.provisionBasicDesktop(
|
||||||
provisionKeys(gpg, ssh)
|
provisionKeys(gpg, ssh)
|
||||||
provisionGit(gitUserName ?: whoami(), gitEmail, gpg?.let { gpgFingerprint(it.publicKey.plain()) })
|
provisionGit(gitUserName ?: whoami(), gitEmail, gpg?.let { gpgFingerprint(it.publicKey.plain()) })
|
||||||
|
|
||||||
installFirefox()
|
installPpaFirefox()
|
||||||
installGopass()
|
installGopass()
|
||||||
configureGopass(publicGpgKey = gpg?.publicKey)
|
configureGopass(publicGpgKey = gpg?.publicKey)
|
||||||
installGopassJsonApi()
|
installGopassJsonApi()
|
||||||
|
@ -153,6 +153,6 @@ fun Prov.provisionBasicDesktop(
|
||||||
configureBash()
|
configureBash()
|
||||||
installVirtualBoxGuestAdditions()
|
installVirtualBoxGuestAdditions()
|
||||||
} else if (onlyModules.contains(DesktopOnlyModule.FIREFOX.name.lowercase())) {
|
} else if (onlyModules.contains(DesktopOnlyModule.FIREFOX.name.lowercase())) {
|
||||||
installFirefox()
|
installPpaFirefox()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,42 +1,61 @@
|
||||||
package org.domaindrivenarchitecture.provs.desktop.infrastructure
|
package org.domaindrivenarchitecture.provs.desktop.infrastructure
|
||||||
|
|
||||||
import org.domaindrivenarchitecture.provs.framework.core.Prov
|
import org.domaindrivenarchitecture.provs.framework.core.Prov
|
||||||
import org.domaindrivenarchitecture.provs.framework.ubuntu.filesystem.base.addTextToFile
|
import org.domaindrivenarchitecture.provs.framework.core.ProvResult
|
||||||
import org.domaindrivenarchitecture.provs.framework.ubuntu.install.base.aptInstall
|
import org.domaindrivenarchitecture.provs.framework.ubuntu.filesystem.base.checkFile
|
||||||
import java.io.File
|
import org.domaindrivenarchitecture.provs.framework.ubuntu.filesystem.base.createFile
|
||||||
|
import org.domaindrivenarchitecture.provs.framework.ubuntu.install.base.aptInstallFromPpa
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Installs non-snap firefox, removing a firefox snap-installation if existing
|
* Installs ppa firefox (i.e. non-snap), removing snap-firefox if existing.
|
||||||
*/
|
*/
|
||||||
fun Prov.installFirefox() = task {
|
fun Prov.installPpaFirefox() = taskWithResult {
|
||||||
|
|
||||||
// inspired by: https://www.omgubuntu.co.uk/2022/04/how-to-install-firefox-deb-apt-ubuntu-22-04
|
// inspired by: https://wiki.ubuntuusers.de/Firefox/Installation/PPA/
|
||||||
|
|
||||||
task("remove snap firefox") {
|
val unattendeUpgradesForPpaFirefox = "/etc/apt/apt.conf.d/51unattended-upgrades-firefox"
|
||||||
if (chk("snap list | grep firefox")) {
|
|
||||||
cmd("snap remove firefox", sudo = true)
|
val preCondition = checkFile(unattendeUpgradesForPpaFirefox)
|
||||||
}
|
if (preCondition) {
|
||||||
|
return@taskWithResult ProvResult(true, out = "Firefox already installed with ppa")
|
||||||
}
|
}
|
||||||
|
|
||||||
aptInstall("software-properties-common")
|
cmd("sudo apt-get -qy remove firefox", sudo = true)
|
||||||
cmd("add-apt-repository -y ppa:mozillateam/ppa", sudo = true)
|
optional {
|
||||||
|
cmd("snap remove firefox", sudo = true)
|
||||||
|
}
|
||||||
|
|
||||||
// set prio in order to use ppa-firefox above snap
|
createFile("/etc/apt/preferences.d/mozillateam", mozillaTeamFileContent, sudo = true)
|
||||||
addTextToFile(
|
|
||||||
"\nPackage: *\n" +
|
aptInstallFromPpa("mozillateam", "ppa", "firefox")
|
||||||
"Pin: release o=LP-PPA-mozillateam\n" +
|
|
||||||
"Pin-Priority: 1001\n",
|
createFile(
|
||||||
File("/etc/apt/preferences.d/mozilla-firefox"),
|
unattendeUpgradesForPpaFirefox,
|
||||||
|
"Unattended-Upgrade::Allowed-Origins:: \"LP-PPA-mozillateam:\${distro_codename}\";\n",
|
||||||
sudo = true
|
sudo = true
|
||||||
)
|
)
|
||||||
|
|
||||||
addTextToFile(
|
|
||||||
"""Unattended-Upgrade::Allowed-Origins:: "LP-PPA-mozillateam:${'$'}{distro_codename}";""",
|
|
||||||
File("/etc/apt/preferences.d/mozilla-firefox"),
|
|
||||||
sudo = true
|
|
||||||
)
|
|
||||||
|
|
||||||
aptInstall("firefox")
|
|
||||||
cmd("apt-get upgrade -y --allow-downgrades firefox", sudo = true)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private val mozillaTeamFileContent = """
|
||||||
|
Package: *
|
||||||
|
Pin: release o=LP-PPA-mozillateam
|
||||||
|
Pin-Priority: 100
|
||||||
|
|
||||||
|
Package: firefox*
|
||||||
|
Pin: release o=LP-PPA-mozillateam
|
||||||
|
Pin-Priority: 1001
|
||||||
|
|
||||||
|
Package: firefox*
|
||||||
|
Pin: release o=Ubuntu
|
||||||
|
Pin-Priority: -1
|
||||||
|
|
||||||
|
Package: thunderbird*
|
||||||
|
Pin: release o=LP-PPA-mozillateam
|
||||||
|
Pin-Priority: 1001
|
||||||
|
|
||||||
|
Package: thunderbird*
|
||||||
|
Pin: release o=Ubuntu
|
||||||
|
Pin-Priority: -1
|
||||||
|
""".trimIndent()
|
|
@ -13,7 +13,7 @@ import org.junit.jupiter.api.AfterAll
|
||||||
import org.junit.jupiter.api.BeforeAll
|
import org.junit.jupiter.api.BeforeAll
|
||||||
import org.junit.jupiter.api.Test
|
import org.junit.jupiter.api.Test
|
||||||
|
|
||||||
internal class CliTargetCommandKtTest {
|
internal class TargetCliCommandKtTest {
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
@BeforeAll
|
@BeforeAll
|
||||||
|
|
|
@ -1,32 +1,60 @@
|
||||||
package org.domaindrivenarchitecture.provs.desktop.infrastructure
|
package org.domaindrivenarchitecture.provs.desktop.infrastructure
|
||||||
|
|
||||||
import org.domaindrivenarchitecture.provs.framework.core.remote
|
import org.domaindrivenarchitecture.provs.framework.core.remote
|
||||||
|
import org.domaindrivenarchitecture.provs.framework.ubuntu.filesystem.base.deleteFile
|
||||||
|
import org.domaindrivenarchitecture.provs.framework.ubuntu.filesystem.base.fileContainsText
|
||||||
import org.domaindrivenarchitecture.provs.framework.ubuntu.install.base.checkPackageInstalled
|
import org.domaindrivenarchitecture.provs.framework.ubuntu.install.base.checkPackageInstalled
|
||||||
|
import org.domaindrivenarchitecture.provs.framework.ubuntu.install.base.isPackageInstalled
|
||||||
import org.domaindrivenarchitecture.provs.framework.ubuntu.secret.secretSources.PromptSecretSource
|
import org.domaindrivenarchitecture.provs.framework.ubuntu.secret.secretSources.PromptSecretSource
|
||||||
import org.domaindrivenarchitecture.provs.test.defaultTestContainer
|
import org.domaindrivenarchitecture.provs.test.defaultTestContainer
|
||||||
import org.domaindrivenarchitecture.provs.test.tags.ExtensiveContainerTest
|
import org.domaindrivenarchitecture.provs.test.tags.ExtensiveContainerTest
|
||||||
|
import org.junit.jupiter.api.Assertions.assertEquals
|
||||||
import org.junit.jupiter.api.Assertions.assertTrue
|
import org.junit.jupiter.api.Assertions.assertTrue
|
||||||
import org.junit.jupiter.api.Disabled
|
import org.junit.jupiter.api.Disabled
|
||||||
import org.junit.jupiter.api.Test
|
import org.junit.jupiter.api.Test
|
||||||
|
|
||||||
internal class FirefoxKtTest {
|
internal class FirefoxKtTest {
|
||||||
|
|
||||||
// Attention: this test does not test full functionality of installFirefox, e.g. does not test
|
// Attention: this test does not test full functionality of installPpaFirefox, e.g. does not test
|
||||||
// remove snap, as this test runs against a container which does not have snap-firefox installed
|
// remove snap-firefox, as this test runs against a container, which does have neither snap nor snap-firefox installed
|
||||||
@ExtensiveContainerTest
|
@ExtensiveContainerTest
|
||||||
fun installFirefox() {
|
fun installFirefox() {
|
||||||
|
// given
|
||||||
|
val prov = defaultTestContainer()
|
||||||
|
|
||||||
// when
|
// when
|
||||||
val result = defaultTestContainer().session {
|
val result = prov.session {
|
||||||
installFirefox()
|
deleteFile("/etc/apt/apt.conf.d/51unattended-upgrades-firefox", sudo = true)
|
||||||
checkPackageInstalled("firefox")
|
deleteFile("/etc/apt/preferences.d/mozillateam", sudo = true)
|
||||||
|
installPpaFirefox()
|
||||||
}
|
}
|
||||||
|
val result2 = prov.installPpaFirefox()
|
||||||
|
|
||||||
// then
|
// then
|
||||||
assertTrue(result.success)
|
assertTrue(result.success)
|
||||||
|
assertEquals("Firefox already installed with ppa", result2.out)
|
||||||
|
|
||||||
|
assertTrue(prov.isPackageInstalled("firefox"))
|
||||||
|
assertTrue(
|
||||||
|
prov.fileContainsText(
|
||||||
|
"/etc/apt/apt.conf.d/51unattended-upgrades-firefox",
|
||||||
|
"Unattended-Upgrade::Allowed-Origins:: \"LP-PPA-mozillateam:\${distro_codename}\";\n",
|
||||||
|
sudo = true
|
||||||
|
)
|
||||||
|
)
|
||||||
|
val expectedPolicyLine = Regex("1001? https?://ppa.launchpad(?:content)?.net/mozillateam/ppa/ubuntu")
|
||||||
|
val policy = prov.cmd("apt policy firefox").out
|
||||||
|
assertTrue(
|
||||||
|
policy?.contains(expectedPolicyLine) ?: false,
|
||||||
|
"$expectedPolicyLine was not found in $policy"
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tests installing firefox on a remote machine, e.g. a virtual machine
|
||||||
|
*/
|
||||||
@Test
|
@Test
|
||||||
@Disabled("Update connection details,then enable and run manually")
|
@Disabled("Update connection details, then enable the test and run manually")
|
||||||
fun installFirefox_remotely() {
|
fun installFirefox_remotely() {
|
||||||
val host = "192.168.56.123"
|
val host = "192.168.56.123"
|
||||||
val user = "user"
|
val user = "user"
|
||||||
|
@ -39,7 +67,7 @@ internal class FirefoxKtTest {
|
||||||
/* remove for ssh authentication */
|
/* remove for ssh authentication */
|
||||||
PromptSecretSource("Remote password for user $user").secret()
|
PromptSecretSource("Remote password for user $user").secret()
|
||||||
).session {
|
).session {
|
||||||
installFirefox()
|
installPpaFirefox()
|
||||||
firefoxVersion = cmd("apt list firefox --installed").out ?: ""
|
firefoxVersion = cmd("apt list firefox --installed").out ?: ""
|
||||||
checkPackageInstalled("firefox")
|
checkPackageInstalled("firefox")
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue