#' Retrieve the Docker image for Splash #' #' @md #' @param tag Splash Docker image tag to install #' @return a `docker_image` object or `NULL` if an error occurred. #' @export #' @family splash_docker_helpers #' @examples \dontrun{ #' install_splash() #' splash_container <- start_splash() #' stop_splash(splash_container) #' } install_splash <- function(tag="latest") { docker <- stevedore::docker_client() tryCatch( docker$image$pull("scrapinghub/splash", tag=tag, stream=stdout()), error = function(e) { message("Error pulling image from DockerHub.\n", e) return(NULL) }, interrupt = function(e) { stop("Terminated by user", call. = FALSE) } ) -> res invisible(res) } #' Start a Splash server Docker container #' #' If using this in an automation context, you should consider adding a #' `Sys.sleep(3)` (or higher) after starting the docker container. #' #' This uses the `latest` image and passed the `--disable-browser-caches` #' parameter. If you do not want to use the 3.2.x+ versions of `Splash` #' you should use your own startup scripts vs this helper function. #' #' @param tag Splash Docker image tag to start #' @note you need Docker running on your system and have pulled the container with #' [install_splash] for this to work. You should save the resultant #' object for use in [stop_splash] otherwise you'll have to kill it from the #' command line interface. #' @param container_name naem for the container. Defaults to "`splashr`". #' @param remove remove the Splash container instance after it's stopped? #' Defaults to `FALSE`. #' @param ... passed on to Splash instance launch parameters #' @family splash_docker_helpers #' @return `stevedore` container object #' @export #' @examples \dontrun{ #' install_splash() #' splash_container <- start_splash() #' stop_splash(splash_container) #' } start_splash <- function(tag="latest", container_name = "splashr", remove=FALSE, ...) { docker <- stevedore::docker_client() tryCatch( docker$container$run( image = sprintf("scrapinghub/splash:%s", tag), name = container_name, ports = c("5023:5023", "8051:8051", "8050:8050"), detach = TRUE, rm = remove, tty = TRUE, "--disable-browser-caches", ... ), error = function(e) { message("Error pulling image from DockerHub.") return(NULL) }, interrupt = function(e) { stop("Terminated by user", call. = FALSE) } ) -> splash_inst invisible(splash_inst) } #' Stop a running a Splash server Docker container #' #' @param splash_container Docker `container` object created by [start_splash()] #' @note you need Docker running on your system and have pulled the container with #' [install_splash()] and started the Splash container with [start_splash()] for this #' to work. You will need the `container` object from [start_splash()] for this to work. #' @family splash_docker_helpers #' @export #' @examples \dontrun{ #' install_splash() #' splash_container <- start_splash() #' stop_splash(splash_container) #' } stop_splash <- function(splash_container) { if (inherits(splash_container, "stevedore_object")) { splash_container$stop() splash_container$remove() } invisible(NULL) } #' Prune all dead and running Splash Docker containers #' #' _This is a destructive function._ It will stop **any** Docker container that #' is based on an image matching "`scrapinghub/splashr`". It's best used when you #' had a session forcefully interuppted and had been using the R helper functions #' to start/stop the Splash Docker container. You may want to consider using the #' Docker command-line interface to perform this work manually. #' #' @export killall_splash <- function() { docker <- stevedore::docker_client() x <- docker$container$list(all=TRUE) for (i in 1:nrow(x)) { if (length(x$command[i])) { if (grepl("bin/splash", x$command[i])) { message(sprintf("Pruning: %s...", x$id[i])) if (x$state[i] == "running") { cntnr <- docker$container$get(x$id[i]) cntnr$stop() cntnr$remove() } } } } } # @param add_tempdir This is `FALSE` initially since you could try to run # the splash image on a remote system. It has to be a local one for this to work. # If `TRUE` then a local temporary directory (made with [tempdir()]) # will be added to the mount configuration for use with [render_file()]. You will need to # ensure the necessary system temp dirs are accessible as a mounts. For # macOS this means adding `/private` to said Docker config.