ro2_ui <- miniPage(
gadgetTitleBar("O2 Assistant", left = NULL),
miniTabstripPanel(
miniTabPanel(
"Login", icon = icon("user"),
miniContentPanel(
fillRow(flex = c(1, 1, 1, 1), height = "50px",
uiOutput("o2id"),
uiOutput("remote"),
uiOutput("local"),
uiOutput("execute")),
hr(),
h4("On your local machine:"),
h5("Login"), sendTermOutput("login"),
h5("Mount Folder"), sendTermOutput("mount"),
h5("Unmount Folder"), sendTermOutput("unmount")
)
),
miniTabPanel(
"Run", icon = icon("paper-plane"),
miniContentPanel(
fillRow(flex = c(1, 1, 1), height = "60px",
uiOutput("partition"),
uiOutput("duration"),
uiOutput("mem")),
fillRow(flex = c(1, 1, 1, 1, 1), height = "60px",
uiOutput("n"),
uiOutput("c"),
uiOutput("N"),
uiOutput("o"),
uiOutput("gpu")),
hr(),
h4("On O2 server:"),
h5("Interactive Session"),
sendTermOutput("run_int"),
tags$div(
h5("Batch Run", style = "float: left;"),
tags$div(
style = "float: right;",
shinyFilesButton("file", "Select Script", "Select batch script" , FALSE)
)
),
sendTermOutput("run_batch"),
actionButton("check_batch", "Check Batch Job Status", icon("chalkboard")),
hr(),
radioGroupButtons(
inputId = "module", label = "Module Related",
choices = c("Search possible modules" = "spider",
"List loaded modules" = "list",
"Save current setups" = "s",
"Restore saved setups" = "r")
),
sendTermOutput("run_module")
)
),
miniTabPanel(
"ssh-keygen", icon = icon("lock"),
miniContentPanel(
h4("On your local machine:"),
h5("1. Generate ssh RSA key"),
fillRow(
flex = c(6, 2), height = "70px",
tagList(
p("Follow instruction on the screen and create a set of ssh RSA keys (private & public)."),
p("Do not enter any passphrase for passwordless login. ")
),
div(style = "min-width: 160px;",
textInput("sshkey_file", "Enter sshkey file name", "id_rsa", width = "100%"))
),
sendTermOutput("run_sshkeygen"),
h5("2. Setup ssh key config file"),
p("Put something like below in ~/.ssh/config. Make changes to the last line if necessary."),
fillRow(
flex = c(7, 1), height = "100px",
verbatimTextOutput("sshkey_config"), uiOutput("sshkey_config_btn")
),
h5("3. Copy the ssh pub key file to the O2 server & login"),
sendTermOutput("run_sshkey_scp"),
sendTermOutput("run_ssh_login"),
hr(),
h4("On O2 server:"),
h5("4. Put pub key into authorized_keys file"),
fillRow(
flex = c(7, 1), height = "180px",
uiOutput("sshkey_auth"),
uiOutput("sshkey_auth_btn")
)
)
)
)
)
ro2_server <- function(input, output, session) {
observeEvent(input$done, {
invisible(stopApp())
})
# Login =====================================================================
if (file.exists("~/.o2meta")) {
init_meta <- readLines("~/.o2meta")
} else {
init_meta <- c("", "~", "~/o2_home")
}
if (length(rstudioapi::terminalList()) != 0) {
terms <- rstudioapi::terminalList()
term_caption <- sapply(terms, function(x){terminalContext(x)["caption"]})
if ("O2" %in% term_caption) {
term_id <- terms[term_caption == "O2"]
} else {
term_id <- rstudioapi::terminalCreate(caption = "O2")
}
} else {
term_id <- rstudioapi::terminalCreate()
}
rstudioapi::terminalActivate(term_id)
output$execute <- renderUI({
tags$div(
# actionButton("create_local", "Create Dir"),
style = "margin-top: 35px; ",
materialSwitch(
"exec", "Execute", value = T, status = "primary"
)
)
})
output$o2id <- renderUI({
textInput(
"o2id", "eCommons ID", value = init_meta[1], width = "95%"
)
})
output$remote <- renderUI({
textInput(
"remote", "Remote Folder", value = init_meta[2], width = "95%"
)
})
output$local <- renderUI({
textInput(
"local", "Local Folder", value = init_meta[3], width = "95%"
)
})
meta <- reactive({
req(input$remote)
if (input$remote == "~") {
remote <- paste0("/home/", input$o2id)
} else {
remote <- input$remote
}
c(input$o2id, remote, input$local, term_id)
})
observeEvent(meta(), writeLines(meta(), "~/.o2meta"))
meta_login <- reactive({
paste0("ssh ", input$o2id, "@o2.hms.harvard.edu")
})
code_exec <- reactive({input$exec})
callModule(sendTerm, "login", code = meta_login, term_id = term_id,
execute = code_exec)
meta_mount <- reactive({
if (Sys.info()[["sysname"]] == "Darwin") {
extra_options <- paste0(
",defer_permissions,noappledouble,negative_vncache,volname=",
basename(input$local)
)
} else {
extra_options <- ""
}
paste0("sshfs -p 22 ", input$o2id, "@o2.hms.harvard.edu:",
meta()[2], " ", input$local,
" -oauto_cache", extra_options)
})
callModule(sendTerm, "mount", code = meta_mount, term_id = term_id,
execute = code_exec)
meta_unmount <- reactive({
if (Sys.info()[["sysname"]] == "Darwin") {
paste("umount", input$local)
} else {
paste("fusermount -u", input$local)
}
})
callModule(sendTerm, "unmount", code = meta_unmount, term_id = term_id)
# Run =======================================================================
if (file.exists("~/.o2job")) {
init_job <- readLines("~/.o2job")
} else {
init_job <- c("short", "0-03:00:00", "2G", "", "", "", "", "1")
}
output$partition <- renderUI({
selectInput(
"partition", "Partition",
choices = c("short", "gpu", "medium", "long",
"mpi", "priority", "transfer"),
selected = init_job[1], width = "95%"
)
})
output$duration <- renderUI({
textInput(
"duration", "Time Limit", value = init_job[2], width = "95%"
)
})
output$mem <- renderUI({
textInput(
"mem", "Memory", value = init_job[3], width = "95%"
)
})
output$n <- renderUI({
textInput("n", "-n", value = init_job[4], width = "95%")
})
output$c <- renderUI({
textInput("c", "-c", value = init_job[5], width = "95%")
})
output$N <- renderUI({
textInput("N", "-N", value = init_job[6], width = "95%")
})
output$o <- renderUI({
textInput("o", "-o", value = init_job[7], width = "95%")
})
output$gpu <- renderUI({
textInput("gpu", "# GPU", value = init_job[8], width = "95%")
})
o2job <- reactive({
c(input$partition, input$duration, input$mem,
input$n, input$c, input$N, input$o, input$gpu)
})
observeEvent(o2job(), writeLines(o2job(), "~/.o2job"))
job_options <- reactive({
options <- c(
paste("-p", input$partition),
paste("-t", input$duration),
paste0("--mem=", input$mem)
)
if (input$n != "") options <- c(options, paste("-n", input$n))
if (input$c != "") options <- c(options, paste("-c", input$c))
if (input$N != "") options <- c(options, paste("-N", input$N))
if (input$o != "") options <- c(options, paste("-o", input$o))
if (input$partition == "gpu") {
options <- c(options, paste0("--gres=gpu:", input$gpu))
}
options <- paste(options, collapse = " ")
return(options)
})
job_int <- reactive({
req(input$partition)
paste0("srun --pty ", job_options(), " /bin/bash")
})
callModule(sendTerm, "run_int", code = job_int, term_id = term_id,
execute = code_exec)
shinyFileChoose(input, 'file', roots = c(home = "~"))
script_path <- reactive({
req(input$file)
paths <- unlist(input$file$files$`0`)
paths[1] <- "~"
path <- normalizePath(paste(paths, collapse = .Platform$file.sep))
path_local <- normalizePath(input$local)
path <- substr(path, nchar(path_local) + 1, nchar(path))
paste0(meta()[2], path)
})
job_batch <- reactive({
req(input$partition)
if (isTruthy(input$file)) {
return(paste("sbatch", job_options(), script_path(),
"-o out.%j -e err.%j"))
}
return("Select a .sh Script")
})
observeEvent(input$check_batch, {
rstudioapi::terminalActivate(term_id)
rstudioapi::terminalSend(term_id, "squeue -u $USER\n")
})
callModule(sendTerm, "run_batch", code = job_batch, term_id = term_id,
execute = code_exec)
module_code <- reactive({
paste("module", input$module)
})
callModule(sendTerm, "run_module", code = module_code, term_id = term_id,
execute = code_exec)
# sshkey-gen ================================================================
sshkeygen <- reactive({
req(input$o2id)
paste0('ssh-keygen -t rsa -C ', '"', input$o2id, '"')
})
callModule(sendTerm, "run_sshkeygen", code = sshkeygen, term_id = term_id,
execute = code_exec)
output$sshkey_config <- renderText({
paste0("Host o2 o2.hms.harvard.edu\n AddKeysToAgent yes\n HostName o2.hms.harvard.edu\n IdentityFile ~/.ssh/", input$sshkey_file)
})
output$sshkey_config_btn <- renderUI({
actionButton("sshkey_config_file", label = icon("play"), width = "95%",
style = "height: 93px; margin-left: 2px;")
})
observeEvent(input$sshkey_config_file, {
file.edit("~/.ssh/config")
})
sshkey_scp <- reactive({
req(input$o2id)
paste0('scp ~/.ssh/', input$sshkey_file, ".pub ", input$o2id, '@o2.hms.harvard.edu:')
})
callModule(sendTerm, "run_sshkey_scp", code = sshkey_scp, term_id = term_id,
execute = code_exec)
callModule(sendTerm, "run_ssh_login", code = meta_login, term_id = term_id,
execute = code_exec)
output$sshkey_auth <- renderUI({
tagList(
textInput("sshkey_auth_1", NULL, "mkdir -p ~/.ssh", width = "100%"),
textInput("sshkey_auth_2", NULL, "touch ~/.ssh/authorized_keys", width = "100%"),
textInput("sshkey_auth_3", NULL,
paste0("cat ~/", input$sshkey_file, ".pub >> ~/.ssh/authorized_keys"), width = "100%"),
textInput("sshkey_auth_4", NULL, paste0("rm ~/", input$sshkey_file, ".pub"), width = "100%")
)
})
output$sshkey_auth_btn <- renderUI({
actionButton("sshkey_auth_run", label = icon("play"), width = "95%",
style = "height: 180px; margin-left: 2px;")
})
observeEvent(input$sshkey_auth_run, {
rstudioapi::terminalActivate(term_id)
rstudioapi::terminalSend(term_id, paste0(input$sshkey_auth_1, "\n"))
rstudioapi::terminalSend(term_id, paste0(input$sshkey_auth_2, "\n"))
rstudioapi::terminalSend(term_id, paste0(input$sshkey_auth_3, "\n"))
rstudioapi::terminalSend(term_id, paste0(input$sshkey_auth_4, "\n"))
})
}
#' RO2 RStudio Addin
#'
#' @export
ro2_addin <- function() {
runGadget(ro2_ui, ro2_server, viewer = paneViewer())
}
Add the following code to your website.
For more information on customizing the embed code, read Embedding Snippets.