Open The-Dub opened 7 years ago
Definitely not against switching to R6 (I was initially just trying to "get'er done").
An S3 class is always the path of least resistance but right now I can see a few different flavors of harbor
:
ssh
/ command-linessh
tunnel to HTTP APIThose could be crammed into S3 but R6 might make sense. We'd just need to design the base class to support all that (and anything others can come up with).
I'm learning about dockers, but I can clearly see why they are so powerful. I feel like localhost is the easiest, and probably should be implemented first, as a "solid base"
One problem might be being cross platform, to please the windows people...
Some possible beginnings of underpinnings for querying the API directly below. Needs a source build of curl
on macOS and those environment variables set.
library(curl)
library(jsonlite)
library(openssl)
docker_auth <- function(username=Sys.getenv("DOCKER_USERNAME"),
password=Sys.getenv("DOCKER_PASSWORD"),
email=Sys.getenv("DOCKER_EMAIL"),
server_address=Sys.getenv("DOCKER_REGISTRY"),
encode=TRUE) {
toJSON(
list(
username=unbox(username),
password=unbox(password),
email=unbox(email),
auth=unbox(""),
serveraddress=unbox(server_address)
)
) -> auth_json
if (encode) auth_json <- openssl::base64_encode(auth_json)
auth_json
}
docker_handle <- function(verbose=FALSE) {
h <- curl::new_handle()
h <- curl::handle_reset(h)
h <- curl::handle_setopt(h, UNIX_SOCKET_PATH = "/var/run/docker.sock")
h <- curl::handle_setopt(h, VERBOSE = verbose)
h <- curl::handle_setheaders(h,
`Content-Type` = "application/json",
`X-Registry-Auth` = docker_auth())
h
}
# Auth check ------------------------------------------------------------------------
h <- docker_handle(TRUE)
handle_setopt(h, copypostfields = docker_auth(encode=FALSE))
res <- curl_fetch_memory(url = "http://v1.26/auth", handle = h)
str(fromJSON(rawToChar(res$content)))
# Docker info -----------------------------------------------------------------------
h <- docker_handle()
res <- curl_fetch_memory(url = "http://v1.26/info", handle = h)
str(fromJSON(rawToChar(res$content)))
# Docker version --------------------------------------------------------------------
h <- docker_handle()
res <- curl_fetch_memory(url = "http://v1.26/version", handle = h)
str(fromJSON(rawToChar(res$content)))
# Docker ping -----------------------------------------------------------------------
h <- docker_handle()
res <- curl_fetch_memory(url = "http://v1.26/_ping", handle = h)
cat(rawToChar(res$content))
# Data usage ------------------------------------------------------------------------
h <- docker_handle()
res <- curl_fetch_memory(url = "http://v1.26/system/df", handle = h)
str(fromJSON(rawToChar(res$content)))
# List images -----------------------------------------------------------------------
h <- docker_handle()
res <- curl_fetch_memory(url = "http://v1.26/images/json", handle = h)
str(fromJSON(rawToChar(res$content)))
# Search images ---------------------------------------------------------------------
h <- docker_handle()
res <- curl_fetch_memory(url = "http://v1.26/images/search?term=alpine&limit=10", handle = h)
str(fromJSON(rawToChar(res$content)))
# Pull an image ---------------------------------------------------
h <- docker_handle(verbose = TRUE)
handle_setopt(h, copypostfields = '')
res <- curl_fetch_memory(url = "http://v1.26/images/create?fromImage=alpine&tag=latest", handle = h)
cat(rawToChar(res$content))
# List running containers -----------------------------------------------------------
h <- docker_handle()
res <- curl_fetch_memory(url = "http://v1.26/containers/json", handle = h)
str(fromJSON(rawToChar(res$content)))
# all: true/false
# limit: int
# size: true/false
# filters: json
h <- docker_handle()
res <- curl_fetch_memory(url = "http://v1.26/containers/json", handle = h)
str(fromJSON(rawToChar(res$content)))
# Inspect a container ---------------------------------------------------------------
# size: true/false
h <- docker_handle(verbose = TRUE)
res <- curl_fetch_memory(url = "http://v1.26/containers/b834259b9e9ed70cd00a43c9a539ab0601dab68a5966e531fea76ec91bc76940/json", handle = h)
str(fromJSON(rawToChar(res$content)))
# List container processes ----------------------------------------------------------
# ps_args: string
h <- docker_handle(verbose = TRUE)
res <- curl_fetch_memory(url = "http://v1.26/containers/b834259b9e9ed70cd00a43c9a539ab0601dab68a5966e531fea76ec91bc76940/top", handle = h)
str(fromJSON(rawToChar(res$content)))
# Get container logs ----------------------------------------------------------------
# follow: true/false
# stdout: t/f
# stderr: r/f
# since: int
# timestamps: t/f
# tail: string
h <- docker_handle(verbose = TRUE)
res <- curl_fetch_memory(url = "http://v1.26/containers/b834259b9e9ed70cd00a43c9a539ab0601dab68a5966e531fea76ec91bc76940/logs?stdout=true&stderr=true", handle = h)
cat(rawToChar(res$content[res$content > 0x09]))
# Run a container -------------------------------------------------------------------
h <- docker_handle()
handle_setopt(h, copypostfields = '{"Image": "alpine", "Cmd": ["echo", "hello world"]}')
res <- curl_fetch_memory(url = "http:/v1.26/containers/create", handle = h)
str(fromJSON(rawToChar(res$content)))
Moving API discussion to #11
I was looking at the source code of harbor to figure out why splashr wasn't working and - I don't know if it's a good idea or not, but throwing it out there - I was wondering if it would be easier for debug & sanity check within functions to use R6 classes?
The structure for opening a docker would be something like
boat <- harbor$new('NameOfTheDocker')
Other packages (let's say harbor) having dependency on harbor would also be R6 class being sub-class of the
harbor
class, for example:I forked the repo and will try to get a crack at it tonight, but if @hrbrmstr think it's a bad idea, I'll just let it go :) !
Cheers