make deleteFile idem-potent, refactor sudo in file functions

This commit is contained in:
ansgarz 2022-01-31 19:33:44 +01:00
parent 08e9dd1e1a
commit 3f1fdb754e
3 changed files with 38 additions and 17 deletions

View file

@ -53,7 +53,7 @@ fun String.escapeDollar(): String = replace("$", "\\$")
fun String.escapeSingleQuoteForShell(): String = replace("'", "'\"'\"'")
fun String.escapeProcentForPrintf(): String = replace("%", "%%")
fun String.endingWithFileSeparator(): String = if (isNotEmpty() && (last() != fileSeparatorChar())) this + fileSeparator() else this
fun prefixWithSudo(text: String, sudo: Boolean): String = if (sudo) "sudo $text" else text
// -------------- Functions for system related properties -----------------
fun fileSeparator(): String = File.separator

View file

@ -10,7 +10,7 @@ import java.io.File
* Returns true if the given file exists.
*/
fun Prov.fileExists(file: String, sudo: Boolean = false): Boolean {
return cmdNoEval((if (sudo) "sudo " else "") + "test -e " + file).success
return cmdNoEval(prefixWithSudo("test -e " + file, sudo)).success
}
@ -116,28 +116,32 @@ fun Prov.createSecretFile(
fullyQualifiedFilename: String,
secret: Secret,
posixFilePermission: String? = null
): ProvResult =
def {
): ProvResult = def {
posixFilePermission?.let {
ensureValidPosixFilePermission(posixFilePermission)
cmd("install -m $posixFilePermission /dev/null $fullyQualifiedFilename")
}
cmdNoLog("echo '" + secret.plain().escapeSingleQuote() + "' > $fullyQualifiedFilename")
}
}
fun Prov.deleteFile(file: String, path: String? = null, sudo: Boolean = false): ProvResult = def {
cmd((path?.let { "cd $path && " } ?: "") + (if (sudo) "sudo " else "") + "rm $file")
val fullyQualifiedFilename = (path?.normalizePath() ?: "") + file
if (fileExists(fullyQualifiedFilename, sudo = sudo)) {
cmd(prefixWithSudo("rm $fullyQualifiedFilename", sudo))
} else {
ProvResult(true, "File to be deleted did not exist.")
}
}
fun Prov.fileContainsText(file: String, content: String, sudo: Boolean = false): Boolean {
return cmdNoEval((if (sudo) "sudo " else "") + "grep -- '${content.escapeSingleQuote()}' $file").success
return cmdNoEval(prefixWithSudo( "grep -- '${content.escapeSingleQuote()}' $file", sudo)).success
}
fun Prov.fileContent(file: String, sudo: Boolean = false): String? {
return cmd((if (sudo) "sudo " else "") + "cat $file").out
return cmd(prefixWithSudo("cat $file", sudo)).out
}
@ -283,10 +287,23 @@ fun Prov.fileSize(filename: String): Int? {
private fun ensureValidPosixFilePermission(posixFilePermission: String) {
if (!Regex("^[0-7]{3}$").matches(posixFilePermission)) throw RuntimeException("Wrong file permission ($posixFilePermission), permission must consist of 3 digits as e.g. 664 ")
if (!Regex("^[0-7]{3}$").matches(posixFilePermission)) throw IllegalArgumentException("Wrong file permission ($posixFilePermission), permission must consist of 3 digits as e.g. 664")
}
/**
* Returns a command encapsulated in a shell command and executed with sudo.
* For simple cases consider sudo as prefix instead.
* @see prefixWithSudo
*/
private fun String.sudoizeCommand(): String {
return "sudo " + SHELL + " -c " + this.escapeAndEncloseByDoubleQuoteForShell()
}
/**
* Returns path with a trailing fileSeparator if path not empty
*/
private fun String.normalizePath(): String {
return if (this == "" || this.endsWith(fileSeparatorChar())) this else this + fileSeparator()
}

View file

@ -70,7 +70,7 @@ internal class FilesystemKtTest {
@Test
@ContainerTest
fun checkingCreatingDeletingFile() {
fun create_and_delete_file() {
// given
val prov = defaultTestContainer()
@ -82,6 +82,7 @@ internal class FilesystemKtTest {
val res4b = prov.fileContainsText("testfile", "some non-existing content")
val res5 = prov.deleteFile("testfile")
val res6 = prov.fileExists("testfile")
val res7 = prov.deleteFile("testfile") // idem-potent
// then
assertFalse(res1)
@ -91,12 +92,13 @@ internal class FilesystemKtTest {
assertFalse(res4b)
assertTrue(res5.success)
assertFalse(res6)
assertTrue(res7.success)
}
@Test
@ContainerTest
fun checkingCreatingDeletingFileWithSudo() {
fun create_and_delete_file_with_sudo() {
// given
val prov = defaultTestContainer()
@ -111,6 +113,7 @@ internal class FilesystemKtTest {
val res6 = prov.fileExists(file)
val res7 = prov.deleteFile(file, sudo = true)
val res8 = prov.fileExists(file)
val res9 = prov.deleteFile(file, sudo = true) // check idem-potence
// then
assertFalse(res1)
@ -122,12 +125,13 @@ internal class FilesystemKtTest {
assertTrue(res6)
assertTrue(res7.success)
assertFalse(res8)
assertTrue(res9.success)
}
@Test
@ContainerTest
fun checkingCreatingDeletingDir() {
fun create_and_delete_dir() {
// given
val prov = defaultTestContainer()
@ -157,7 +161,7 @@ internal class FilesystemKtTest {
@Test
@ContainerTest
fun checkingCreatingDeletingDirWithSudo() {
fun create_and_delete_dir_with_sudo() {
// given
val prov = defaultTestContainer()