From c4d5f38f9d95e9554a1891d2a00a1990dac48d24 Mon Sep 17 00:00:00 2001 From: ansgarz Date: Sun, 30 Jan 2022 21:39:20 +0100 Subject: [PATCH] chg createFile for large files, fix LocationsKtTest.kt, rename const (NGINX_CONFIG_FILE) --- .../standalone_server/nginx/ProvisionNginx.kt | 23 +++-------- .../ubuntu/filesystem/base/Filesystem.kt | 39 ++++++++++--------- .../nginx/base/LocationsKtTest.kt | 8 ++-- .../filesystem/base/FilesystemKtTest.kt | 34 +++++++++++----- 4 files changed, 55 insertions(+), 49 deletions(-) diff --git a/src/main/kotlin/org/domaindrivenarchitecture/provs/framework/extensions/server_software/standalone_server/nginx/ProvisionNginx.kt b/src/main/kotlin/org/domaindrivenarchitecture/provs/framework/extensions/server_software/standalone_server/nginx/ProvisionNginx.kt index 6e7632c..bf9f710 100644 --- a/src/main/kotlin/org/domaindrivenarchitecture/provs/framework/extensions/server_software/standalone_server/nginx/ProvisionNginx.kt +++ b/src/main/kotlin/org/domaindrivenarchitecture/provs/framework/extensions/server_software/standalone_server/nginx/ProvisionNginx.kt @@ -2,16 +2,14 @@ package org.domaindrivenarchitecture.provs.framework.extensions.server_software. import org.domaindrivenarchitecture.provs.framework.core.Prov import org.domaindrivenarchitecture.provs.framework.core.ProvResult -import org.domaindrivenarchitecture.provs.framework.core.remote +import org.domaindrivenarchitecture.provs.framework.extensions.server_software.standalone_server.nginx.base.NginxConf +import org.domaindrivenarchitecture.provs.framework.extensions.server_software.standalone_server.nginx.base.createNginxLocationFolders import org.domaindrivenarchitecture.provs.framework.ubuntu.filesystem.base.createFile import org.domaindrivenarchitecture.provs.framework.ubuntu.filesystem.base.fileExists import org.domaindrivenarchitecture.provs.framework.ubuntu.install.base.aptInstall -import org.domaindrivenarchitecture.provs.framework.extensions.server_software.standalone_server.nginx.base.NginxConf -import org.domaindrivenarchitecture.provs.framework.extensions.server_software.standalone_server.nginx.base.createNginxLocationFolders -import kotlin.system.exitProcess -internal const val configFile = "/etc/nginx/nginx.conf" +internal const val NGINX_CONFIG_FILE = "/etc/nginx/nginx.conf" fun Prov.provisionNginxStandAlone(config: NginxConf? = null) = requireAll { @@ -21,10 +19,10 @@ fun Prov.provisionNginxStandAlone(config: NginxConf? = null) = requireAll { createNginxLocationFolders() if (config != null) { - if (fileExists(configFile)) { - cmd("sudo mv $configFile $configFile-orig") + if (fileExists(NGINX_CONFIG_FILE)) { + cmd("sudo mv $NGINX_CONFIG_FILE $NGINX_CONFIG_FILE-orig") } - createFile(configFile, config.conf, sudo = true) + createFile(NGINX_CONFIG_FILE, config.conf, sudo = true) val configCheck = cmd("sudo nginx -t") if (configCheck.success) { cmd("sudo service nginx restart") @@ -35,12 +33,3 @@ fun Prov.provisionNginxStandAlone(config: NginxConf? = null) = requireAll { ProvResult(true) // dummy } } - - -fun provisionRemote(vararg args: String) { - if (args.size != 2) { - println("Pls specify host and user for remote installation of nginx.") - exitProcess(1) - } - remote(args[0], args[1]).provisionNginxStandAlone() -} \ No newline at end of file diff --git a/src/main/kotlin/org/domaindrivenarchitecture/provs/framework/ubuntu/filesystem/base/Filesystem.kt b/src/main/kotlin/org/domaindrivenarchitecture/provs/framework/ubuntu/filesystem/base/Filesystem.kt index 81cb309..8ac3f28 100644 --- a/src/main/kotlin/org/domaindrivenarchitecture/provs/framework/ubuntu/filesystem/base/Filesystem.kt +++ b/src/main/kotlin/org/domaindrivenarchitecture/provs/framework/ubuntu/filesystem/base/Filesystem.kt @@ -80,39 +80,32 @@ fun Prov.createFile( text: String?, posixFilePermission: String? = null, sudo: Boolean = false, - overwriteIfExisting: Boolean = false + overwriteIfExisting: Boolean = true ): ProvResult = task { - val maxBlockSize = 100000 - - if (!overwriteIfExisting && fileExists(fullyQualifiedFilename, sudo)) { - return@task ProvResult(true, "File $fullyQualifiedFilename already existing.") - } + val maxBlockSize = 50000 val withSudo = if (sudo) "sudo " else "" posixFilePermission?.let { ensureValidPosixFilePermission(posixFilePermission) } + if (!overwriteIfExisting && fileExists(fullyQualifiedFilename, sudo)) { + return@task ProvResult(true, "File $fullyQualifiedFilename already existing.") + } + val modeOption = posixFilePermission?.let { "-m $it"} ?: "" // create empty file resp. clear file cmd(withSudo + "install $modeOption /dev/null $fullyQualifiedFilename") if (text != null) { - if (text.length <= maxBlockSize) { + val chunkedTest = text.chunked(maxBlockSize) + for (chunk in chunkedTest) { cmd( - "printf '%s' " + text - .escapeAndEncloseByDoubleQuoteForShell() + " | ${if (sudo) "sudo" else ""} tee $fullyQualifiedFilename > /dev/null" + "printf '%s' " + chunk + .escapeAndEncloseByDoubleQuoteForShell() + " | $withSudo tee -a $fullyQualifiedFilename > /dev/null" ) - } else { - val chunkedTest = text.chunked(maxBlockSize) - for (chunk in chunkedTest) { - cmd( - "printf '%s' " + chunk - .escapeAndEncloseByDoubleQuoteForShell() + " | ${if (sudo) "sudo" else ""} tee -a $fullyQualifiedFilename > /dev/null" - ) - } - ProvResult(true) // dummy } + ProvResult(true) // dummy } else { cmd(withSudo + "touch $fullyQualifiedFilename") } @@ -265,6 +258,7 @@ fun Prov.deleteDir(dir: String, path: String, sudo: Boolean = false): ProvResult } +// --------------------- various functions ---------------------- fun Prov.userHome(): String { val user = cmd("whoami").out?.trim() if (user == null) { @@ -279,6 +273,15 @@ fun Prov.userHome(): String { } +/** + * Returns number of bytes of a file or null if size could not be determined + */ +fun Prov.fileSize(filename: String): Int? { + val result = cmd("wc -c < $filename") + return result.out?.trim()?.toIntOrNull() +} + + 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 ") } diff --git a/src/test/kotlin/org/domaindrivenarchitecture/provs/framework/extensions/server_software/standalone_server/nginx/base/LocationsKtTest.kt b/src/test/kotlin/org/domaindrivenarchitecture/provs/framework/extensions/server_software/standalone_server/nginx/base/LocationsKtTest.kt index 19ba579..1a03428 100644 --- a/src/test/kotlin/org/domaindrivenarchitecture/provs/framework/extensions/server_software/standalone_server/nginx/base/LocationsKtTest.kt +++ b/src/test/kotlin/org/domaindrivenarchitecture/provs/framework/extensions/server_software/standalone_server/nginx/base/LocationsKtTest.kt @@ -2,7 +2,7 @@ package org.domaindrivenarchitecture.provs.framework.extensions.server_software. import org.domaindrivenarchitecture.provs.framework.ubuntu.filesystem.base.createFile import org.domaindrivenarchitecture.provs.framework.ubuntu.filesystem.base.fileContainsText -import org.domaindrivenarchitecture.provs.framework.extensions.server_software.standalone_server.nginx.configFile +import org.domaindrivenarchitecture.provs.framework.extensions.server_software.standalone_server.nginx.NGINX_CONFIG_FILE import org.domaindrivenarchitecture.provs.framework.extensions.server_software.standalone_server.nginx.provisionNginxStandAlone import org.junit.jupiter.api.Assertions.assertEquals import org.junit.jupiter.api.Assertions.assertTrue @@ -20,7 +20,7 @@ internal class LocationsKtTest { // given val a = defaultTestContainer() a.provisionNginxStandAlone() - a.createFile(configFile, NGINX_MINIMAL_CONF, sudo = true) + a.createFile(NGINX_CONFIG_FILE, NGINX_MINIMAL_CONF, sudo = true) // when val res = a.nginxIncludeLocationFolders() @@ -28,10 +28,10 @@ internal class LocationsKtTest { // then assertTrue(res.success) assertTrue(a.fileContainsText( - configFile, """listen 80; + NGINX_CONFIG_FILE, """listen 80; include /etc/nginx/locations-enabled/port80*.conf include /etc/nginx/locations-enabled/port443*.conf""")) // just 1 occurrence - assertEquals("1", a.cmd("grep -o 'listen 80;' $configFile | wc -l").out?.trim()) + assertEquals("1", a.cmd("grep -o 'listen 80;' $NGINX_CONFIG_FILE | wc -l").out?.trim()) } } \ No newline at end of file diff --git a/src/test/kotlin/org/domaindrivenarchitecture/provs/framework/ubuntu/filesystem/base/FilesystemKtTest.kt b/src/test/kotlin/org/domaindrivenarchitecture/provs/framework/ubuntu/filesystem/base/FilesystemKtTest.kt index 98385bb..d5730eb 100644 --- a/src/test/kotlin/org/domaindrivenarchitecture/provs/framework/ubuntu/filesystem/base/FilesystemKtTest.kt +++ b/src/test/kotlin/org/domaindrivenarchitecture/provs/framework/ubuntu/filesystem/base/FilesystemKtTest.kt @@ -11,16 +11,12 @@ import java.io.File internal class FilesystemKtTest { val testtext = "tabs \t\t\t triple quotes \"\"\"" + """ - \\ \\\ \\\\ \\\\\ - '\t%s \\ " "" - ' "${'$'}arg")" - '%s' "${'$'}@" | 's/\([][!#${'$'}%&()*;<=>?\_`{|}]\)/\\\1/g;' - "${'$'}@" | sed -e 's/"/\\"/g' - apostrophe's ' " \" \' and special chars ${'$'} {} ${'$'}\{something}!§${'$'}%[]\\ äöüß ${'$'}\notakotlinvariable ${'$'}notakotlinvariable and tabs and \t are should be handled correctly + newline + and apostrophe's ' '' ''' \' " "" \" and special chars ${'$'} {} ${'$'}\{something}<>äöüß!§@€%#|&/[]\\ äöüß %s %% %%% \\ \\\ \\\\ \\\\\ ${'$'}\notakotlinvariable ${'$'}notakotlinvariable and tabs and \t should be handled correctly """ @Test - fun test_createFile_locally() { + fun createFile_locally() { // given val prov = testLocal() prov.createDir("tmp") @@ -38,7 +34,7 @@ internal class FilesystemKtTest { @Test @ContainerTest - fun test_createFile_in_container() { + fun createFile_in_container() { // given val prov = defaultTestContainer() val filename = "testfile8" @@ -54,6 +50,24 @@ internal class FilesystemKtTest { assertEquals(testtext, prov.fileContent("sudo$filename")) } + @Test + @ContainerTest + fun create_large_file_in_container() { + // given + val prov = defaultTestContainer() + val filename = "largetestfile" + val content = "012345äöüß".repeat(100000) + + // when + val res = prov.createFile(filename, content) + val size = prov.fileSize(filename) + + // then + assertTrue(res.success) + assertEquals(1400000, size) + // assertEquals(testtext, prov.fileContent(filename)) + } + @Test @ContainerTest fun checkingCreatingDeletingFile() { @@ -255,7 +269,7 @@ internal class FilesystemKtTest { @Test @ContainerTest - fun test_fileContainsText() { + fun fileContainsText() { // given defaultTestContainer().createFile("testfilecontainingtext", "abc\n- def\nefg") @@ -271,4 +285,4 @@ internal class FilesystemKtTest { assertTrue(res3) assertFalse(res4) } -} \ No newline at end of file +}