diff --git a/README.md b/README.md index ba7e806..a44827d 100644 --- a/README.md +++ b/README.md @@ -77,6 +77,32 @@ _concore_ supports customization through configuration files in the `CONCOREPATH Tool paths can also be set via environment variables (e.g., `CONCORE_CPPEXE=/usr/bin/g++`). Priority: config file > env var > defaults. +### Docker Executable Configuration + +The Docker executable used by generated scripts (`build`, `run`, `stop`, `maxtime`, `params`, `unlock`) is controlled by the `DOCKEREXE` variable. It defaults to `docker` and can be overridden in three ways (highest priority first): + +1. **Config file** — Write the desired command into `concore.sudo` in your `CONCOREPATH` directory: + ``` + docker + ``` + This remains the highest-priority override, preserving backward compatibility. + +2. **Environment variable** — Set `DOCKEREXE` before running `mkconcore.py`: + ```bash + # Rootless Docker / Docker Desktop (macOS, Windows) + export DOCKEREXE="docker" + + # Podman + export DOCKEREXE="podman" + + # Traditional Linux with sudo + export DOCKEREXE="sudo docker" + ``` + +3. **Default** — If neither the config file nor the environment variable is set, `docker` is used. + +> **Note:** Previous versions defaulted to `sudo docker`, which failed on Docker Desktop (macOS/Windows), rootless Docker, and Podman. The new default (`docker`) works out of the box on those platforms. If you still need `sudo`, set `DOCKEREXE="sudo docker"` via the environment variable or `concore.sudo` config file. + ### Security Configuration Set a secure secret key for the Flask server before running in production: diff --git a/mkconcore.py b/mkconcore.py index 974c9bb..eff438f 100644 --- a/mkconcore.py +++ b/mkconcore.py @@ -158,7 +158,7 @@ def _resolve_concore_path(): OCTAVEWIN = os.environ.get("CONCORE_OCTAVEWIN", "octave") #Windows octave M_IS_OCTAVE = False #treat .m as octave MCRPATH = "~/MATLAB/R2021a" #path to local Ubunta Matlab Compiler Runtime -DOCKEREXE = "sudo docker"#assume simple docker install +DOCKEREXE = os.environ.get("DOCKEREXE", "docker")#default to docker, allow env override DOCKEREPO = "markgarnold"#where pulls come from 3/28/21 INDIRNAME = ":/in" OUTDIRNAME = ":/out" @@ -858,8 +858,8 @@ def cleanup_script_files(): fmaxtime.write('#!/bin/bash' + "\n") fmaxtime.write('echo "$1" >concore.maxtime\n') fmaxtime.write('echo "FROM alpine:3.8" > Dockerfile\n') - fmaxtime.write('sudo docker build -t docker-concore .\n') - fmaxtime.write('sudo docker run --name=concore') + fmaxtime.write(f'{DOCKEREXE} build -t docker-concore .\n') + fmaxtime.write(f'{DOCKEREXE} run --name=concore') # -v VCZ:/VCZ -v VPZ:/VPZ i=0 # 9/12/21 for node in nodes_dict: @@ -885,15 +885,15 @@ def cleanup_script_files(): dockername = sourcecode.rsplit(".", 1)[0] #3/28/21 writeedges = volswr[i] while writeedges.find(":") != -1: - fmaxtime.write('sudo docker cp concore.maxtime concore:/') + fmaxtime.write(f'{DOCKEREXE} cp concore.maxtime concore:/') # escape destination path in docker cp vol_path = writeedges.split(":")[0].split("-v ")[1].strip() fmaxtime.write(shlex.quote(vol_path+"/concore.maxtime")+"\n") writeedges = writeedges[writeedges.find(":")+1:] i=i+1 - fmaxtime.write('sudo docker stop concore \n') - fmaxtime.write('sudo docker rm concore\n') - fmaxtime.write('sudo docker rmi docker-concore\n') + fmaxtime.write(f'{DOCKEREXE} stop concore \n') + fmaxtime.write(f'{DOCKEREXE} rm concore\n') + fmaxtime.write(f'{DOCKEREXE} rmi docker-concore\n') fmaxtime.write('rm Dockerfile\n') fmaxtime.write('rm concore.maxtime\n') fmaxtime.close() @@ -901,8 +901,8 @@ def cleanup_script_files(): fparams.write('#!/bin/bash' + "\n") fparams.write('echo "$1" >concore.params\n') fparams.write('echo "FROM alpine:3.8" > Dockerfile\n') - fparams.write('sudo docker build -t docker-concore .\n') - fparams.write('sudo docker run --name=concore') + fparams.write(f'{DOCKEREXE} build -t docker-concore .\n') + fparams.write(f'{DOCKEREXE} run --name=concore') # -v VCZ:/VCZ -v VPZ:/VPZ i=0 # 9/12/21 for node in nodes_dict: @@ -928,23 +928,23 @@ def cleanup_script_files(): dockername = sourcecode.rsplit(".", 1)[0] #3/28/21 writeedges = volswr[i] while writeedges.find(":") != -1: - fparams.write('sudo docker cp concore.params concore:/') + fparams.write(f'{DOCKEREXE} cp concore.params concore:/') # escape destination path vol_path = writeedges.split(":")[0].split("-v ")[1].strip() fparams.write(shlex.quote(vol_path+"/concore.params")+"\n") writeedges = writeedges[writeedges.find(":")+1:] i=i+1 - fparams.write('sudo docker stop concore \n') - fparams.write('sudo docker rm concore\n') - fparams.write('sudo docker rmi docker-concore\n') + fparams.write(f'{DOCKEREXE} stop concore \n') + fparams.write(f'{DOCKEREXE} rm concore\n') + fparams.write(f'{DOCKEREXE} rmi docker-concore\n') fparams.write('rm Dockerfile\n') fparams.write('rm concore.params\n') fparams.close() funlock.write('#!/bin/bash' + "\n") funlock.write('echo "FROM alpine:3.8" > Dockerfile\n') - funlock.write('sudo docker build -t docker-concore .\n') - funlock.write('sudo docker run --name=concore') + funlock.write(f'{DOCKEREXE} build -t docker-concore .\n') + funlock.write(f'{DOCKEREXE} run --name=concore') # -v VCZ:/VCZ -v VPZ:/VPZ i=0 # 9/12/21 for node in nodes_dict: @@ -970,15 +970,15 @@ def cleanup_script_files(): dockername = sourcecode.rsplit(".", 1)[0] #3/28/21 writeedges = volswr[i] while writeedges.find(":") != -1: - funlock.write('sudo docker cp ~/concore.apikey concore:/') + funlock.write(f'{DOCKEREXE} cp ~/concore.apikey concore:/') # escape destination path vol_path = writeedges.split(":")[0].split("-v ")[1].strip() funlock.write(shlex.quote(vol_path+"/concore.apikey")+"\n") writeedges = writeedges[writeedges.find(":")+1:] i=i+1 - funlock.write('sudo docker stop concore \n') - funlock.write('sudo docker rm concore\n') - funlock.write('sudo docker rmi docker-concore\n') + funlock.write(f'{DOCKEREXE} stop concore \n') + funlock.write(f'{DOCKEREXE} rm concore\n') + funlock.write(f'{DOCKEREXE} rmi docker-concore\n') funlock.write('rm Dockerfile\n') funlock.close()