Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

local development with Docker #2553

Closed
istfer opened this issue Mar 26, 2020 · 9 comments · Fixed by #2610
Closed

local development with Docker #2553

istfer opened this issue Mar 26, 2020 · 9 comments · Fixed by #2610

Comments

@istfer
Copy link
Contributor

istfer commented Mar 26, 2020

Description

I'm trying to set up a pecan development environment with docker. I will have couple of questions, so I'm opening an issue (I'll try to translate it to documentation later).

Context

I pulled latest changes from develop, switched to my feature branch, and started following these steps in the documentation:

  • I mounted my local version of the PEcAn source code onto pecan/executor in the docker-compose.override.yml
  • updated my PEcAn Docker stack docker-compose -p pecan up -d
  • as I want to work with my code and propagate it into the PEcAn container, I tried to re-compile code inside the executor by running docker exec -it pecan_executor_1 /bin/bash, there I moved to /pecan directory and ran make clean and make
  • At this point, I hit the following BASGRA error.
    Screen Shot 2020-03-26 at 15 06 59

This is a critical error for me because I want to work with BASGRA. BASGRA source code currently lives in the pecan/models/basgra package and compiles with the rest of the PEcAn code (there were reasons to do this in the native installation, this was the only way I could make this .Fortran() call work).

Possible Implementation

What is the best way to solve this and make BASGRA work with pecan-docker environment? I guess even if I solve the compilation issue it may not mean that I will be able to run the model through pecan-docker? I can try dockerizing BASGRA, but I'm not sure how native version will communicate with it then.

I will have DB questions (I have populated DB tables for BASGRA at BU servers, but how will I get them onto my server now but I still haven't figured out syncing with docker), once I move past this issue.

[added by @dlebauer:]

  • how can I run the integration tests like ./web/workflow.R --settings tests/pecan64.ed.xml ?
  • how can I make sure that the most recent version of ED2 is running (currently the stack seems to pull down v2.1)?
  • how do I sync the database?
@infotroph
Copy link
Member

To move forward immediately without rebuilding any images, you should be able to execute Rscript -e 'devtools::install_version("roxygen2", "7.0.2")' from a shell inside the running executor container. It'll need redoing every time you restart the container, but I've been doing a lot of it during moments I want to think about R code instead of Docker setup.

@infotroph
Copy link
Member

infotroph commented Mar 26, 2020

What's happening here is that Roxygen needs to be able to load the whole package including compiled code. Roxygen 7 is smart enough to recompile DLLs when it needs them, but Roxygen 6 isn't. You might also be able to work around it by forcing the compilation before Roxygen runs: make clean; Rscript -e 'devtools::load_all("models/basgra")'; make

@istfer
Copy link
Contributor Author

istfer commented Mar 26, 2020

Rscript -e 'devtools::install_version("roxygen2", "7.0.2")'
this gives me

Error in download_version_url(package, version, repos, type) : 
  version '7.0.2' is invalid for package 'roxygen2'
Calls: <Anonymous> -> download_version_url
Execution halted

maybe I should also update depends or something?

make clean; Rscript -e 'devtools::load_all("models/basgra")'; make
But this worked! Thanks @infotroph!

Does this mean I can just start working with BASGRA? or do I still need to go through json steps to "announce" the model?

@infotroph
Copy link
Member

maybe I should also update depends or something?

Looks like it's defaulting to an outdated CRAN mirror. Maybe we should consider reconfiguring this in the Dockerfile? But meanwhile, looks like you can specify the repository directly, e.g. devtools::install_version("roxygen2", "7.0.2", repos="https://cran.rstudio.com").

All of this should be moot once #2538 is merged and the Docker images are building automatically again.

Does this mean I can just start working with BASGRA? or do I still need to go through json steps to "announce" the model?

I'll defer to @robkooper here

@istfer
Copy link
Contributor Author

istfer commented Mar 26, 2020

OK adding the extra repo arg solved it.

In the meantime, is there a way to confirm that I indeed managed to map my source code to the PEcAn container? when I go into the executor I see my code (e.g. I am able to see my changes to the code when interact with it docker exec -it pecan_executor_1 /bin/bash) But when I open RStudio (localhost:8000/rstudio) and navigate to /pecan I don't see my code. Do they not communicate (this way)?

I guess I need to mount my source code to all of the services that has pecan:/data as a volume in the docker-compose.override.yml to make sure every service uses my code, right?

  rstudio:
    volumes:
      - .:/pecan

and also for minio, thredds, web, monitor, sipnet, ....

@infotroph
Copy link
Member

That mountpoint looks right to me. For Rstudio I'd been using - .:/pecan_dev to avoid conflicting with the /pecan that's already mounted, but I think I'll adopt yours -- not like I need both versions at once.

@robkooper robkooper added this to the 1.8.0 milestone Apr 14, 2020
@robkooper robkooper added this to To do in Season of Docs via automation Apr 25, 2020
@istfer
Copy link
Contributor Author

istfer commented May 13, 2020

@dlebauer here is a messy trial on my part:

setup
on develop branch
up-to-date

I made these changes to overcome the  permission issues: #2572
Then I rebuilt my images locally with my UID-GID: UID=myuid GID=mygid ./docker.sh
I now have images with "develop" tags

my docker-compose.override.yml

version: "3"
services:
  postgres:
    ports:
      - 7654:5432

  web:
    volumes:
      - ./web:/var/www/html/pecan/

  executor:
    volumes:
      - .:/pecan

  monitor:
    volumes:
      - .:/pecan

  rstudio:
    volumes:
      - .:/pecan

  basgra:
    volumes:
      - .:/pecan


volumes:
  pecan:
    driver_opts:
      type: none
      device: /data
      o: bind

and my .env has  PECAN_VERSION=develop
then I ran docker-compose -p pecan up -d

run
First thing I tried is my typical workflow: start a run from web interface and then continue in RStudio (i.e. http://localhost:8000/rstudio/)

  • host:docker
  • model:ED2.2
  • Site: EBI Energy farm
  • pft: ebifarm.c4grass.doe_vd
  • start_date:2006/01/01
  • end_date:2006/12/31
  • tick edit pecan.xml box and hit next

I would then continue editing the xml on RStudio, open RStudio (inside docker), navigate to workflowdir which is /data/workflows/PEcAn_15000000002 for me in this case
But this xml is already similar to tests/pecan64.ed.xml and ready to test.
Note that my input paths are not /home/carya/sites but /data/sites because of my setup, see my volume in the docker-compose.override. But I didn't have to edit the xml further because BETY IDs of the inputs were already pointing to /data/sites/ebifarm for me

Anyway, I hit continue, and workflow finished without any errors, which is a problem because there were no outputs!

Looks like the ED2IN (ED2IN.rgit) was not compatible with the current version, and there are tons of new tags in the ED2IN since the last time I used it. I don't know how we want to handle ED2IN these days (I believe this is work in progress?), but since I just want to get a run, I manually added the following tags to the ED2IN under the run folder, e.g. /data/workflows/PEcAn_15000000002/run/15000000001/ED2IN

   NL%IOOUTPUT  =  0
   NL%MONTH_YRSTEP = 7
   NL%GROWTH_RESP_SCHEME = 1
   NL%STORAGE_RESP_SCHEME = 1
   NL%PLANT_HYDRO_SCHEME   = 0
   NL%ISTOMATA_SCHEME = 0
   NL%ISTRUCT_GROWTH_SCHEME = 1
   NL%TRAIT_PLASTICITY_SCHEME = 0
   NL%ECONOMICS_SCHEME = 0
   NL%CBR_SCHEME      = 0
   NL%ICANRAD        =  2
   NL%IHRZRAD        =  0
   NL%IGOUTPUT = 0

Then under /data/workflows/PEcAn_15000000002 I re-read pecan.CONFIGS.xml and just ran the
PEcAn.remote::runModule.start.model.runs(settings, stop.on.error = FALSE)
step. Then I got the model running, outputting -T- and -Y- files but then I hit a model2netcdf.ED2 error about some variables not being found. I personally won't bother with these errors since they are not docker related.

So this was with web-page & workflow.R combo, note that if you don't fix the permissions issue you probably won't be able to use this approach.

@istfer
Copy link
Contributor Author

istfer commented May 13, 2020

I was able to start a run following @ashiklom's example as well, but note that connections change inside (http://localhost:8000/rstudio/) the container and outside (on the host machine):

  devtools::install_github("pecanproject/pecan/api@develop")
  library(pecanapi)
  library(magrittr)
  
  start_date <- "2006/01/01"
  end_date <- "2006/12/31"
  ensemble_size = 1
  con = NULL
  nowait = TRUE
  crown_model = FALSE
  n_limit_ps = FALSE
  n_limit_soil = FALSE
  multiple_scatter = FALSE
  trait_plasticity = FALSE
  
  pft_list <- list()
  pft_list[[1]] <- list()
  pft_list[[1]]$name <-  "ebifarm.c4grass.doe_vd"
  pft_list[[1]]$ed2_pft_number <- 14
  
  options(pecanapi.user_id = 15000000002) # my id

 ##### outside of docker
  con <- DBI::dbConnect( 
    RPostgres::Postgres(),
    user = "bety",
    password = "bety",
    host = "fmi-pecan.fmi.fi",
    port = 7654
  )

##### inside docker
  con <- DBI::dbConnect(
    RPostgres::Postgres(),
    user = "bety",
    password = "bety",
    host = "postgres",
    port = 5432
  )
  
  model_id <- 5000000001
  site_id <- 76                   # EBI Energy farm
  workflow <- pecanapi::insert_new_workflow(con, site_id, model_id,
                                            start_date = start_date,
                                            end_date = end_date)
  
  
  ed2in_tags <- list(
    # Custom met
    ED_MET_DRIVER_DB = "/data/sites/ebifarm/ED_MET_DRIVER_HEADER",
    ITOUTPUT = 0,
    IMOUTPUT = 3,
    IOOUTPUT = 3,
    OBSTIME_DB = "",
    OUTFAST = 0,
    ISOUTPUT = 3,
    FRQSTATE = 1,
    UNITSTATE = 2,
    IFOUTPUT = 0,
    IDOUTPUT = 0,
    IQOUTPUT = 0,
    IYOUTPUT = 0,
    # Enable cohort-level output
    IADD_COHORT_MEANS = 1,
    PLANT_HYDRO_SCHEME = 0,
    ISTOMATA_SCHEME = 0,
    ISTRUCT_GROWTH_SCHEME = 0,
    TRAIT_PLASTICITY_SCHEME = as.integer(trait_plasticity),
    ICANRAD = ifelse(multiple_scatter, 1, 2),
    CROWN_MOD = as.integer(crown_model),
    N_PLANT_LIM = as.integer(n_limit_ps),
    N_DECOMP_LIM = as.integer(n_limit_soil),
    INCLUDE_THESE_PFT = "6,9,10,11",
    ISOILFLG = 2, # Set soil characteristics in ED2IN
    NSLCON = 1, # Sand
    SLXCLAY = 0.01,
    SLXSAND = 0.92,
    NZG = 9,
    SLZ = "-2,-1.5,-1,-0.8,-0.6,-0.4,-0.2,-0.1,-0.05",
    SLMSTR = "0.65,0.65,0.65,0.65,0.65,0.65,0.65,0.65,0.65"
  )
  
  
  settings <- list() %>%
    pecanapi::add_workflow(workflow) %>%
    pecanapi::add_database() %>%
    pecanapi::add_pft_list(pft_list) %>%
    pecanapi::add_rabbitmq(model_queue = "ED2_develop") %>%
    modifyList(list(
      meta.analysis = list(iter = 3000, random.effects = FALSE),
      run = list(inputs = list(
        met = list(source = "CFmet", id = 7)
      )),
      ensemble = list(size = ensemble_size, variable = "NPP")
    )) %>%
    modifyList(list(
      run = list(inputs = list(
        lu = list(id = 294),
        soil = list(id = 297),
        thsum = list(id = 295),
        veg = list(id = 296)
      )),
      model = list(
        phenol.scheme = 0,
        edin = "ED2IN.rgit",
        prerun = "ulimit -s unlimited",
        barebones_ed2in = "true",
        ed2in_tags = ed2in_tags
      ),
      workflow = list(nowait = isTRUE(nowait))
    ))
  # outside docker this is fine
  pecanapi::submit_workflow(settings)

  # insider docker, this is what has worked for me:
  pecanapi::submit_workflow(settings, rabbitmq_hostname = "rabbitmq", rabbitmq_port = 15672)
  

Well I got a write.config.ED2 error but I guess this works nicely in the sense that it starts the workflow successfully.

Error in vapply(custom_tags, function(x) grepl(numvec_rxp, x), logical(1)) : 
  values must be length 1,
 but FUN(X[[5]]) result is length 0
Calls: <Anonymous> ... <Anonymous> -> do.call -> write.config.ED2 -> vapply

@robkooper
Copy link
Member

Lets make sure we keep issues clean, the ED/sync is not for development, those are other issues.

Season of Docs automation moved this from To do to Done Jun 29, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
Development

Successfully merging a pull request may close this issue.

3 participants