providers/docker: support auth [GH-4042]

This commit is contained in:
Mitchell Hashimoto 2014-10-22 13:12:31 -07:00
parent cff57c8d01
commit 296d0639cc
9 changed files with 122 additions and 3 deletions

View File

@ -2,6 +2,8 @@
IMPROVEMENTS:
- providers/docker: Can now start containers from private repositories
more easily. Vagrant will login for you if you specify auth. [GH-4042]
- providers/docker: `stop_timeout` can be used to modify the `docker stop`
timeout. [GH-4504]

View File

@ -241,6 +241,7 @@ module VagrantPlugins
b2.use PrepareNFSValidIds
b2.use SyncedFolderCleanup
b2.use PrepareNFSSettings
b2.use Login
b2.use Build
if env[:machine_action] != :run_command
@ -295,6 +296,7 @@ module VagrantPlugins
autoload :HostMachineSyncFoldersDisable, action_root.join("host_machine_sync_folders_disable")
autoload :IsBuild, action_root.join("is_build")
autoload :IsHostMachineCreated, action_root.join("is_host_machine_created")
autoload :Login, action_root.join("login")
autoload :PrepareSSH, action_root.join("prepare_ssh")
autoload :Stop, action_root.join("stop")
autoload :PrepareNFSValidIds, action_root.join("prepare_nfs_valid_ids")

View File

@ -48,9 +48,6 @@ module VagrantPlugins
# hold the lock, we'll see the updated state.
host_machine.reload
p host_machine.id
p host_machine.ssh_info
# See if the machine is ready already. If not, start it.
if host_machine.communicate.ready?
env[:machine].ui.detail(I18n.t("docker_provider.host_machine_ready"))

View File

@ -0,0 +1,39 @@
require "log4r"
module VagrantPlugins
module DockerProvider
module Action
class Login
def initialize(app, env)
@app = app
@logger = Log4r::Logger.new("vagrant::docker::login")
end
def call(env)
config = env[:machine].provider_config
driver = env[:machine].provider.driver
# If we don't have a password set, don't auth
return @app.call(env) if config.password == ""
# Grab a host VM lock to do the login so that we only login
# once per container for the rest of this process.
env[:machine].provider.host_vm_lock do
# Login!
env[:ui].output(I18n.t("docker_provider.logging_in"))
driver.login(
config.email, config.username,
config.password, config.auth_server)
# Continue, within the lock, so that the auth is protected
# from meddling.
@app.call(env)
# Log out
driver.logout(config.auth_server)
end
end
end
end
end
end

View File

@ -89,6 +89,37 @@ module VagrantPlugins
# @return [String]
attr_accessor :vagrant_vagrantfile
#--------------------------------------------------------------
# Auth Settings
#--------------------------------------------------------------
# Server to authenticate to. If blank, will use the default
# Docker authentication endpoint (which is the Docker Hub at the
# time of this comment).
#
# @return [String]
attr_accessor :auth_server
# Email for logging in to a remote Docker server.
#
# @return [String]
attr_accessor :email
# Email for logging in to a remote Docker server.
#
# @return [String]
attr_accessor :username
# Password for logging in to a remote Docker server. If this is
# not blank, then Vagrant will run `docker login` prior to any
# Docker runs.
#
# The presence of auth will also force the Docker environments to
# serialize on `up` so that different users/passwords don't overlap.
#
# @return [String]
attr_accessor :password
def initialize
@build_args = []
@build_dir = UNSET_VALUE
@ -109,6 +140,11 @@ module VagrantPlugins
@volumes = []
@vagrant_machine = UNSET_VALUE
@vagrant_vagrantfile = UNSET_VALUE
@auth_server = UNSET_VALUE
@email = UNSET_VALUE
@username = UNSET_VALUE
@password = UNSET_VALUE
end
def link(name)
@ -162,6 +198,11 @@ module VagrantPlugins
@vagrant_machine = nil if @vagrant_machine == UNSET_VALUE
@vagrant_vagrantfile = nil if @vagrant_vagrantfile == UNSET_VALUE
@auth_server = nil if @auth_server == UNSET_VALUE
@email = "" if @email == UNSET_VALUE
@username = "" if @username == UNSET_VALUE
@password = "" if @password == UNSET_VALUE
if @host_vm_build_dir_options == UNSET_VALUE
@host_vm_build_dir_options = nil
end

View File

@ -86,6 +86,22 @@ module VagrantPlugins
inspect_container(cid)['HostConfig']['Privileged']
end
def login(email, username, password, server)
cmd = %W(docker login)
cmd += ["-e", email] if email != ""
cmd += ["-u", username] if username != ""
cmd += ["-p", password] if password != ""
cmd << server if server && server != ""
execute(*cmd.flatten)
end
def logout(server)
cmd = %W(docker logout)
cmd << server if server && server != ""
execute(*cmd.flatten)
end
def start(cid)
if !running?(cid)
execute('docker', 'start', cid)

View File

@ -33,6 +33,8 @@ en:
host. You'll see the output of the `vagrant up` for this VM below.
host_machine_syncing_folders: |-
Syncing folders to the host VM...
logging_in: |-
Logging in to Docker server...
logs_host_state_unknown: |-
This container requires a host VM, and the state of that VM
is unknown. Run `vagrant up` to verify that the container and

View File

@ -50,6 +50,11 @@ describe VagrantPlugins::DockerProvider::Config do
its(:stop_timeout) { should eq(1) }
its(:vagrant_machine) { should be_nil }
its(:vagrant_vagrantfile) { should be_nil }
its(:auth_server) { should be_nil }
its(:email) { should eq("") }
its(:username) { should eq("") }
its(:password) { should eq("") }
end
before do

View File

@ -18,6 +18,8 @@ you may set. A complete reference is shown below.
### Optional
General settings:
* `build_args` (array of strings) - Extra arguments to pass to
`docker build` when `build_dir` is in use.
@ -76,3 +78,16 @@ you may set. A complete reference is shown below.
volumes into the container. These directories must exist in the
host where Docker is running. If you want to sync folders from the
host Vagrant is running, just use synced folders.
Below, we have settings related to auth. If these are set, then Vagrant
will `docker login` prior to starting containers, allowing you to pull
images from private repositories.
* `email` (string) - Email address for logging in.
* `username` (string) - Username for logging in.
* `password` (string) - Password for logging in.
* `auth_server` (string) - The server to use for authentication. If not
set, the Docker Hub will be used.