hashicorp / vagrant

Vagrant is a tool for building and distributing development environments.
https://www.vagrantup.com
Other
26.26k stars 4.43k forks source link

Docker Provisioner Not Idempotent #7547

Open darkn3rd opened 8 years ago

darkn3rd commented 8 years ago

Summary

The Docker Provisioner should be idempotent. If you do docker.run twice, you get a failure.

Vagrant version

WEBPORT = ENV['WEBPORT'] || 8080
IMGSOURCE = "/vagrant/"
IMGNAME = "vagrant/express-web"

Vagrant.configure(2) do |config|
  config.vm.box = "ubuntu/trusty64"
  config.vm.network "forwarded_port", guest: WEBPORT, host: WEBPORT
  # config.vm.synced_folder ".", "/home/vagrant/app", type: "rsync",
  #   rsync__exclude: ["node_modules/", "npm-debug.log"]
  config.vm.synced_folder ".", "/vagrant", disabled: false

  # docker install (otherwise vagrant takes 20+ min to install)
  config.vm.provision "shell", path: "install_docker_trusty.sh"

  # docker stuff
  config.vm.provision "docker" do |docker|
    #docker.build_image "#{IMGSOURCE}", args: "-t #{IMGNAME} --env WEBPORT=#{WEBPORT}"
    docker.build_image "#{IMGSOURCE}", args: "-t #{IMGNAME}"

    docker.run "#{IMGNAME}", args: "-p #{WEBPORT}:#{WEBPORT}"
  end
end

Expected behavior

  1. There would be no failure for one.
  2. Second, it should be idempotent. Ideally, kill existing container if already running, and do statements in the vagrant provisioner.

    Actual behavior

The following SSH command responded with a non-zero exit status.
Vagrant assumes that this means the command failed!

          rm -f /var/lib/vagrant/cids/288979dc12fed41244c586d72dc9561a4bd782ef
          docker run --cidfile=/var/lib/vagrant/cids/288979dc12fed41244c586d72dc9561a4bd782ef -d --name vagrant-express-web --restart=always -p 9090:9090 vagrant/express-web

Stdout from the command:

Stderr from the command:

stdin: is not a tty
docker: Error response from daemon: Conflict. The name "/vagrant-express-web" is already in use by container b1e82ad77df7264147454e4dbaea7750c319a1cb6afce971d6dfad76ef9a0076. You have to remove (or rename) that container to be able to reuse that name..
See 'docker run --help'.

Steps to reproduce

  1. vagrant up
  2. vagrant provision

    Debug

darkn3rd commented 8 years ago

One workaround is to: vagrant destroy --force && vagrant up

darkn3rd commented 8 years ago

Another workaround.

$dockerhelper = <<DOCKERHELPER
docker ps -q | xargs -r docker kill
docker ps -aq | xargs -r docker rm
DOCKERHELPER

Vagrant.configure(2) do |config|
  ...
  # making vagrant idempotent again
  config.vm.provision "shell", inline: $dockerhelper
  # docker stuff
  config.vm.provision "docker" do |docker|
    ...
  end
end
allan-simon commented 8 years ago

vagrant destroy --force does not clean things, if the previous vagrant up has not finished succesfully