fix configureVenv for idempotence, add createSymlink
This commit is contained in:
parent
876836f6a3
commit
a881310f48
5 changed files with 123 additions and 21 deletions
|
@ -2,7 +2,9 @@ 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.core.ProvResult
|
import org.domaindrivenarchitecture.provs.framework.core.ProvResult
|
||||||
|
import org.domaindrivenarchitecture.provs.framework.ubuntu.filesystem.base.createSymlink
|
||||||
import org.domaindrivenarchitecture.provs.framework.ubuntu.install.base.aptInstall
|
import org.domaindrivenarchitecture.provs.framework.ubuntu.install.base.aptInstall
|
||||||
|
import java.io.File
|
||||||
|
|
||||||
|
|
||||||
fun Prov.provisionPython() = task {
|
fun Prov.provisionPython() = task {
|
||||||
|
@ -21,7 +23,7 @@ fun Prov.configureVenv(): ProvResult = task {
|
||||||
val venvHome = "~/.venv/meissa"
|
val venvHome = "~/.venv/meissa"
|
||||||
cmd("python3 -m venv " + venvHome)
|
cmd("python3 -m venv " + venvHome)
|
||||||
cmd("source " + venvHome + "/bin/activate")
|
cmd("source " + venvHome + "/bin/activate")
|
||||||
cmd("ln -s " + venvHome + "/bin/activate ~/.bashrc.d/venv.sh")
|
createSymlink(File(venvHome + "/bin/activate"), File("~/.bashrc.d/venv.sh"))
|
||||||
cmd("pip3 install pip --upgrade")
|
cmd("pip3 install pip --upgrade")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -94,10 +94,9 @@ fun Prov.createFile(
|
||||||
val maxBlockSize = 50000
|
val maxBlockSize = 50000
|
||||||
val withSudo = if (sudo) "sudo " else ""
|
val withSudo = if (sudo) "sudo " else ""
|
||||||
val file = File(fullyQualifiedFilename)
|
val file = File(fullyQualifiedFilename)
|
||||||
val dir = file.parent?.toString()
|
|
||||||
|
|
||||||
if (dir != null && dir != "" && createDirIfMissing && !checkDir(dir, sudo = sudo)) {
|
if (createDirIfMissing) {
|
||||||
createDirs(dir, sudo = sudo)
|
createParentDir(file, sudo)
|
||||||
}
|
}
|
||||||
|
|
||||||
posixFilePermission?.let {
|
posixFilePermission?.let {
|
||||||
|
@ -336,6 +335,29 @@ fun Prov.deleteDir(dir: String, path: String, sudo: Boolean = false): ProvResult
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// ============================= link operations ==========================
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates and validates a symlink.
|
||||||
|
*/
|
||||||
|
fun Prov.createSymlink(
|
||||||
|
source: File,
|
||||||
|
target: File,
|
||||||
|
sudo: Boolean = false,
|
||||||
|
overwriteIfExisting: Boolean = true,
|
||||||
|
createTargetDirIfMissing: Boolean = true,
|
||||||
|
): ProvResult = task {
|
||||||
|
if (createTargetDirIfMissing) {
|
||||||
|
createParentDir(target, sudo)
|
||||||
|
}
|
||||||
|
val overwriteFlag = if (overwriteIfExisting) "f" else ""
|
||||||
|
cmd("ln -s$overwriteFlag $source $target", sudo = sudo)
|
||||||
|
// ensure link works
|
||||||
|
taskWithResult("validate link") {
|
||||||
|
ProvResult(checkFile(target.toString(), sudo = sudo))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// --------------------- various functions ----------------------
|
// --------------------- various functions ----------------------
|
||||||
fun Prov.userHome(): String {
|
fun Prov.userHome(): String {
|
||||||
val user = cmd("whoami").out?.trim()
|
val user = cmd("whoami").out?.trim()
|
||||||
|
@ -351,6 +373,17 @@ fun Prov.userHome(): String {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates the parent-dir (parent path) of the specified file if parent-dir id not yet existing
|
||||||
|
*/
|
||||||
|
internal fun Prov.createParentDir(file: File, sudo: Boolean = false) = task {
|
||||||
|
val dir = file.parent?.toString()
|
||||||
|
|
||||||
|
if (dir != null && dir != "" && !checkDir(dir, sudo = sudo)) {
|
||||||
|
createDirs(dir, sudo = sudo)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns number of bytes of a file or null if size could not be determined
|
* Returns number of bytes of a file or null if size could not be determined
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -7,11 +7,9 @@ import org.domaindrivenarchitecture.provs.test.defaultTestContainer
|
||||||
import org.domaindrivenarchitecture.provs.test.tags.ContainerTest
|
import org.domaindrivenarchitecture.provs.test.tags.ContainerTest
|
||||||
import org.junit.jupiter.api.Assertions.assertEquals
|
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.Test
|
|
||||||
|
|
||||||
internal class BashKtTest {
|
internal class BashKtTest {
|
||||||
|
|
||||||
@Test
|
|
||||||
@ContainerTest
|
@ContainerTest
|
||||||
fun configureBashForUser() {
|
fun configureBashForUser() {
|
||||||
// when
|
// when
|
||||||
|
|
|
@ -7,7 +7,7 @@ import org.junit.jupiter.api.Assertions.assertTrue
|
||||||
internal class PythonKtTest {
|
internal class PythonKtTest {
|
||||||
|
|
||||||
@ExtensiveContainerTest
|
@ExtensiveContainerTest
|
||||||
fun installPython() {
|
fun test_provisionPython() {
|
||||||
// when
|
// when
|
||||||
val res = defaultTestContainer().provisionPython()
|
val res = defaultTestContainer().provisionPython()
|
||||||
|
|
||||||
|
|
|
@ -33,7 +33,6 @@ internal class FilesystemKtTest {
|
||||||
assertEquals(testtext, textFromFile)
|
assertEquals(testtext, textFromFile)
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
|
||||||
@ContainerTest
|
@ContainerTest
|
||||||
fun createFile_successfully() {
|
fun createFile_successfully() {
|
||||||
// given
|
// given
|
||||||
|
@ -51,7 +50,6 @@ internal class FilesystemKtTest {
|
||||||
assertEquals(testtext, prov.fileContent("sudo$filename"))
|
assertEquals(testtext, prov.fileContent("sudo$filename"))
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
|
||||||
@ContainerTest
|
@ContainerTest
|
||||||
fun createFile_with_dir_successfully() {
|
fun createFile_with_dir_successfully() {
|
||||||
// given
|
// given
|
||||||
|
@ -77,7 +75,6 @@ internal class FilesystemKtTest {
|
||||||
assertEquals(testtext, prov.fileContent("sudo$filename"))
|
assertEquals(testtext, prov.fileContent("sudo$filename"))
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
|
||||||
@ContainerTest
|
@ContainerTest
|
||||||
fun createFile_with_dir_fails_if_createDirIfMissing_is_false() {
|
fun createFile_with_dir_fails_if_createDirIfMissing_is_false() {
|
||||||
// given
|
// given
|
||||||
|
@ -95,7 +92,6 @@ internal class FilesystemKtTest {
|
||||||
assertFalse(prov.checkDir("sudodirDoesNotExist", sudo = true))
|
assertFalse(prov.checkDir("sudodirDoesNotExist", sudo = true))
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
|
||||||
@ContainerTest
|
@ContainerTest
|
||||||
fun create_large_file_in_container() {
|
fun create_large_file_in_container() {
|
||||||
// given
|
// given
|
||||||
|
@ -113,7 +109,6 @@ internal class FilesystemKtTest {
|
||||||
// assertEquals(testtext, prov.fileContent(filename))
|
// assertEquals(testtext, prov.fileContent(filename))
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
|
||||||
@ContainerTest
|
@ContainerTest
|
||||||
fun create_and_delete_file() {
|
fun create_and_delete_file() {
|
||||||
// given
|
// given
|
||||||
|
@ -141,7 +136,6 @@ internal class FilesystemKtTest {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Test
|
|
||||||
@ContainerTest
|
@ContainerTest
|
||||||
fun create_and_delete_file_with_sudo() {
|
fun create_and_delete_file_with_sudo() {
|
||||||
// given
|
// given
|
||||||
|
@ -174,7 +168,6 @@ internal class FilesystemKtTest {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Test
|
|
||||||
@ContainerTest
|
@ContainerTest
|
||||||
fun create_and_delete_dir() {
|
fun create_and_delete_dir() {
|
||||||
// given
|
// given
|
||||||
|
@ -204,7 +197,6 @@ internal class FilesystemKtTest {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Test
|
|
||||||
@ContainerTest
|
@ContainerTest
|
||||||
fun create_and_delete_dir_with_sudo() {
|
fun create_and_delete_dir_with_sudo() {
|
||||||
// given
|
// given
|
||||||
|
@ -240,7 +232,6 @@ internal class FilesystemKtTest {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Test
|
|
||||||
@ContainerTest
|
@ContainerTest
|
||||||
fun replaceTextInFile() {
|
fun replaceTextInFile() {
|
||||||
// given
|
// given
|
||||||
|
@ -261,7 +252,6 @@ internal class FilesystemKtTest {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Test
|
|
||||||
@ContainerTest
|
@ContainerTest
|
||||||
fun replaceTextInFileRegex() {
|
fun replaceTextInFileRegex() {
|
||||||
// given
|
// given
|
||||||
|
@ -282,7 +272,6 @@ internal class FilesystemKtTest {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Test
|
|
||||||
@ContainerTest
|
@ContainerTest
|
||||||
fun insertTextInFile() {
|
fun insertTextInFile() {
|
||||||
// given
|
// given
|
||||||
|
@ -302,7 +291,6 @@ internal class FilesystemKtTest {
|
||||||
assertTrue(res4.success)
|
assertTrue(res4.success)
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
|
||||||
@ContainerTest
|
@ContainerTest
|
||||||
fun copyFileFromLocal_successfully() {
|
fun copyFileFromLocal_successfully() {
|
||||||
// given
|
// given
|
||||||
|
@ -316,7 +304,6 @@ internal class FilesystemKtTest {
|
||||||
assertEquals("resource text\n", content)
|
assertEquals("resource text\n", content)
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
|
||||||
@ContainerTest
|
@ContainerTest
|
||||||
fun fileContainsText() {
|
fun fileContainsText() {
|
||||||
// given
|
// given
|
||||||
|
@ -346,7 +333,6 @@ internal class FilesystemKtTest {
|
||||||
assertTrue(res10)
|
assertTrue(res10)
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
|
||||||
@ContainerTest
|
@ContainerTest
|
||||||
fun fileContainsText_with_sudo() {
|
fun fileContainsText_with_sudo() {
|
||||||
// given
|
// given
|
||||||
|
@ -404,4 +390,87 @@ internal class FilesystemKtTest {
|
||||||
assertEquals(content, actualContent)
|
assertEquals(content, actualContent)
|
||||||
assertEquals(1400000, size)
|
assertEquals(1400000, size)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ContainerTest
|
||||||
|
fun test_createParentDir() {
|
||||||
|
// given
|
||||||
|
val prov = defaultTestContainer()
|
||||||
|
val filename = "parent_dir/test/file"
|
||||||
|
|
||||||
|
// when
|
||||||
|
val res = prov.createParentDir(File(filename))
|
||||||
|
val dirExists = prov.checkDir("parent_dir/test")
|
||||||
|
val res2 = prov.createParentDir(File(filename)) // test idempotence
|
||||||
|
val dirExists2 = prov.checkDir("parent_dir/test")
|
||||||
|
|
||||||
|
// then
|
||||||
|
assertTrue(res.success)
|
||||||
|
assertTrue(dirExists)
|
||||||
|
assertTrue(res2.success)
|
||||||
|
assertTrue(dirExists2)
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@ContainerTest
|
||||||
|
fun test_createLink_without_dir() {
|
||||||
|
// given
|
||||||
|
val prov = defaultTestContainer()
|
||||||
|
val source = File("testlinksource")
|
||||||
|
val target = File("testlinktarget")
|
||||||
|
prov.createFile(source.toString(), "textinlinkfile")
|
||||||
|
|
||||||
|
// when
|
||||||
|
val res = prov.createSymlink(source, target)
|
||||||
|
val res2 = prov.createSymlink(source, target) // test idempotence
|
||||||
|
val linkExists = prov.checkFile(target.name)
|
||||||
|
val content = prov.fileContent(target.name)
|
||||||
|
|
||||||
|
// then
|
||||||
|
assertTrue(res.success)
|
||||||
|
assertTrue(res2.success)
|
||||||
|
assertTrue(linkExists)
|
||||||
|
assertEquals("textinlinkfile", content)
|
||||||
|
}
|
||||||
|
|
||||||
|
@ContainerTest
|
||||||
|
fun test_createLink_with_dirs() {
|
||||||
|
// given
|
||||||
|
val prov = defaultTestContainer()
|
||||||
|
val source = File("~/linksourcedir/testlinksource2")
|
||||||
|
val target = File("linkdir1/linkdir2/testlinktarget2")
|
||||||
|
prov.createFile(source.toString(), "textinlinkfile2")
|
||||||
|
|
||||||
|
// when
|
||||||
|
val res = prov.createSymlink(source, target)
|
||||||
|
val res2 = prov.createSymlink(source, target) // test idempotence
|
||||||
|
val linkExists = prov.checkFile(target.toString())
|
||||||
|
val content = prov.fileContent(target.toString())
|
||||||
|
|
||||||
|
// then
|
||||||
|
assertTrue(res.success)
|
||||||
|
assertTrue(res2.success)
|
||||||
|
assertTrue(linkExists)
|
||||||
|
assertEquals("textinlinkfile2", content)
|
||||||
|
}
|
||||||
|
|
||||||
|
@ContainerTest
|
||||||
|
fun test_createLink_with_dirs_and_sudo() {
|
||||||
|
// given
|
||||||
|
val prov = defaultTestContainer()
|
||||||
|
val source = File("/linksourcedirsudo/linksourcefilesudo")
|
||||||
|
val target = File("/linkdir1sudo/linkdir2sudo/linksudo")
|
||||||
|
prov.createFile(source.toString(), "textinlinkfilesudo", sudo = true)
|
||||||
|
|
||||||
|
// when
|
||||||
|
val res = prov.createSymlink(source, target, sudo = true)
|
||||||
|
val res2 = prov.createSymlink(source, target, sudo = true) // test idempotence
|
||||||
|
val linkExists = prov.checkFile(target.toString(), sudo = true)
|
||||||
|
val content = prov.fileContent(target.toString(), sudo = true)
|
||||||
|
|
||||||
|
// then
|
||||||
|
assertTrue(res.success)
|
||||||
|
assertTrue(res2.success)
|
||||||
|
assertTrue(linkExists)
|
||||||
|
assertEquals("textinlinkfilesudo", content)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue