1

This is partly related to Pass PowerShell variables to Docker commands, but I have an edge case that I am struggling to solve, and that is probably down to my lack of PowerShell knowledge.

I have a PowerShell script that optionally needs to include a -v option in the docker run command.

This is the script:

$pwd = (Get-Location)

# If GEM_HOME is declared, see if it is in the current directory. If not, we need
# to volume-mount it and change the variable value.
$gem_mount_cmd = ""
$gem_env_var = "-e GEM_HOME"
if (Test-Path env:GEM_HOME)
{
    $gem_home = $env:GEM_HOME
    $parent = (Split-Path -parent $gem_home)
    if ((Join-Path $parent '') -ne $pwd)
    {
        $gem_mount_cmd = "-v ""`$('$parent' -replace '\\','/'):/gems"""
        $gem_env_var = "-e GEM_HOME='/gems/"+(Split-Path -leaf $gem_home)+"'"
    }
}

$cmd = "& docker run --rm -it $gem_env_var $gem_mount_cmd -v ${pwd}:/srv alpine bash"
Write-Output $cmd
& $cmd

As it stands, running that script will result in a PowerShell error about docker run not being recognized as the name of a cmdlet, function, script file or operable program.

I've also tried:

& docker run --rm -it $gem_env_var $gem_mount_cmd -v ${pwd}:/srv alpine bash

and that gives me a Docker error instead, complaining about "unknown shorthand flag: 'r' in -replace".

I've also tried replacing the assignment to $gem_mount_cmd with:

$gem_mount_cmd = "-v $($parent -replace '\\','/'):/gems"

but that takes me back to the "Error response from daemon: invalid mode" error that the OP of the linked question was hitting.

I've also read Powershell Call MSI with Arguments and revised the script to this:

$pwd = (Get-Location)

# If GEM_HOME is declared, see if it is in the current directory. If not, we need
# to volume-mount it and change the variable value.
$gem_mount_cmd = ""
$gem_env_var = "-e GEM_HOME"
if (Test-Path env:GEM_HOME)
{
    $gem_home = $env:GEM_HOME
    $parent = (Split-Path -parent $gem_home)
    if ((Join-Path $parent '') -ne $pwd)
    {
        $gem_mount_cmd = "-v $($parent -replace '\\','/'):/gems"
        $gem_env_var = "-e GEM_HOME='/gems/"+(Split-Path -leaf $gem_home)+"'"
    }
}

$params = 'run', '--rm', '-it',
          $gem_env_var, $gem_mount_cmd, '-v ${pwd}:/srv',
          'alpine', 'bash'
& docker @params

but this gives me the same Docker "invalid mode" error.

What do I need to do in order to get this to work? I suppose one option would be to have the script embed two different versions of the docker run command, e.g.:

$pwd = (Get-Location)

# If GEM_HOME is declared, see if it is in the current directory. If not, we need
# to volume-mount it and change the variable value.
$gem_mount_cmd = ""
$gem_env_var = "-e GEM_HOME"
if (Test-Path env:GEM_HOME)
{
    $gem_home = $env:GEM_HOME
    $parent = (Split-Path -parent $gem_home)
    if ((Join-Path $parent '') -ne $pwd)
    {
        $gem_mount_cmd = "-v $($parent -replace '\\','/'):/gems"
        $gem_env_var = "-e GEM_HOME='/gems/"+(Split-Path -leaf $gem_home)+"'"
    }
}

if ("$gem_mount_cmd" -ne "") {
    & docker run --rm -it $gem_env_var -v "$($parent -replace '\\','/'):/gems" -v ${pwd}:/srv alpine bash
}
else {
    & docker run --rm -it -v ${pwd}:/srv alpine bash
}

but it feels like there must be a better way …

Philip Colmer
  • 1,426
  • 2
  • 17
  • 30
  • Try conditionally appending values to the `$params` array. `$params = 'run', '--rm', '--it'; if (Test-Path env:GEM_HOME) {$params += '-e', "GEM_HOME='/gems/$(Split-Path -Leaf $gem_home)'", '-v', ($parent -replace '\\', '/')}; $params += '-v', "${pwd}:/srv", 'alpine', 'bash'` – Ansgar Wiechers Aug 15 '18 at 11:21
  • Thanks, @AnsgarWiechers. There was a small typo - "$($parent -replace '\\', '/'):/gems" but that is now working. – Philip Colmer Aug 15 '18 at 14:03

1 Answers1

2

I would dynamically build the parameters array and then splat it on the command:

$params = 'run', '--rm', '--it'
if (Test-Path env:GEM_HOME) {
    $params += '-e', "GEM_HOME='/gems/$(Split-Path -Leaf $gem_home)'",
               '-v', "$($parent -replace '\\', '/'):/gems"
}
$params += '-v', "${pwd}:/srv", 'alpine', 'bash'

& 'docker.exe' @params
Ansgar Wiechers
  • 193,178
  • 25
  • 254
  • 328