fix configureVenv for idempotence, add createSymlink

This commit is contained in:
ansgarz 2022-05-16 22:09:35 +02:00
parent 876836f6a3
commit a881310f48
5 changed files with 123 additions and 21 deletions

View file

@ -2,7 +2,9 @@ package org.domaindrivenarchitecture.provs.desktop.infrastructure
import org.domaindrivenarchitecture.provs.framework.core.Prov
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 java.io.File
fun Prov.provisionPython() = task {
@ -21,7 +23,7 @@ fun Prov.configureVenv(): ProvResult = task {
val venvHome = "~/.venv/meissa"
cmd("python3 -m venv " + venvHome)
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")
}

View file

@ -94,10 +94,9 @@ fun Prov.createFile(
val maxBlockSize = 50000
val withSudo = if (sudo) "sudo " else ""
val file = File(fullyQualifiedFilename)
val dir = file.parent?.toString()
if (dir != null && dir != "" && createDirIfMissing && !checkDir(dir, sudo = sudo)) {
createDirs(dir, sudo = sudo)
if (createDirIfMissing) {
createParentDir(file, sudo)
}
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 ----------------------
fun Prov.userHome(): String {
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
*/

View file

@ -7,11 +7,9 @@ import org.domaindrivenarchitecture.provs.test.defaultTestContainer
import org.domaindrivenarchitecture.provs.test.tags.ContainerTest
import org.junit.jupiter.api.Assertions.assertEquals
import org.junit.jupiter.api.Assertions.assertTrue
import org.junit.jupiter.api.Test
internal class BashKtTest {
@Test
@ContainerTest
fun configureBashForUser() {
// when

View file

@ -7,7 +7,7 @@ import org.junit.jupiter.api.Assertions.assertTrue
internal class PythonKtTest {
@ExtensiveContainerTest
fun installPython() {
fun test_provisionPython() {
// when
val res = defaultTestContainer().provisionPython()

View file

@ -33,7 +33,6 @@ internal class FilesystemKtTest {
assertEquals(testtext, textFromFile)
}
@Test
@ContainerTest
fun createFile_successfully() {
// given
@ -51,7 +50,6 @@ internal class FilesystemKtTest {
assertEquals(testtext, prov.fileContent("sudo$filename"))
}
@Test
@ContainerTest
fun createFile_with_dir_successfully() {
// given
@ -77,7 +75,6 @@ internal class FilesystemKtTest {
assertEquals(testtext, prov.fileContent("sudo$filename"))
}
@Test
@ContainerTest
fun createFile_with_dir_fails_if_createDirIfMissing_is_false() {
// given
@ -95,7 +92,6 @@ internal class FilesystemKtTest {
assertFalse(prov.checkDir("sudodirDoesNotExist", sudo = true))
}
@Test
@ContainerTest
fun create_large_file_in_container() {
// given
@ -113,7 +109,6 @@ internal class FilesystemKtTest {
// assertEquals(testtext, prov.fileContent(filename))
}
@Test
@ContainerTest
fun create_and_delete_file() {
// given
@ -141,7 +136,6 @@ internal class FilesystemKtTest {
}
@Test
@ContainerTest
fun create_and_delete_file_with_sudo() {
// given
@ -174,7 +168,6 @@ internal class FilesystemKtTest {
}
@Test
@ContainerTest
fun create_and_delete_dir() {
// given
@ -204,7 +197,6 @@ internal class FilesystemKtTest {
}
@Test
@ContainerTest
fun create_and_delete_dir_with_sudo() {
// given
@ -240,7 +232,6 @@ internal class FilesystemKtTest {
}
@Test
@ContainerTest
fun replaceTextInFile() {
// given
@ -261,7 +252,6 @@ internal class FilesystemKtTest {
}
@Test
@ContainerTest
fun replaceTextInFileRegex() {
// given
@ -282,7 +272,6 @@ internal class FilesystemKtTest {
}
@Test
@ContainerTest
fun insertTextInFile() {
// given
@ -302,7 +291,6 @@ internal class FilesystemKtTest {
assertTrue(res4.success)
}
@Test
@ContainerTest
fun copyFileFromLocal_successfully() {
// given
@ -316,7 +304,6 @@ internal class FilesystemKtTest {
assertEquals("resource text\n", content)
}
@Test
@ContainerTest
fun fileContainsText() {
// given
@ -346,7 +333,6 @@ internal class FilesystemKtTest {
assertTrue(res10)
}
@Test
@ContainerTest
fun fileContainsText_with_sudo() {
// given
@ -404,4 +390,87 @@ internal class FilesystemKtTest {
assertEquals(content, actualContent)
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)
}
}