add sha256sum checksum check to downloadFormUrl
This commit is contained in:
parent
f518e00208
commit
a0fde38bd2
9 changed files with 111 additions and 47 deletions
|
@ -352,11 +352,10 @@ open class Prov protected constructor(
|
||||||
"============================================== "
|
"============================================== "
|
||||||
)
|
)
|
||||||
for (result in internalResults) {
|
for (result in internalResults) {
|
||||||
println(
|
val outputLine = result.toString().escapeControlChars()
|
||||||
result.toString().escapeNewline()
|
.replaceFirst("Success --", ANSI_BRIGHT_GREEN + "Success" + ANSI_RESET + " --")
|
||||||
.replace("Success --", ANSI_BRIGHT_GREEN + "Success" + ANSI_RESET + " --")
|
.replaceFirst("FAILED --", ANSI_BRIGHT_RED + "FAILED" + ANSI_RESET + " --")
|
||||||
.replace("FAILED --", ANSI_BRIGHT_RED + "FAILED" + ANSI_RESET + " --")
|
println(outputLine)
|
||||||
)
|
|
||||||
}
|
}
|
||||||
if (internalResults.size > 1) {
|
if (internalResults.size > 1) {
|
||||||
println("----------------------------------------------------------------------------------------------------- ")
|
println("----------------------------------------------------------------------------------------------------- ")
|
||||||
|
@ -410,7 +409,7 @@ internal data class ResultLine(val level: Int, val method: String?, var provResu
|
||||||
return if (provResult != null) {
|
return if (provResult != null) {
|
||||||
prefix(level) + (if (provResult.success) "Success -- " else "FAILED -- ") +
|
prefix(level) + (if (provResult.success) "Success -- " else "FAILED -- ") +
|
||||||
method + " " + (provResult.cmd ?: "") +
|
method + " " + (provResult.cmd ?: "") +
|
||||||
(if (!provResult.success && provResult.err != null) " -- Error: " + provResult.err.escapeNewline() else "")
|
(if (!provResult.success && provResult.err != null) " -- Error: " + provResult.err.escapeControlChars() else "")
|
||||||
} else
|
} else
|
||||||
prefix(level) + method + " " + "... in progress ... "
|
prefix(level) + method + " " + "... in progress ... "
|
||||||
|
|
||||||
|
|
|
@ -40,7 +40,8 @@ fun getCallingMethodName(): String? {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
fun String.escapeNewline(): String = this.replace("\r\n", "\\n").replace("\n", "\\n")
|
fun String.escapeNewline(): String = this.replace("\r", "\\r").replace("\n", "\\n")
|
||||||
|
fun String.escapeControlChars(): String = this.replace("\r", "\\r").replace("\n", "\\n").replace("\t", "\\t").replace("[\\p{Cntrl}]".toRegex(), "\\?")
|
||||||
fun String.escapeBackslash(): String = this.replace("\\", "\\\\")
|
fun String.escapeBackslash(): String = this.replace("\\", "\\\\")
|
||||||
fun String.escapeDoubleQuote(): String = this.replace("\"", "\\\"")
|
fun String.escapeDoubleQuote(): String = this.replace("\"", "\\\"")
|
||||||
fun String.escapeSingleQuote(): String = this.replace("'", "\'")
|
fun String.escapeSingleQuote(): String = this.replace("'", "\'")
|
||||||
|
|
|
@ -17,7 +17,7 @@ class UbuntuPlusUser(private val userName: String = "testuser") : DockerImage {
|
||||||
|
|
||||||
override fun imageText(): String {
|
override fun imageText(): String {
|
||||||
return """
|
return """
|
||||||
FROM ubuntu:18.04
|
FROM ubuntu:20.04
|
||||||
|
|
||||||
ARG DEBIAN_FRONTEND=noninteractive
|
ARG DEBIAN_FRONTEND=noninteractive
|
||||||
|
|
||||||
|
|
|
@ -2,29 +2,39 @@ package org.domaindrivenarchitecture.provs.extensions.workplace.base
|
||||||
|
|
||||||
import org.domaindrivenarchitecture.provs.core.Prov
|
import org.domaindrivenarchitecture.provs.core.Prov
|
||||||
import org.domaindrivenarchitecture.provs.core.ProvResult
|
import org.domaindrivenarchitecture.provs.core.ProvResult
|
||||||
import org.domaindrivenarchitecture.provs.ubuntu.filesystem.base.createDir
|
import org.domaindrivenarchitecture.provs.ubuntu.filesystem.base.*
|
||||||
import org.domaindrivenarchitecture.provs.ubuntu.filesystem.base.createDirs
|
|
||||||
import org.domaindrivenarchitecture.provs.ubuntu.filesystem.base.createFile
|
|
||||||
import org.domaindrivenarchitecture.provs.ubuntu.filesystem.base.userHome
|
|
||||||
import org.domaindrivenarchitecture.provs.ubuntu.install.base.aptInstall
|
import org.domaindrivenarchitecture.provs.ubuntu.install.base.aptInstall
|
||||||
import org.domaindrivenarchitecture.provs.ubuntu.install.base.isPackageInstalled
|
import org.domaindrivenarchitecture.provs.ubuntu.install.base.isPackageInstalled
|
||||||
|
import org.domaindrivenarchitecture.provs.ubuntu.web.base.downloadFromURL
|
||||||
|
|
||||||
|
|
||||||
fun Prov.installGopass(version: String = "1.12.7", enforceVersion: Boolean = false) = def {
|
fun Prov.installGopass(version: String = "1.12.7", enforceVersion: Boolean = false) = def {
|
||||||
if (isPackageInstalled("gopass") && !enforceVersion) {
|
|
||||||
ProvResult(true)
|
|
||||||
} else {
|
|
||||||
// install required dependencies
|
|
||||||
aptInstall("rng-tools gnupg2 git")
|
|
||||||
aptInstall("curl")
|
|
||||||
|
|
||||||
sh(
|
val sha256sum = "0824d5110ff1e68bff1ba10c1be63acb67cb1ad8e3bccddd6b6fc989608beca8" // checksum for sha256sum version 8.30 (e.g. ubuntu 20.04)
|
||||||
"""
|
|
||||||
curl -L https://github.com/gopasspw/gopass/releases/download/v${version}/gopass_${version}_linux_amd64.deb -o gopass_${version}_linux_amd64.deb
|
if (isPackageInstalled("gopass") && !enforceVersion) {
|
||||||
sudo dpkg -i gopass_${version}_linux_amd64.deb
|
return@def ProvResult(true)
|
||||||
"""
|
}
|
||||||
)
|
if (checkGopassVersion(version)) {
|
||||||
gopassEnsureVersion(version)
|
return@def ProvResult(true, out = "Version $version of gopass is already installed.")
|
||||||
|
}
|
||||||
|
|
||||||
|
val path = "tmp"
|
||||||
|
// install required dependencies
|
||||||
|
aptInstall("rng-tools gnupg2 git")
|
||||||
|
val filename = "gopass_${version}_linux_amd64.deb"
|
||||||
|
val result = downloadFromURL(
|
||||||
|
"https://github.com/gopasspw/gopass/releases/download/v$version/$filename",
|
||||||
|
filename,
|
||||||
|
path,
|
||||||
|
sha256sum = sha256sum
|
||||||
|
)
|
||||||
|
if (result.success) {
|
||||||
|
cmd("sudo dpkg -i $path/gopass_${version}_linux_amd64.deb")
|
||||||
|
// Cross-check if installation was successful
|
||||||
|
addResultToEval(ProvResult(checkGopassVersion(version)))
|
||||||
|
} else {
|
||||||
|
addResultToEval(ProvResult(false, err = "Gopass could not be installed. " + result.err))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -76,13 +86,9 @@ mounts: {}
|
||||||
*
|
*
|
||||||
* @param version that is checked; specifies left part of text of installed version, e.g. both "1" and "1.12" will return true if installed version is "1.12.6+8d7a311b9273846bbb618e4bd9ddbae51b1db7b8"
|
* @param version that is checked; specifies left part of text of installed version, e.g. both "1" and "1.12" will return true if installed version is "1.12.6+8d7a311b9273846bbb618e4bd9ddbae51b1db7b8"
|
||||||
*/
|
*/
|
||||||
internal fun Prov.gopassEnsureVersion(version: String) = def {
|
internal fun Prov.checkGopassVersion(version: String): Boolean {
|
||||||
val installedGopassVersion = gopassVersion()
|
val installedGopassVersion = gopassVersion()
|
||||||
if (installedGopassVersion != null && installedGopassVersion.startsWith("gopass " + version)) {
|
return installedGopassVersion != null && installedGopassVersion.startsWith("gopass " + version)
|
||||||
ProvResult(true, out = "Required gopass version ($version) matches installed version ($installedGopassVersion)")
|
|
||||||
} else {
|
|
||||||
ProvResult(false, err = "Wrong gopass version. Expected $version but found $installedGopassVersion")
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
internal fun Prov.gopassVersion(): String? {
|
internal fun Prov.gopassVersion(): String? {
|
||||||
|
|
|
@ -34,7 +34,7 @@ fun Prov.installGopassBridgeJsonApi() = def {
|
||||||
|
|
||||||
if (installedJsonApiVersion == null) {
|
if (installedJsonApiVersion == null) {
|
||||||
if (chk("gopass ls")) {
|
if (chk("gopass ls")) {
|
||||||
if (gopassEnsureVersion(requiredGopassVersion).success) {
|
if (checkGopassVersion(requiredGopassVersion)) {
|
||||||
aptInstall("git gnupg2") // required dependencies
|
aptInstall("git gnupg2") // required dependencies
|
||||||
createDir(downloadDir)
|
createDir(downloadDir)
|
||||||
downloadFromURL(downloadUrl, filename, downloadDir)
|
downloadFromURL(downloadUrl, filename, downloadDir)
|
||||||
|
|
|
@ -54,8 +54,8 @@ fun Prov.createSecretFile(
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
fun Prov.deleteFile(file: String, sudo: Boolean = false): ProvResult = def {
|
fun Prov.deleteFile(file: String, path: String? = null, sudo: Boolean = false): ProvResult = def {
|
||||||
cmd((if (sudo) "sudo " else "") + "rm $file")
|
cmd((path?.let { "cd $path && " } ?: "") + (if (sudo) "sudo " else "") + "rm $file")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -2,25 +2,45 @@ package org.domaindrivenarchitecture.provs.ubuntu.web.base
|
||||||
|
|
||||||
import org.domaindrivenarchitecture.provs.core.Prov
|
import org.domaindrivenarchitecture.provs.core.Prov
|
||||||
import org.domaindrivenarchitecture.provs.core.ProvResult
|
import org.domaindrivenarchitecture.provs.core.ProvResult
|
||||||
|
import org.domaindrivenarchitecture.provs.core.tags.Api
|
||||||
|
import org.domaindrivenarchitecture.provs.ubuntu.filesystem.base.createDirs
|
||||||
|
import org.domaindrivenarchitecture.provs.ubuntu.filesystem.base.deleteFile
|
||||||
import org.domaindrivenarchitecture.provs.ubuntu.install.base.aptInstall
|
import org.domaindrivenarchitecture.provs.ubuntu.install.base.aptInstall
|
||||||
import org.domaindrivenarchitecture.provs.ubuntu.install.base.isPackageInstalled
|
import org.domaindrivenarchitecture.provs.ubuntu.install.base.isPackageInstalled
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Downloads a file from the given URL using curl
|
* Downloads a file from the given URL using curl.
|
||||||
*
|
*
|
||||||
* @param path where to download to
|
* ATTENTION: sha256sum uses the version available, which can differ in different versions of ubuntu; e.g. gopass download only works with sha256sum version 8.30 from ubuntu 20.04 !
|
||||||
* @param url file to download
|
|
||||||
* @param filename filename after download
|
|
||||||
*/
|
*/
|
||||||
@Suppress("unused") // used externally
|
@Api
|
||||||
fun Prov.downloadFromURL(url: String, filename: String? = null, path: String? = null, sudo: Boolean = false) : ProvResult = def {
|
fun Prov.downloadFromURL(
|
||||||
|
url: String,
|
||||||
|
filename: String? = null,
|
||||||
|
path: String? = null,
|
||||||
|
sudo: Boolean = false,
|
||||||
|
followRedirect: Boolean = true,
|
||||||
|
sha256sum: String? = null
|
||||||
|
): ProvResult = def {
|
||||||
|
|
||||||
if (!isPackageInstalled("curl")) aptInstall("curl")
|
aptInstall("curl")
|
||||||
|
|
||||||
if (filename == null) {
|
val followRedirectOption = if (followRedirect) "-L" else ""
|
||||||
cmd("curl $url", path, sudo)
|
val filenameFromUrl = url.substringAfterLast("/")
|
||||||
|
|
||||||
|
val finalFilename: String = filename ?: filenameFromUrl
|
||||||
|
|
||||||
|
path?.let { createDirs(path) }
|
||||||
|
cmd("curl $followRedirectOption $url -o $finalFilename", path, sudo)
|
||||||
|
|
||||||
|
if (sha256sum != null) {
|
||||||
|
if (!cmd("echo \"$sha256sum $finalFilename\" | sha256sum --check", path).success) {
|
||||||
|
deleteFile(finalFilename, path, sudo)
|
||||||
|
} else {
|
||||||
|
ProvResult(true, out = "Sha256sum is correct.")
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
cmd("curl $url -o $filename", path, sudo)
|
ProvResult(true, out = "No sha256sum check requested.")
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -49,7 +49,7 @@ internal class FilesystemKtTest {
|
||||||
val res4b = prov.fileContainsText(file, "some non-existing content")
|
val res4b = prov.fileContainsText(file, "some non-existing content")
|
||||||
val res5 = prov.deleteFile(file)
|
val res5 = prov.deleteFile(file)
|
||||||
val res6 = prov.fileExists(file)
|
val res6 = prov.fileExists(file)
|
||||||
val res7 = prov.deleteFile(file, true)
|
val res7 = prov.deleteFile(file, sudo = true)
|
||||||
val res8 = prov.fileExists(file)
|
val res8 = prov.fileExists(file)
|
||||||
|
|
||||||
// then
|
// then
|
||||||
|
|
|
@ -4,8 +4,8 @@ import org.domaindrivenarchitecture.provs.test.defaultTestContainer
|
||||||
import org.domaindrivenarchitecture.provs.test.tags.ContainerTest
|
import org.domaindrivenarchitecture.provs.test.tags.ContainerTest
|
||||||
import org.domaindrivenarchitecture.provs.ubuntu.filesystem.base.createFile
|
import org.domaindrivenarchitecture.provs.ubuntu.filesystem.base.createFile
|
||||||
import org.domaindrivenarchitecture.provs.ubuntu.filesystem.base.fileContent
|
import org.domaindrivenarchitecture.provs.ubuntu.filesystem.base.fileContent
|
||||||
import org.junit.jupiter.api.Assertions.assertEquals
|
import org.domaindrivenarchitecture.provs.ubuntu.filesystem.base.fileExists
|
||||||
import org.junit.jupiter.api.Assertions.assertTrue
|
import org.junit.jupiter.api.Assertions.*
|
||||||
import org.junit.jupiter.api.Test
|
import org.junit.jupiter.api.Test
|
||||||
|
|
||||||
internal class WebKtTest {
|
internal class WebKtTest {
|
||||||
|
@ -27,4 +27,42 @@ internal class WebKtTest {
|
||||||
assertTrue(res.success)
|
assertTrue(res.success)
|
||||||
assertEquals("hello", res2)
|
assertEquals("hello", res2)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ContainerTest
|
||||||
|
@Test
|
||||||
|
fun downloadFromURL_local_file_with_correct_checksum() {
|
||||||
|
// given
|
||||||
|
val a = defaultTestContainer()
|
||||||
|
val srcFile = "file3.txt"
|
||||||
|
val targetFile = "file3b.txt"
|
||||||
|
a.createFile("/tmp/" + srcFile, "hello")
|
||||||
|
|
||||||
|
// when
|
||||||
|
val res = a.downloadFromURL("file:///tmp/" + srcFile, targetFile, "tmp", sha256sum ="2cf24dba5fb0a30e26e83b2ac5b9e29e1b161e5c1fa7425e73043362938b9824") // ubuntu 20.04 sha256sum version 8.30
|
||||||
|
|
||||||
|
// then
|
||||||
|
val res2 = a.fileContent("tmp/$targetFile")
|
||||||
|
|
||||||
|
assertEquals("hello", res2)
|
||||||
|
assertTrue(res.success)
|
||||||
|
}
|
||||||
|
|
||||||
|
@ContainerTest
|
||||||
|
@Test
|
||||||
|
fun downloadFromURL_local_file_with_incorrect_checksum() {
|
||||||
|
// given
|
||||||
|
val a = defaultTestContainer()
|
||||||
|
val srcFile = "file3.txt"
|
||||||
|
val targetFile = "file3b.txt"
|
||||||
|
a.createFile("/tmp/" + srcFile, "hello")
|
||||||
|
|
||||||
|
// when
|
||||||
|
val res = a.downloadFromURL("file:///tmp/" + srcFile, targetFile, "tmp", sha256sum = "2cf24dba5fb0a30e26e83b2ac5b9e29e1b161e5c1fa7425e73043362938b9824WRONG")
|
||||||
|
|
||||||
|
// then
|
||||||
|
val res2 = a.fileExists("tmp/$targetFile")
|
||||||
|
|
||||||
|
assertFalse(res.success)
|
||||||
|
assertFalse(res2)
|
||||||
|
}
|
||||||
}
|
}
|
Loading…
Reference in a new issue