From ac8ca2ea963983989981e0a1e78fb694c13afe44 Mon Sep 17 00:00:00 2001 From: chainsawriot Date: Tue, 18 Apr 2023 15:31:42 +0200 Subject: [PATCH] Add `.normalize_docker_steps` ref #133 --- R/dockerfile.R | 16 +++++++-- R/memo_misc.R | 10 +++--- data/recipes.rda | Bin 428 -> 424 bytes tests/testthat/test_apptainerize.R | 9 +++++ tests/testthat/test_dockerize.R | 53 +++++++++++++++++++---------- 5 files changed, 63 insertions(+), 25 deletions(-) diff --git a/R/dockerfile.R b/R/dockerfile.R index d2be369..4a0ab3f 100644 --- a/R/dockerfile.R +++ b/R/dockerfile.R @@ -1,3 +1,15 @@ +## for normalizing post_installation_steps +.normalize_docker_steps <- function(steps) { + fx <- function(step) { + docker_regex <- "^#|^ADD |^COPY |^ENV |^EXPOSE |^FROM |^LABEL |^STOPSIGNAL |^USER |^VOLUME |^WORKDIR |^ONBUILD |^RUN |^CMD |^ENTRYPOINT |^ARG |^HEALTHCHECK |^SHELL " + splitted_step <- strsplit(step, "\n")[[1]] + docker_line_lgl <- grepl(docker_regex, splitted_step) + splitted_step[!docker_line_lgl] <- paste0("RUN ", splitted_step[!docker_line_lgl]) + paste0(splitted_step, collapse = "\n") + } + vapply(steps, fx, character(1), USE.NAMES = FALSE) +} + .generate_debian_eol_dockerfile_content <- function(r_version, lib, sysreqs_cmd, cache, debian_version = "lenny", post_installation_steps = NULL, rel_dir = "", @@ -24,7 +36,7 @@ containerfile_content$FROM <- c("FROM scratch", paste0("ADD ", file.path(rel_dir, "cache/debian/rootfs.tar.xz"), " /")) containerfile_content$ENV <- append(containerfile_content$ENV, paste0("ENV CACHE_PATH ", cache_path)) } - containerfile_content$RUN <- append(containerfile_content$RUN, post_installation_steps) + containerfile_content$RUN <- append(containerfile_content$RUN, .normalize_docker_steps(post_installation_steps)) if (isTRUE(copy_all)) { containerfile_content$COPY <- c("COPY . /") } @@ -55,7 +67,7 @@ if (image == "rstudio") { containerfile_content$CMD <- c("EXPOSE 8787", "CMD [\"/init\"]") } - containerfile_content$RUN <- append(containerfile_content$RUN, post_installation_steps) + containerfile_content$RUN <- append(containerfile_content$RUN, .normalize_docker_steps(post_installation_steps)) if (isTRUE(copy_all)) { containerfile_content$COPY <- c("COPY . /") } diff --git a/R/memo_misc.R b/R/memo_misc.R index 852a670..6261015 100644 --- a/R/memo_misc.R +++ b/R/memo_misc.R @@ -64,11 +64,11 @@ NULL ## data generation ## --- ## recipes <- list() -## recipes["texlive"] <- "## install texlive\nRUN apt-get install -y pandoc pandoc-citeproc texlive" -## recipes["texlivefull"] <- "## install texlive-full\nRUN apt-get install -y pandoc pandoc-citeproc texlive-full" -## recipes["quarto"] <- "## install quarto (latest)\nRUN apt-get install -y curl git && curl -LO https://quarto.org/download/latest/quarto-linux-amd64.deb && dpkg -i quarto-linux-amd64.deb && quarto install tool tinytex && rm quarto-linux-amd64.deb" -## recipes["clean"] <- "## Clean up caches\nRUN rm -rf /var/lib/apt/lists/* && if [ -d \"$CACHE_PATH\" ]; then rm -rf $CACHE_PATH; fi" -## recipes["make"] <- "## install GNU make\nRUN apt-get -y install make" +## recipes["texlive"] <- "## install texlive\napt-get install -y pandoc pandoc-citeproc texlive" +## recipes["texlivefull"] <- "## install texlive-full\napt-get install -y pandoc pandoc-citeproc texlive-full" +## recipes["quarto"] <- "## install quarto (latest)\napt-get install -y curl git && curl -LO https://quarto.org/download/latest/quarto-linux-amd64.deb && dpkg -i quarto-linux-amd64.deb && quarto install tool tinytex && rm quarto-linux-amd64.deb" +## recipes["clean"] <- "## Clean up caches\nrm -rf /var/lib/apt/lists/* && if [ -d \"$CACHE_PATH\" ]; then rm -rf $CACHE_PATH; fi" +## recipes["make"] <- "## install GNU make\napt-get -y install make" ## usethis::use_data(recipes, overwrite = TRUE) #' Recipes for Building Container Images diff --git a/data/recipes.rda b/data/recipes.rda index af2554670009db3c6ee6e003d9cd08eb678d5fab..9d708a571e3df3c9b61eb3ef6cf87c3b3a3c5472 100644 GIT binary patch literal 424 zcmV;Z0ayM)T4*^jL0KkKS-izp3;+PFe}ezGNB~`Xl^8C?)=Izc|KI=+00A%ocC%;= zDWrOudVtUX+Mb9206jz0F#rt&B+Qa}jiE42HlczvVF#&^iHHJ8LZ6~N1wBvFhK)4S zAOO$-paz~uf#f7?kYWP%lh04S_Yi0Fpav=t5j_5O%^AKVAmK9sSSCUkVVWV51G_7+ zHR>FczM20ak*%)(pTE#rh9jX8kFM|2@^vd2M&l`6@WH$+Qqg@{(>NGqIbcEEAC}6p zrx0irJ;`p-It-w24P2T9yo~=FsejzDJs4I;Bw34~?iLskS{DOx2M1Hb6k&4$nFP@o zQgfBE0)b?J>j#GI*Co<9W}H=Ml5^HVDJohOK|`ptW@SOZu`lG|^Qw%1854zT@aL>` zT!1nwDW#JrAY|5~&>&VSVpo_MgJG?*T(M4@Ft*dsV0!q~Bt#nv2Az~E60Zq-ViImg zOyM+hj(R_wt7eYa6TEgdz)F+TAd^0A?I~kgn2ME@iWR{y StOsOY;_gVN3KAEXs^NeFytsn^ literal 428 zcmV;d0aN}$T4*^jL0KkKS;xqf5dZ+Pe}ezGNB~`Pl^8C?)=Izs|KI=t00A%ocC%>1 zD5DXRY7I02kN^Mx&}0UKL?@{pQ_^ZZOaU390{{RJVWJ5nhNh>QnvYY;G%_^x00Yzj zG6AQQC^&;)Z3ZY7rsvDI^$0V&zzkZ5h@5d5AV;Y>2hSw`W+G zLIH7v)hY?L76C4l1GuKu&JVqB;~`C8;#VxuhoJB{hyyiP35CQ;5MU$3F$OqvA+d=> zNQFWo%)JXD3Rf=qXlVvp?@Oe5wgSPTIn2?Hj)kF64@b-l%$_|<;d4kGBGx{DG9(f@ zKNEZk0f|Xk*+pRtq>w6lT$ diff --git a/tests/testthat/test_apptainerize.R b/tests/testthat/test_apptainerize.R index f1f95d6..4790f6e 100644 --- a/tests/testthat/test_apptainerize.R +++ b/tests/testthat/test_apptainerize.R @@ -309,3 +309,12 @@ test_that(".insert_materials_dir with actual outcome", { expect_identical(names(.insert_materials_dir(container_content, verb = "apptainerize/singularize")), "FILES") expect_false(names(.insert_materials_dir(container_content, verb = "apptainerize/singularize")) %in% "COPY") }) + +test_that("No .normalize_docker_steps integration in apptainerize", { + graph <- readRDS("../testdata/graph.RDS") + temp_dir <- .generate_temp_dir() + apptainerize(graph, output_dir = temp_dir, post_installation_steps = c(recipes[["texlive"]], "RUN apt-get install -y make")) + def_file <- readLines(file.path(temp_dir, "container.def")) + expect_true("RUN apt-get install -y make" %in% def_file) ## you ask for it + expect_false("RUN apt-get install -y pandoc pandoc-citeproc texlive" %in% def_file) +}) diff --git a/tests/testthat/test_dockerize.R b/tests/testthat/test_dockerize.R index 71dbaea..479ce1f 100644 --- a/tests/testthat/test_dockerize.R +++ b/tests/testthat/test_dockerize.R @@ -317,25 +317,42 @@ test_that("dockerize with inst/rang", { expect_true("ENV RANG_PATH inst/rang/rang.R" %in% dockerfile) }) +test_that(".normalize_docker_steps", { + expect_equal(.normalize_docker_steps("RUN apt-get install -y pandoc"), "RUN apt-get install -y pandoc") + expect_equal(.normalize_docker_steps("apt-get install -y pandoc"), "RUN apt-get install -y pandoc") + expect_equal(.normalize_docker_steps(c("apt-get install -y pandoc", "RUN apt-get install -y pandoc")), + rep("RUN apt-get install -y pandoc", 2)) + expect_equal(.normalize_docker_steps(recipes[["quarto"]]), "## install quarto (latest)\nRUN apt-get install -y curl git && curl -LO https://quarto.org/download/latest/quarto-linux-amd64.deb && dpkg -i quarto-linux-amd64.deb && quarto install tool tinytex && rm quarto-linux-amd64.deb") +}) + +test_that(".normalize_docker_steps integration", { + graph <- readRDS("../testdata/graph.RDS") + temp_dir <- .generate_temp_dir() + dockerize(graph, output_dir = temp_dir, post_installation_steps = c(recipes[["texlive"]], "RUN apt-get install -y make")) + dockerfile <- readLines(file.path(temp_dir, "Dockerfile")) + expect_true("RUN apt-get install -y make" %in% dockerfile) + expect_true("RUN apt-get install -y pandoc pandoc-citeproc texlive" %in% dockerfile) +}) + test_that(".generate_wrapped_line", { - graph <- readRDS("../testdata/graph.RDS") - temp_dir <- .generate_temp_dir() - dockerize(graph, output_dir = temp_dir) - Dockerfile <- readLines(file.path(temp_dir, "Dockerfile")) - expect_equal(max(lengths(regmatches(Dockerfile, gregexpr("&&", Dockerfile)))), 1) - expect_true(all(grepl("^\t&&", Dockerfile[grepl("&&", Dockerfile)]))) - graph <- readRDS("../testdata/rang_bioc.RDS") - temp_dir <- .generate_temp_dir() - dockerize(graph, output_dir = temp_dir) - Dockerfile <- readLines(file.path(temp_dir, "Dockerfile")) - expect_equal(max(lengths(regmatches(Dockerfile, gregexpr("&&", Dockerfile)))), 1) - expect_true(all(grepl("^\t&&", Dockerfile[grepl("&&", Dockerfile)]))) - graph <- readRDS("../testdata/rang_rio_old.RDS") - temp_dir <- .generate_temp_dir() - dockerize(graph, output_dir = temp_dir) - Dockerfile <- readLines(file.path(temp_dir, "Dockerfile")) - expect_equal(max(lengths(regmatches(Dockerfile, gregexpr("&&", Dockerfile)))), 1) - expect_true(all(grepl("^\t&&", Dockerfile[grepl("&&", Dockerfile)]))) + graph <- readRDS("../testdata/graph.RDS") + temp_dir <- .generate_temp_dir() + dockerize(graph, output_dir = temp_dir) + Dockerfile <- readLines(file.path(temp_dir, "Dockerfile")) + expect_equal(max(lengths(regmatches(Dockerfile, gregexpr("&&", Dockerfile)))), 1) + expect_true(all(grepl("^\t&&", Dockerfile[grepl("&&", Dockerfile)]))) + graph <- readRDS("../testdata/rang_bioc.RDS") + temp_dir <- .generate_temp_dir() + dockerize(graph, output_dir = temp_dir) + Dockerfile <- readLines(file.path(temp_dir, "Dockerfile")) + expect_equal(max(lengths(regmatches(Dockerfile, gregexpr("&&", Dockerfile)))), 1) + expect_true(all(grepl("^\t&&", Dockerfile[grepl("&&", Dockerfile)]))) + graph <- readRDS("../testdata/rang_rio_old.RDS") + temp_dir <- .generate_temp_dir() + dockerize(graph, output_dir = temp_dir) + Dockerfile <- readLines(file.path(temp_dir, "Dockerfile")) + expect_equal(max(lengths(regmatches(Dockerfile, gregexpr("&&", Dockerfile)))), 1) + expect_true(all(grepl("^\t&&", Dockerfile[grepl("&&", Dockerfile)]))) }) test_that(".generate_wrapped_line with actual outcome", {