From 1118bc7d07e3a3ab3607f0f8f6298cf79023627b Mon Sep 17 00:00:00 2001 From: ansgarz Date: Fri, 22 Nov 2024 11:27:04 +0100 Subject: [PATCH] add createCronJob --- .../ubuntu/cron/infrstructure/CronJob.kt | 22 ++++++ .../cron/infrstructure/CronJobKtTest.kt | 68 +++++++++++++++++++ 2 files changed, 90 insertions(+) create mode 100644 src/main/kotlin/org/domaindrivenarchitecture/provs/framework/ubuntu/cron/infrstructure/CronJob.kt create mode 100644 src/test/kotlin/org/domaindrivenarchitecture/provs/framework/ubuntu/cron/infrstructure/CronJobKtTest.kt diff --git a/src/main/kotlin/org/domaindrivenarchitecture/provs/framework/ubuntu/cron/infrstructure/CronJob.kt b/src/main/kotlin/org/domaindrivenarchitecture/provs/framework/ubuntu/cron/infrstructure/CronJob.kt new file mode 100644 index 0000000..2d3ccb4 --- /dev/null +++ b/src/main/kotlin/org/domaindrivenarchitecture/provs/framework/ubuntu/cron/infrstructure/CronJob.kt @@ -0,0 +1,22 @@ +package org.domaindrivenarchitecture.provs.framework.ubuntu.cron.infrstructure + +import org.domaindrivenarchitecture.provs.framework.core.Prov +import org.domaindrivenarchitecture.provs.framework.ubuntu.filesystem.base.createDirs +import org.domaindrivenarchitecture.provs.framework.ubuntu.filesystem.base.createFile +import org.domaindrivenarchitecture.provs.framework.ubuntu.user.base.whoami + + +/** + * Creates a cron job. + * @param cronFilename e.g. "90_my_cron", file is created in folder /etc/cron.d/ + * @param schedule in the usual cron-format, examples: "0 * * * *" for each hour, "0 3 1-7 * 1" for the first Monday each month at 3:00, etc + * @param cronCommand the executed command + * @param cronUser the user with whom the command will be executed, if null the current user is used + */ +fun Prov.createCronJob(cronFilename: String, schedule: String, cronCommand: String, cronUser: String? = null) = task { + val user = cronUser ?: whoami() + val cronLine = "$schedule $user $cronCommand\n" + + createDirs("/etc/cron.d/", sudo = true) + createFile("/etc/cron.d/$cronFilename", cronLine, "644", sudo = true, overwriteIfExisting = true) +} diff --git a/src/test/kotlin/org/domaindrivenarchitecture/provs/framework/ubuntu/cron/infrstructure/CronJobKtTest.kt b/src/test/kotlin/org/domaindrivenarchitecture/provs/framework/ubuntu/cron/infrstructure/CronJobKtTest.kt new file mode 100644 index 0000000..1225274 --- /dev/null +++ b/src/test/kotlin/org/domaindrivenarchitecture/provs/framework/ubuntu/cron/infrstructure/CronJobKtTest.kt @@ -0,0 +1,68 @@ +package org.domaindrivenarchitecture.provs.framework.ubuntu.cron.infrstructure + +import org.domaindrivenarchitecture.provs.framework.ubuntu.filesystem.base.checkFile +import org.domaindrivenarchitecture.provs.framework.ubuntu.filesystem.base.createDirs +import org.domaindrivenarchitecture.provs.framework.ubuntu.filesystem.base.fileContent +import org.domaindrivenarchitecture.provs.framework.ubuntu.install.base.aptInstall +import org.domaindrivenarchitecture.provs.framework.ubuntu.user.base.whoami +import org.domaindrivenarchitecture.provs.test.defaultTestContainer +import org.junit.jupiter.api.Assertions.* +import org.junit.jupiter.api.Disabled +import org.junit.jupiter.api.Test + +class CronJobKtTest { + @Test + fun createCronJob_creates_cron_file() { + // given + val prov = defaultTestContainer() + val cronFilename = "50_test_cron" + + // when + val result = prov.createCronJob(cronFilename, "0 * * * *", "echo hello > /dev/null 2>&1") + + // then + assertTrue(result.success) + val fqFilename = "/etc/cron.d/$cronFilename" + assertTrue(prov.checkFile(fqFilename), "") + val actualFileContent = prov.fileContent(fqFilename, sudo = true) + val expectedUser = prov.whoami() + assertEquals("0 * * * * $expectedUser echo hello > /dev/null 2>&1\n", actualFileContent) + } + + @Test + @Disabled // only for manual execution and manual check for the created files + // Test if cron-job is actually running, but needs manual checks + fun createCronJob_which_creates_files_with_timestamp() { + // given + val prov = defaultTestContainer() + val cronFilename = "90_time_cron" + + // for cron in docker see e.g. https://serverfault.com/questions/924779/docker-cron-not-working + prov.task { + aptInstall("cron") + cmd("sudo touch /var/log/cron.log") // Create the log file + optional { // may already be running + cmd("sudo cron") // Run cron + } + cmd("pgrep cron") // Ensure cron is running + } + + prov.createDirs("tmp") + val user = prov.whoami() + + // when + val result = prov.createCronJob( + cronFilename, + "*/1 * * * *", + "echo \"xxx\" > /home/$user/tmp/\$(/usr/bin/date +\\%Y_\\%m_\\%d-\\%H_\\%M)" + ) + + // then + assertTrue(result.success) + val fqFilename = "/etc/cron.d/$cronFilename" + assertTrue(prov.checkFile(fqFilename), "File does not exist: $fqFilename") + + // after a minute check manually if files exist, e.g. with: sudo docker exec provs_test /bin/bash -c "ls -l tmp" + // each minute a new file should be created with the timestamp + } +} \ No newline at end of file