8

I've got a program that needs to automatically install & manage some Docker containers on Windows with minimal user input.

It needs to automatically setup Docker to mount arbitrary Windows folders. It needs to do this from a clean install, where the Docker VM cannot be assumed to have been created.

Docker by default will allow almost any folder in C:\Users to mount through to its Boot2Docker image, which in turn makes them available for mounting into Docker images themselves.

I'd like a way to automatically modify the default mount script from outside the VM so that I can use other folders, but "VBoxManage.exe run", copyto, etc. commands don't work on Boot2Docker in any way, unlike other Linux VMs I have.

So, in my quest for a solution, I stumbled upon py-vbox, which lets you easily send keyboard events to the console using the VirtualBox API. It also allows for direct console sessions, but they fail just like VBoxManage.exe does. So, this ended with me sending lots of

echo command >> /c/script.sh

commands over the keyboard in order to setup a script that will mount the extra volumes. Is there a better way?

For anyone who might need it, here's a very simplified version of what goes on. The first two bits are the old .bat files, so that they apply to anyone. First, to create our docker VM:

set PATH=%PATH%;"c:\Program Files (x86)\Git\bin"
docker-machine create --driver virtualbox my-docker-vm
"C:\Program Files\Oracle\VirtualBox\VBoxManage.exe" sharedfolder add "my-docker-vm" --name "c/myfolder" --hostpath "c:\myfolder" --automount
"C:\Program Files\Oracle\VirtualBox\VBoxManage.exe" setextradata "my-docker-vm" VBoxInternal2/SharedFoldersEnableSymlinksCreate/c/myfolder 1

Then, the docker VM must be started...

"C:\Program Files\Oracle\VirtualBox\VBoxManage.exe" startvm --type=headless my-docker-vm
set PATH=%PATH%;"c:\Program Files (x86)\Git\bin"
docker-machine env --shell cmd my-docker-vm > temp.cmd
call temp.cmd
del temp.cmd

Now, a simplified version of the Python script to write a simplified mount script into the VM via the keyboard using py-vbox:

import virtualbox
script = """\n\
echo if [ ! -d /c/myfolder ] > /c/script.sh\n\
echo then >> /c/script.sh\n\
echo     mkdir -p /c/myfolder >> /c/script.sh\n\
echo     mount -t vboxsf c/myfolder /c/myfolder >> /c/script.sh\n\
echo fi >> /c/script.sh\n\
chmod +x /c/script.sh\n\
/bin/sh /c/script.sh\n\
rm /c/script.sh\n\
"""
my_vm_name = 'my-docker-vm'

def mount_folder():
    vbox = virtualbox.VirtualBox()
    is_there = False
    for vmname in vbox.machines:
        if str(vmname) == my_vm_name:
            is_there = True
            break
    if is_there is False:
        raise whatever
        return

    vm = vbox.find_machine(my_vm_name)
    session = vm.create_session()
    session.console.keyboard.put_keys(script)
std''OrgnlDave
  • 3,912
  • 1
  • 25
  • 34
  • 1
    See if this link helps you http://www.incrediblemolk.com/sharing-a-windows-folder-with-the-boot2docker-vm/. The command is `vboxmanage sharedfolder` – Xiongbing Jin Mar 05 '16 at 16:10
  • @warmoverflow Thank you, but I already googled the heck out of this. This solution would remove access to c:\users, and also doesn't seem to work on the latest version, at least not on my machine. – std''OrgnlDave Mar 07 '16 at 12:56
  • Why do you need to execute those commands from the VM? The only thing you need to do in the VM is to modify `/var/lib/boot2docker/bootlocal.sh`. And the `VBoxManage.exe sharedfolder add` is done when the VM is created but not started yet. http://stackoverflow.com/a/35498478/6309 – VonC Mar 08 '16 at 07:29
  • @VonC Yes, you need to modify that file. But how do you do automatically without using the VBox API to send keyboard strokes? Or is that really the best way? – std''OrgnlDave Mar 09 '16 at 02:04
  • Doesn't `sharedfolder` require guest additions on the target VM ? – xvan Mar 12 '16 at 23:35
  • The `C:/Users` folder is already shared the same way. So the VM should have the guest additions already. – ZeissS May 14 '16 at 10:30

1 Answers1

0

as discussed in the comments:

The C:\Users folder is shared with the VM using the sharedfolders feature of VirtualBox. Just add another sharedfolder and you are done. This is possible from the commandline via VBoxManage sharedfolder add <uuid|vmname> --name <name> --hostpath <path> [--transient] [--readonly] [--automount]. You probably need to restart the VM afterwards.

Another option in newer Windows versions is to just mount whatever folder you want somewhere inside the C:\Users folder, e.g. C:\Users\myuser\dockerdata.

ZeissS
  • 11,867
  • 4
  • 35
  • 50
  • Unfortunately, adding shared folders does not work. You will see using vboxmanage is part of my solution, but making that mount available to VMs running inside is the problem. Also, mounting folders into c:\users\wherever is difficult when it needs to be accessed by different users, and services that may not have a user folder, etc. – std''OrgnlDave May 20 '16 at 15:48