Dev (#14)
* vignette tweak * bump ver no * tool tests * pass cmd args as processx::run expects * update news
This commit is contained in:
Родитель
c69fd4f087
Коммит
b9cbbdd262
|
@ -1,6 +1,6 @@
|
|||
Package: AzureContainers
|
||||
Title: Interface to 'Container Instances', 'Docker Registry' and 'Kubernetes' in 'Azure'
|
||||
Version: 1.2.1.9000
|
||||
Version: 1.3.0
|
||||
Authors@R: c(
|
||||
person("Hong", "Ooi", , "hongooi@microsoft.com", role = c("aut", "cre")),
|
||||
person("Bill", "Liang", role = "ctb", comment = "Assistance debugging MMLS on Kubernetes"),
|
||||
|
|
3
NEWS.md
3
NEWS.md
|
@ -1,4 +1,4 @@
|
|||
# AzureContainers 1.2.1.9000
|
||||
# AzureContainers 1.3.0
|
||||
|
||||
- Significant enhancements for AKS:
|
||||
- Fully support creating clusters with managed identities. This is recommended and the new default, compared to the older method of using service principals to control cluster resources.
|
||||
|
@ -11,6 +11,7 @@
|
|||
- The functions to call external tools (`call_docker`, `call_docker_compose`, `call_kubernetes` and `call_helm`) now use the value of the system option `azure_containers_tool_echo` to determine whether to echo output to the screen. If this is unset, the fallback is `TRUE` (as in previous versions).
|
||||
- Remove MMLS vignette; version 9.3.0 is now very old.
|
||||
- New vignettes on securing an ACI deployment with RestRserve, and deploying a secured service on AKS with Traefik/Let's Encrypt.
|
||||
- The utility functions `call_docker`, `call_docker_compose`, `call_kubectl` and `call_helm` now accept a vector of individual commandline options as the first argument, which is the format expected by `processx::run`. You can still provide the full commandline as a single string but this is discouraged, as it will likely fail for things like paths containing spaces.
|
||||
|
||||
# AzureContainers 1.2.1
|
||||
|
||||
|
|
|
@ -1,12 +1,14 @@
|
|||
#' Call the docker commandline tool
|
||||
#'
|
||||
#' @param cmd The docker command line to execute.
|
||||
#' @param cmd The docker command. This should be a _vector_ of individual docker arguments, but can also be a single commandline string. See below.
|
||||
#' @param echo Whether to echo the output of the command to the console.
|
||||
#' @param ... Other arguments to pass to [processx::run].
|
||||
#'
|
||||
#' @details
|
||||
#' This function calls the `docker` binary, which must be located in your search path. AzureContainers will search for the binary at package startup, and print a warning if it is not found.
|
||||
|
||||
#'
|
||||
#' The docker command should be specified as a vector of the individual arguments, which is what `processx::run` expects. If a single string is passed, for convenience and back-compatibility reasons `call_docker` will split it into arguments for you. This is prone to error, for example if you are working with pathnames that contain spaces, so it's strongly recommended to pass a vector of arguments as a general practice.
|
||||
#'
|
||||
#' @return
|
||||
#' A list with the following components:
|
||||
#' - `status`: The exit status of the docker tool. If this is `NA`, then the process was killed and had no exit status.
|
||||
|
@ -30,15 +32,18 @@
|
|||
#' # without any args, prints the docker help screen
|
||||
#' call_docker()
|
||||
#'
|
||||
#' # build an image
|
||||
#' # build an image: recommended usage
|
||||
#' call_docker(c("build", "-t", "myimage", ""."))
|
||||
#'
|
||||
#' # alternative usage, will be split into individual arguments
|
||||
#' call_docker("build -t myimage .")
|
||||
#'
|
||||
#' # list running containers
|
||||
#' call_docker("container ls")
|
||||
#' call_docker(c("container", "ls"))
|
||||
#'
|
||||
#' # prune unused containers and images
|
||||
#' call_docker("container prune -f")
|
||||
#' call_docker("image prune -f")
|
||||
#' call_docker(c("container", "prune", "-f"))
|
||||
#' call_docker(c("image", "prune", "-f"))
|
||||
#'
|
||||
#' }
|
||||
#' @export
|
||||
|
@ -46,13 +51,15 @@ call_docker <- function(cmd="", ..., echo=getOption("azure_containers_tool_echo"
|
|||
{
|
||||
if(.AzureContainers$docker == "")
|
||||
stop("docker binary not found", call.=FALSE)
|
||||
message("Docker operation: ", cmd)
|
||||
|
||||
if(length(cmd) == 1 && grepl(" ", cmd, fixed=TRUE))
|
||||
cmd <- strsplit(cmd, "\\s+")[[1]]
|
||||
|
||||
win <- .Platform$OS.type == "windows"
|
||||
if(!win)
|
||||
{
|
||||
dockercmd <- "sudo"
|
||||
realcmd <- paste(.AzureContainers$docker, cmd)
|
||||
realcmd <- c(.AzureContainers$docker, cmd)
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -61,21 +68,23 @@ call_docker <- function(cmd="", ..., echo=getOption("azure_containers_tool_echo"
|
|||
}
|
||||
|
||||
echo <- as.logical(echo)
|
||||
val <- processx::run(dockercmd, strsplit(realcmd, " ", fixed=TRUE)[[1]], ..., echo=echo)
|
||||
val$cmdline <- paste("docker", cmd)
|
||||
val <- processx::run(dockercmd, realcmd, ..., echo=echo)
|
||||
val$cmdline <- paste("docker", paste(realcmd, collapse=" "))
|
||||
invisible(val)
|
||||
}
|
||||
|
||||
|
||||
#' Call the docker-compose commandline tool
|
||||
#'
|
||||
#' @param cmd The docker-compose command line to execute.
|
||||
#' @param cmd The docker-compose command line to execute. This should be a _vector_ of individual docker-compose arguments, but can also be a single commandline string. See below.
|
||||
#' @param echo Whether to echo the output of the command to the console.
|
||||
#' @param ... Other arguments to pass to [processx::run].
|
||||
#'
|
||||
#' @details
|
||||
#' This function calls the `docker-compose` binary, which must be located in your search path. AzureContainers will search for the binary at package startup, and print a warning if it is not found.
|
||||
|
||||
#'
|
||||
#' The docker-compose command should be specified as a vector of the individual arguments, which is what `processx::run` expects. If a single string is passed, for convenience and back-compatibility reasons `call_docker_compose` will split it into arguments for you. This is prone to error, for example if you are working with pathnames that contain spaces, so it's strongly recommended to pass a vector of arguments as a general practice.
|
||||
#'
|
||||
#' @return
|
||||
#' A list with the following components:
|
||||
#' - `status`: The exit status of the docker-compose tool. If this is `NA`, then the process was killed and had no exit status.
|
||||
|
@ -97,13 +106,15 @@ call_docker_compose <- function(cmd="", ..., echo=getOption("azure_containers_to
|
|||
{
|
||||
if(.AzureContainers$dockercompose == "")
|
||||
stop("docker-compose binary not found", call.=FALSE)
|
||||
message("Docker-compose operation: ", cmd)
|
||||
|
||||
if(length(cmd) == 1 && grepl(" ", cmd, fixed=TRUE))
|
||||
cmd <- strsplit(cmd, "\\s+")[[1]]
|
||||
|
||||
win <- .Platform$OS.type == "windows"
|
||||
if(!win)
|
||||
{
|
||||
dcmpcmd <- "sudo"
|
||||
realcmd <- paste(.AzureContainers$dockercompose, cmd)
|
||||
realcmd <- c(.AzureContainers$dockercompose, cmd)
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -112,22 +123,24 @@ call_docker_compose <- function(cmd="", ..., echo=getOption("azure_containers_to
|
|||
}
|
||||
|
||||
echo <- as.logical(echo)
|
||||
val <- processx::run(dcmpcmd, strsplit(realcmd, " ", fixed=TRUE)[[1]], ..., echo=echo)
|
||||
val$cmdline <- paste("docker-compose", cmd)
|
||||
val <- processx::run(dcmpcmd, realcmd, ..., echo=echo)
|
||||
val$cmdline <- paste("docker-compose", paste(realcmd, collapse=" "))
|
||||
invisible(val)
|
||||
}
|
||||
|
||||
|
||||
#' Call the Kubernetes commandline tool, kubectl
|
||||
#'
|
||||
#' @param cmd The kubectl command line to execute.
|
||||
#' @param cmd The kubectl command line to execute. This should be a _vector_ of individual kubectl arguments, but can also be a single commandline string. See below.
|
||||
#' @param echo Whether to echo the output of the command to the console.
|
||||
#' @param config The pathname of the cluster config file, if required.
|
||||
#' @param ... Other arguments to pass to [processx::run].
|
||||
#'
|
||||
#' @details
|
||||
#' This function calls the `kubectl` binary, which must be located in your search path. AzureContainers will search for the binary at package startup, and print a warning if it is not found.
|
||||
|
||||
#'
|
||||
#' The kubectl command should be specified as a vector of the individual arguments, which is what `processx::run` expects. If a single string is passed, for convenience and back-compatibility reasons `call_docker_compose` will split it into arguments for you. This is prone to error, for example if you are working with pathnames that contain spaces, so it's strongly recommended to pass a vector of arguments as a general practice.
|
||||
#'
|
||||
#' @return
|
||||
#' A list with the following components:
|
||||
#' - `status`: The exit status of the kubectl tool. If this is `NA`, then the process was killed and had no exit status.
|
||||
|
@ -170,25 +183,29 @@ call_kubectl <- function(cmd="", config=NULL, ..., echo=getOption("azure_contain
|
|||
|
||||
if(!is.null(config))
|
||||
config <- paste0("--kubeconfig=", config)
|
||||
message("Kubernetes operation: ", cmd, " ", config)
|
||||
|
||||
if(length(cmd) == 1 && grepl(" ", cmd, fixed=TRUE))
|
||||
cmd <- strsplit(cmd, "\\s+")[[1]]
|
||||
|
||||
echo <- as.logical(echo)
|
||||
val <- processx::run(.AzureContainers$kubectl, c(strsplit(cmd, " ", fixed=TRUE)[[1]], config), ..., echo=echo)
|
||||
val$cmdline <- paste("kubectl", cmd, config)
|
||||
val <- processx::run(.AzureContainers$kubectl, c(cmd, config), ..., echo=echo)
|
||||
val$cmdline <- paste("kubectl", paste(cmd, collapse=" "), config)
|
||||
invisible(val)
|
||||
}
|
||||
|
||||
|
||||
#' Call the Helm commandline tool
|
||||
#'
|
||||
#' @param cmd The Helm command line to execute.
|
||||
#' @param cmd The Helm command line to execute. This should be a _vector_ of individual helm arguments, but can also be a single commandline string. See below.
|
||||
#' @param echo Whether to echo the output of the command to the console.
|
||||
#' @param config The pathname of the cluster config file, if required.
|
||||
#' @param ... Other arguments to pass to [processx::run].
|
||||
#'
|
||||
#' @details
|
||||
#' This function calls the `helm` binary, which must be located in your search path. AzureContainers will search for the binary at package startup, and print a warning if it is not found.
|
||||
|
||||
#'
|
||||
#' The helm command should be specified as a vector of the individual arguments, which is what `processx::run` expects. If a single string is passed, for convenience and back-compatibility reasons `call_docker_compose` will split it into arguments for you. This is prone to error, for example if you are working with pathnames that contain spaces, so it's strongly recommended to pass a vector of arguments as a general practice.
|
||||
#'
|
||||
#' @return
|
||||
#' A list with the following components:
|
||||
#' - `status`: The exit status of the helm tool. If this is `NA`, then the process was killed and had no exit status.
|
||||
|
@ -214,11 +231,13 @@ call_helm <- function(cmd="", config=NULL, ..., echo=getOption("azure_containers
|
|||
|
||||
if(!is.null(config))
|
||||
config <- paste0("--kubeconfig=", config)
|
||||
message("Helm operation: ", cmd, " ", config)
|
||||
|
||||
if(length(cmd) == 1 && grepl(" ", cmd, fixed=TRUE))
|
||||
cmd <- strsplit(cmd, "\\s+")[[1]]
|
||||
|
||||
echo <- as.logical(echo)
|
||||
val <- processx::run(.AzureContainers$helm, c(strsplit(cmd, " ", fixed=TRUE)[[1]], config), ..., echo=echo)
|
||||
val$cmdline <- paste("helm", cmd, config)
|
||||
val <- processx::run(.AzureContainers$helm, c(cmd, config), ..., echo=echo)
|
||||
val$cmdline <- paste("helm", paste(cmd, collapse=" "), config)
|
||||
invisible(val)
|
||||
}
|
||||
|
||||
|
|
|
@ -8,7 +8,7 @@ call_docker(cmd = "", ..., echo = getOption("azure_containers_tool_echo",
|
|||
TRUE))
|
||||
}
|
||||
\arguments{
|
||||
\item{cmd}{The docker command line to execute.}
|
||||
\item{cmd}{The docker command. This should be a \emph{vector} of individual docker arguments, but can also be a single commandline string. See below.}
|
||||
|
||||
\item{...}{Other arguments to pass to \link[processx:run]{processx::run}.}
|
||||
|
||||
|
@ -31,24 +31,8 @@ Call the docker commandline tool
|
|||
}
|
||||
\details{
|
||||
This function calls the \code{docker} binary, which must be located in your search path. AzureContainers will search for the binary at package startup, and print a warning if it is not found.
|
||||
}
|
||||
\examples{
|
||||
\dontrun{
|
||||
|
||||
# without any args, prints the docker help screen
|
||||
call_docker()
|
||||
|
||||
# build an image
|
||||
call_docker("build -t myimage .")
|
||||
|
||||
# list running containers
|
||||
call_docker("container ls")
|
||||
|
||||
# prune unused containers and images
|
||||
call_docker("container prune -f")
|
||||
call_docker("image prune -f")
|
||||
|
||||
}
|
||||
The docker command should be specified as a vector of the individual arguments, which is what \code{processx::run} expects. If a single string is passed, for convenience and back-compatibility reasons \code{call_docker} will split it into arguments for you. This is prone to error, for example if you are working with pathnames that contain spaces, so it's strongly recommended to pass a vector of arguments as a general practice.
|
||||
}
|
||||
\seealso{
|
||||
\link[processx:run]{processx::run}, \link{call_docker_compose}, \link{call_kubectl} for the equivalent interface to the \code{kubectl} Kubernetes tool
|
||||
|
|
|
@ -8,7 +8,7 @@ call_docker_compose(cmd = "", ...,
|
|||
echo = getOption("azure_containers_tool_echo", TRUE))
|
||||
}
|
||||
\arguments{
|
||||
\item{cmd}{The docker-compose command line to execute.}
|
||||
\item{cmd}{The docker-compose command line to execute. This should be a \emph{vector} of individual docker-compose arguments, but can also be a single commandline string. See below.}
|
||||
|
||||
\item{...}{Other arguments to pass to \link[processx:run]{processx::run}.}
|
||||
|
||||
|
@ -31,6 +31,8 @@ Call the docker-compose commandline tool
|
|||
}
|
||||
\details{
|
||||
This function calls the \code{docker-compose} binary, which must be located in your search path. AzureContainers will search for the binary at package startup, and print a warning if it is not found.
|
||||
|
||||
The docker-compose command should be specified as a vector of the individual arguments, which is what \code{processx::run} expects. If a single string is passed, for convenience and back-compatibility reasons \code{call_docker_compose} will split it into arguments for you. This is prone to error, for example if you are working with pathnames that contain spaces, so it's strongly recommended to pass a vector of arguments as a general practice.
|
||||
}
|
||||
\seealso{
|
||||
\link[processx:run]{processx::run}, \link{call_docker}, \link{call_kubectl} for the equivalent interface to the \code{kubectl} Kubernetes tool
|
||||
|
|
|
@ -8,7 +8,7 @@ call_helm(cmd = "", config = NULL, ...,
|
|||
echo = getOption("azure_containers_tool_echo", TRUE))
|
||||
}
|
||||
\arguments{
|
||||
\item{cmd}{The Helm command line to execute.}
|
||||
\item{cmd}{The Helm command line to execute. This should be a \emph{vector} of individual helm arguments, but can also be a single commandline string. See below.}
|
||||
|
||||
\item{config}{The pathname of the cluster config file, if required.}
|
||||
|
||||
|
@ -33,6 +33,8 @@ Call the Helm commandline tool
|
|||
}
|
||||
\details{
|
||||
This function calls the \code{helm} binary, which must be located in your search path. AzureContainers will search for the binary at package startup, and print a warning if it is not found.
|
||||
|
||||
The helm command should be specified as a vector of the individual arguments, which is what \code{processx::run} expects. If a single string is passed, for convenience and back-compatibility reasons \code{call_docker_compose} will split it into arguments for you. This is prone to error, for example if you are working with pathnames that contain spaces, so it's strongly recommended to pass a vector of arguments as a general practice.
|
||||
}
|
||||
\seealso{
|
||||
\link[processx:run]{processx::run}, \link{call_docker}, \link{call_kubectl}
|
||||
|
|
|
@ -8,7 +8,7 @@ call_kubectl(cmd = "", config = NULL, ...,
|
|||
echo = getOption("azure_containers_tool_echo", TRUE))
|
||||
}
|
||||
\arguments{
|
||||
\item{cmd}{The kubectl command line to execute.}
|
||||
\item{cmd}{The kubectl command line to execute. This should be a \emph{vector} of individual kubectl arguments, but can also be a single commandline string. See below.}
|
||||
|
||||
\item{config}{The pathname of the cluster config file, if required.}
|
||||
|
||||
|
@ -33,6 +33,8 @@ Call the Kubernetes commandline tool, kubectl
|
|||
}
|
||||
\details{
|
||||
This function calls the \code{kubectl} binary, which must be located in your search path. AzureContainers will search for the binary at package startup, and print a warning if it is not found.
|
||||
|
||||
The kubectl command should be specified as a vector of the individual arguments, which is what \code{processx::run} expects. If a single string is passed, for convenience and back-compatibility reasons \code{call_docker_compose} will split it into arguments for you. This is prone to error, for example if you are working with pathnames that contain spaces, so it's strongly recommended to pass a vector of arguments as a general practice.
|
||||
}
|
||||
\examples{
|
||||
\dontrun{
|
||||
|
|
|
@ -0,0 +1,39 @@
|
|||
context("Tools interface")
|
||||
|
||||
if(.AzureContainers$docker == "" ||
|
||||
.AzureContainers$dockercompose == "" ||
|
||||
.AzureContainers$kubectl == "" ||
|
||||
.AzureContainers$helm == "")
|
||||
skip("Tests skipped: external tools not found")
|
||||
|
||||
test_that("Docker works",
|
||||
{
|
||||
cmd <- "--help"
|
||||
obj <- call_docker(cmd)
|
||||
expect_is(obj, "list")
|
||||
expect_identical(obj$cmdline, "docker --help")
|
||||
})
|
||||
|
||||
test_that("Docker compose works",
|
||||
{
|
||||
cmd <- "--help"
|
||||
obj <- call_docker_compose(cmd)
|
||||
expect_is(obj, "list")
|
||||
expect_identical(obj$cmdline, "docker-compose --help")
|
||||
})
|
||||
|
||||
test_that("Kubectl works",
|
||||
{
|
||||
cmd <- "--help"
|
||||
obj <- call_kubectl(cmd)
|
||||
expect_is(obj, "list")
|
||||
expect_identical(trimws(obj$cmdline), "kubectl --help")
|
||||
})
|
||||
|
||||
test_that("Helm works",
|
||||
{
|
||||
cmd <- "--help"
|
||||
obj <- call_helm(cmd)
|
||||
expect_is(obj, "list")
|
||||
expect_identical(trimws(obj$cmdline), "helm --help")
|
||||
})
|
|
@ -321,7 +321,5 @@ httr::content(response, simplifyVector=TRUE)
|
|||
|
||||
## Further comments
|
||||
|
||||
In this vignette, we've used Let's Encrypt to obtain a TLS certificate, as it is a convenient and free source of certificates. In a production setting you would generally use a certificate issued to your organisation.
|
||||
|
||||
Similarly, we've secured the predictive service with a single username and password. While we could add more users to the authentication file, a more flexible and scalable solution is to use a frontend service, such as [Azure API Management](https://azure.microsoft.com/services/api-management/), or a directory service like [Azure Active Directory](https://azure.microsoft.com/services/active-directory/). The specifics will typically be determined by your organisation's IT infrastructure, and are beyond the scope of this vignette.
|
||||
In this vignette, we've secured the predictive service with a single username and password. While we could add more users to the authentication file, a more flexible and scalable solution is to use a frontend service, such as [Azure API Management](https://azure.microsoft.com/services/api-management/), or a directory service like [Azure Active Directory](https://azure.microsoft.com/services/active-directory/). The specifics will typically be determined by your organisation's IT infrastructure, and are beyond the scope of this vignette.
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче