Vagrant: `Running provisioner: shell...` executes multiple times

Created on 18 Jul 2019  ยท  9Comments  ยท  Source: hashicorp/vagrant

Running Vagrant 2.2.5 and VirtualBox 6.0.10 causes the shell provisioner to execute the same script multiple times.
I've had no issues with this previously, so it might be related to VirtualBox 6, but I can't for the moment verify this.

Host, Vagrant and VirtualBox version:

$ uname -vi
Darwin Kernel Version 18.6.0: Thu Apr 25 23:16:27 PDT 2019; root:xnu-4903.261.4~2/RELEASE_X86_64 MacBookPro11,5
$ vagrant --version
Vagrant 2.2.5
$ vboxmanage --version
6.0.10r132072

Vagrantfile:

Vagrant.configure("2") do |config|
  config.vm.provider "virtualbox" do |v|
    v.default_nic_type = "Am79C973"
    v.memory = 2048
    v.cpus = 2
  end

  config.vm.define "bionic" do |bionic|
    bionic.vm.box = "ubuntu/bionic64"
    bionic.ssh.insert_key = true
    bionic.vm.network "private_network", ip: "10.7.8.45"
    bionic.vm.hostname = "bionic"

    config.vm.provider "virtualbox" do |disk01|
      bionic_disk01 = '/tmp/bionic_disk01.vdi'
      if not File.exists?(bionic_disk01)
        disk01.customize ['createhd', '--filename', bionic_disk01, '--variant', 'Standard', '--size', 5 * 1024]
      end
      disk01.customize ['storageattach', :id, '--storagectl', 'SCSI', '--port', 2, '--device', 0, '--type', 'hdd', '--medium', bionic_disk01]

      if ARGV[0] == "up" && ! File.exist?(bionic_disk01)
        bionic.vm.provision "shell", path: "createPartitions.sh"
      end
    end
  end
end

The original Vagrantfile is available at https://github.com/konstruktoid/hardening/blob/master/Vagrantfile.
createPartitions.sh is available at https://github.com/konstruktoid/hardening/blob/master/createPartitions.sh.

vagrant up log:

Bringing machine 'bionic' up with 'virtualbox' provider...
==> bionic: Checking if box 'ubuntu/bionic64' version '20190716.0.0' is up to date...
==> bionic: Clearing any previously set network interfaces...
==> bionic: Preparing network interfaces based on configuration...
    bionic: Adapter 1: nat
    bionic: Adapter 2: hostonly
==> bionic: Forwarding ports...
    bionic: 22 (guest) => 2222 (host) (adapter 1)
==> bionic: Running 'pre-boot' VM customizations...
==> bionic: Booting VM...
==> bionic: Waiting for machine to boot. This may take a few minutes...
    bionic: SSH address: 127.0.0.1:2222
    bionic: SSH username: vagrant
    bionic: SSH auth method: private key
    bionic:
    bionic: Vagrant insecure key detected. Vagrant will automatically replace
    bionic: this with a newly generated keypair for better security.
    bionic:
    bionic: Inserting generated public key within guest...
    bionic: Removing insecure key from the guest if it's present...
    bionic: Key inserted! Disconnecting and reconnecting using new SSH key...
==> bionic: Machine booted and ready!
Got different reports about installed GuestAdditions version:
Virtualbox on your host claims:   5.2.8
VBoxService inside the vm claims: 5.2.18
Going on, assuming VBoxService is correct...
[bionic] GuestAdditions versions on your host (6.0.10) and guest (5.2.18) do not match.
Got different reports about installed GuestAdditions version:
Virtualbox on your host claims:   5.2.8
VBoxService inside the vm claims: 5.2.18
Going on, assuming VBoxService is correct...
Reading package lists...
Building dependency tree...
Reading state information...
[... package updates and installation removed ...]
VirtualBox Guest Additions: Starting.
VirtualBox Guest Additions: Building the VirtualBox Guest Additions kernel 
modules.  This may take a while.
VirtualBox Guest Additions: To build modules for other installed kernels, run
VirtualBox Guest Additions:   /sbin/rcvboxadd quicksetup <version>
VirtualBox Guest Additions: or
VirtualBox Guest Additions:   /sbin/rcvboxadd quicksetup all
VirtualBox Guest Additions: Building the modules for kernel 4.15.0-54-generic.
update-initramfs: Generating /boot/initrd.img-4.15.0-54-generic
Unmounting Virtualbox Guest Additions ISO from: /mnt
==> bionic: Checking for guest additions in VM...
==> bionic: Setting hostname...
==> bionic: Configuring and enabling network interfaces...
==> bionic: Mounting shared folders...
    bionic: /vagrant => /REMOVED/Github/hardening
==> bionic: Running provisioner: shell...
    bionic: Running: /var/folders/g5/cz5cgtwd5l59bzkjkr0cbj0xwnlwnj/T/vagrant-shell20190718-71164-7oar1m.sh
    bionic: sdc      8:32   0   5G  0 disk 
    bionic: 
    bionic: Welcome to fdisk (util-linux 2.31.1).
    bionic: Changes will remain in memory only, until you decide to write them.
    bionic: Be careful before using the write command.
    bionic: Device does not contain a recognized partition table.
    bionic: Created a new DOS disklabel with disk identifier 0x97ca5fc4.
    bionic: 
    bionic: Command (m for help): 
    bionic: Partition type
    bionic:    p   primary (0 primary, 0 extended, 4 free)
    bionic:    e   extended (container for logical partitions)
    bionic: Select (default p): 
    bionic: Partition number (1-4, default 1): First sector (2048-10485759, default 2048): Last sector, +sectors or +size{K,M,G,T,P} (2048-10485759, default 10485759): 
    bionic: 
    bionic: Created a new partition 1 of type 'Linux' and of size 500 MiB.
    bionic: 
    bionic: Command (m for help): Partition type
    bionic:    p   primary (1 primary, 0 extended, 3 free)
    bionic:    e   extended (container for logical partitions)
    bionic: Select (default p): Partition number (2-4, default 2): First sector (1026048-10485759, default 1026048): Last sector, +sectors or +size{K,M,G,T,P} (1026048-10485759, default 10485759): 
    bionic: 
    bionic: Created a new partition 2 of type 'Linux' and of size 500 MiB.
    bionic: 
    bionic: Command (m for help): Partition type
    bionic:    p   primary (2 primary, 0 extended, 2 free)
    bionic:    e   extended (container for logical partitions)
    bionic: Select (default p): Partition number (3,4, default 3): First sector (2050048-10485759, default 2050048): Last sector, +sectors or +size{K,M,G,T,P} (2050048-10485759, default 10485759): 
    bionic: 
    bionic: Created a new partition 3 of type 'Linux' and of size 500 MiB.
    bionic: 
    bionic: Command (m for help): 
    bionic: The partition table has been altered.
    bionic: Calling ioctl() to re-read partition table.
    bionic: Syncing disks.
    bionic: meta-data=/dev/sdc1              isize=512    agcount=4, agsize=32000 blks
    bionic:          =                       sectsz=512   attr=2, projid32bit=1
    bionic:          =                       crc=1        finobt=1, sparse=0, rmapbt=0, reflink=0
    bionic: data     =                       bsize=4096   blocks=128000, imaxpct=25
    bionic:          =                       sunit=0      swidth=0 blks
    bionic: naming   =version 2              bsize=4096   ascii-ci=0 ftype=1
    bionic: log      =internal log           bsize=4096   blocks=855, version=2
    bionic:          =                       sectsz=512   sunit=0 blks, lazy-count=1
    bionic: realtime =none                   extsz=4096   blocks=0, rtextents=0
    bionic: meta-data=/dev/sdc2              isize=512    agcount=4, agsize=32000 blks
    bionic:          =                       sectsz=512   attr=2, projid32bit=1
    bionic:          =                       crc=1        finobt=1, sparse=0, rmapbt=0, reflink=0
    bionic: data     =                       bsize=4096   blocks=128000, imaxpct=25
    bionic:          =                       sunit=0      swidth=0 blks
    bionic: naming   =version 2              bsize=4096   ascii-ci=0 ftype=1
    bionic: log      =internal log           bsize=4096   blocks=855, version=2
    bionic:          =                       sectsz=512   sunit=0 blks, lazy-count=1
    bionic: realtime =none                   extsz=4096   blocks=0, rtextents=0
    bionic: meta-data=/dev/sdc3              isize=512    agcount=4, agsize=32000 blks
    bionic:          =                       sectsz=512   attr=2, projid32bit=1
    bionic:          =                       crc=1        finobt=1, sparse=0, rmapbt=0, reflink=0
    bionic: data     =                       bsize=4096   blocks=128000, imaxpct=25
    bionic:          =                       sunit=0      swidth=0 blks
    bionic: naming   =version 2              bsize=4096   ascii-ci=0 ftype=1
    bionic: log      =internal log           bsize=4096   blocks=855, version=2
    bionic:          =                       sectsz=512   sunit=0 blks, lazy-count=1
    bionic: realtime =none                   extsz=4096   blocks=0, rtextents=0
    bionic: mount: 
    bionic: /var/log/audit: mount point does not exist.
    bionic: vagrant:x:1000:1000:,,,:/home/vagrant:/bin/bash
==> bionic: Running provisioner: shell...
    bionic: Running: /var/folders/g5/cz5cgtwd5l59bzkjkr0cbj0xwnlwnj/T/vagrant-shell20190718-71164-3iwir3.sh
    bionic: sdc      8:32   0    5G  0 disk 
    bionic: 
    bionic: Welcome to fdisk (util-linux 2.31.1).
    bionic: Changes will remain in memory only, until you decide to write them.
    bionic: Be careful before using the write command.
    bionic: 
    bionic: 
    bionic: Command (m for help): 
    bionic: Partition type
    bionic:    p   primary (3 primary, 0 extended, 1 free)
    bionic:    e   extended (container for logical partitions)
    bionic: Select (default e): 
    bionic: Selected partition 4
    bionic: First sector (3074048-10485759, default 3074048): First sector (3074048-10485759, default 3074048): Last sector, +sectors or +size{K,M,G,T,P} (3074048-10485759, default 10485759): 
    bionic: Value out of range.
    bionic: 
    bionic: Created a new partition 4 of type 'Linux' and of size 500 MiB.
    bionic: 
    bionic: Command (m for help): To create more partitions, first replace a primary with an extended partition.
    bionic: 
    bionic: Command (m for help): 
    bionic: Disk /dev/sdc: 5 GiB, 5368709120 bytes, 10485760 sectors
    bionic: Units: sectors of 1 * 512 = 512 bytes
    bionic: Sector size (logical/physical): 512 bytes / 512 bytes
    bionic: I/O size (minimum/optimal): 512 bytes / 512 bytes
    bionic: Disklabel type: dos
    bionic: Disk identifier: 0x97ca5fc4
    bionic: 
    bionic: Device     Boot   Start     End Sectors  Size Id Type
    bionic: /dev/sdc1          2048 1026047 1024000  500M 83 Linux
    bionic: /dev/sdc2       1026048 2050047 1024000  500M 83 Linux
    bionic: /dev/sdc3       2050048 3074047 1024000  500M 83 Linux
    bionic: /dev/sdc4       3074048 4098047 1024000  500M 83 Linux
    bionic: 
    bionic: Command (m for help): 
    bionic: Command (m for help): 
    bionic: Command (m for help): 
    bionic: Command (m for help): 
    bionic: To create more partitions, first replace a primary with an extended partition.
    bionic: 
    bionic: Command (m for help): 
    bionic: 2: unknown command
    bionic: 
    bionic: +: unknown command
    bionic: Disk /dev/sdc: 5 GiB, 5368709120 bytes, 10485760 sectors
    bionic: Units: sectors of 1 * 512 = 512 bytes
    bionic: Sector size (logical/physical): 512 bytes / 512 bytes
    bionic: I/O size (minimum/optimal): 512 bytes / 512 bytes
    bionic: Disklabel type: dos
    bionic: Disk identifier: 0x97ca5fc4
    bionic: 
    bionic: Device     Boot   Start     End Sectors  Size Id Type
    bionic: /dev/sdc1          2048 1026047 1024000  500M 83 Linux
    bionic: /dev/sdc2       1026048 2050047 1024000  500M 83 Linux
    bionic: /dev/sdc3       2050048 3074047 1024000  500M 83 Linux
    bionic: /dev/sdc4       3074048 4098047 1024000  500M 83 Linux
    bionic: 
    bionic: Command (m for help): 
    bionic: Command (m for help): 
    bionic: Command (m for help): 
    bionic: Command (m for help): 
    bionic: 3: unknown command
    bionic: 
    bionic: +: unknown command
    bionic: 
    bionic: The partition table has been altered.
    bionic: Syncing disks.
    bionic: mkfs.xfs: /dev/sdc1 appears to contain an existing filesystem (xfs).
    bionic: mkfs.xfs: Use the -f option to force overwrite.
    bionic: mkfs.xfs: /dev/sdc2 appears to contain an existing filesystem (xfs).
    bionic: mkfs.xfs: Use the -f option to force overwrite.
    bionic: mkfs.xfs: /dev/sdc3 appears to contain an existing filesystem (xfs).
    bionic: mkfs.xfs: Use the -f option to force overwrite.
    bionic: mount: /var/log: /dev/sdc1 already mounted on /var/log.
    bionic: mount: 
    bionic: /home: /dev/sdc3 already mounted on /home.
    bionic: vagrant:x:1000:1000:,,,:/home/vagrant:/bin/bash

Expected behavior

Running provisioner: shell... should only execute once.

waiting-reply

Most helpful comment

Sorry about that @briancain, the debug log is available at https://gist.github.com/konstruktoid/13a030535f92c916e26c77d6a2ae5820

All 9 comments

Hello! Thanks for opening an issue. When opening a new issue on the Vagrant project, we ask that everyone provide a gist containing the behavior you're seeing with the --debug flag included. This helps us figure out what's actually going on. Thanks!

Sorry about that @briancain, the debug log is available at https://gist.github.com/konstruktoid/13a030535f92c916e26c77d6a2ae5820

If I remember correctly, this provider block gets evaluated more than once per guest when Vagrant goes to parse a guests config. Because of where you've placed your provisioner, that means it gets defined every time the provider block gets parsed in Vagrant. Generally I don't think it's supported to place things other than provider related config options inside this block for this reason. Moving it out from your provider block will eliminate the duplicate provisioners from being created.

edit: By _this_ provider block, I mean where you have

config.vm.provider "virtualbox" do |disk01|`
...
...
  bionic.vm.provision ...
end

Thanks @briancain, but has this behavior changed recently?

Fixed example for the archives:

Vagrant.configure("2") do |config|
  bionic_disk01 = '/tmp/bionic_disk01.vdi'

  config.vm.provider "virtualbox" do |v|
    v.default_nic_type = "Am79C973"
    v.memory = 2048
    v.cpus = 2
  end

  config.vm.provider "virtualbox" do |bionic_disk|
    if not File.exists?(bionic_disk01)
      bionic_disk.customize ['createhd', '--filename', bionic_disk01, '--variant', 'Standard', '--size', 5 * 1024]
    end
    bionic_disk.customize ['storageattach', :id, '--storagectl', 'SCSI', '--port', 2, '--device', 0, '--type', 'hdd', '--medium', bionic_disk01]
  end

  config.vm.define "bionic" do |bionic|
    bionic.vm.box = "ubuntu/bionic64"
    bionic.ssh.insert_key = true
    bionic.vm.network "private_network", ip: "10.7.8.45"
    bionic.vm.hostname = "bionic"
    if ARGV[0] == "up" && ! File.exist?(bionic_disk01)
      bionic.vm.provision "shell", path: "createPartitions.sh"
    end
  end
end

Thanks @briancain, but has this behavior changed recently?

I am also interested in the reply here. Thank you!

EDIT:
I believe the commit which changed everything is 50c4464, see also https://github.com/hashicorp/vagrant/issues/10972.
P.S. I can be wrong here.

Trying to expand the Vagrantfile so I can run multiple machines as I did before but it seems more logic has changed regardingif not File.exists??

$ ls /tmp/*.vdi
ls: cannot access '/tmp/*.vdi': No such file or directory
$ vagrant up
Bringing machine 'bionic' up with 'virtualbox' provider...
Bringing machine 'standard' up with 'virtualbox' provider...
==> bionic: Importing base box 'ubuntu/bionic64'...
==> bionic: Matching MAC address for NAT networking...
==> bionic: Checking if box 'ubuntu/bionic64' version '20190720.0.0' is up to date...
==> bionic: Setting the name of the VM: hardening_bionic_1566209815430_24921
==> bionic: Clearing any previously set network interfaces...
==> bionic: Preparing network interfaces based on configuration...
    bionic: Adapter 1: nat
    bionic: Adapter 2: hostonly
==> bionic: Forwarding ports...
    bionic: 22 (guest) => 2222 (host) (adapter 1)
==> bionic: Running 'pre-boot' VM customizations...
A customization command failed:

["createhd", "--filename", "/tmp/standard_disk01.vdi", "--variant", "Standard", "--size", 5120]

The following error was experienced:

#<Vagrant::Errors::VBoxManageError: There was an error while executing `VBoxManage`, a CLI used by Vagrant
for controlling VirtualBox. The command and stderr is shown below.

Command: ["createhd", "--filename", "/tmp/standard_disk01.vdi", "--variant", "Standard", "--size", "5120"]

Stderr: 0%...
Progress state: VBOX_E_FILE_ERROR
VBoxManage: error: Failed to create medium
VBoxManage: error: Could not create the medium storage unit '/tmp/standard_disk01.vdi'.
VBoxManage: error: VDI: cannot create image '/tmp/standard_disk01.vdi' (VERR_ALREADY_EXISTS)
VBoxManage: error: Details: code VBOX_E_FILE_ERROR (0x80bb0004), component MediumWrap, interface IMedium
VBoxManage: error: Context: "RTEXITCODE handleCreateMedium(HandlerArg *)" at line 462 of file VBoxManageDisk.cpp
>

Please fix this customization and try again.
$ ls /tmp/*.vdi
/tmp/bionic_disk01.vdi  /tmp/standard_disk01.vdi
$ vagrant status | grep virtualbox
bionic                    poweroff (virtualbox)
standard                  not created (virtualbox)
$ vagrant destroy -f
==> standard: VM not created. Moving on...
==> bionic: Destroying VM and associated drives...
$ ls /tmp/*.vdi
/tmp/standard_disk01.vdi
Vagrant.configure("2") do |config|
  bionic_disk01 = '/tmp/bionic_disk01.vdi'
  standard_disk01 = '/tmp/standard_disk01.vdi'

  config.vm.provider "virtualbox" do |v|
    v.default_nic_type = "Am79C973"
    v.memory = 2048
    v.cpus = 2
  end

  config.vm.provider "virtualbox" do |bionic_disk|
    if not File.exists?(bionic_disk01)
      bionic_disk.customize ['createhd', '--filename', bionic_disk01, '--variant', 'Standard', '--size', 5 * 1024]
    end
    bionic_disk.customize ['storageattach', :id, '--storagectl', 'SCSI', '--port', 2, '--device', 0, '--type', 'hdd', '--medium', bionic_disk01]
  end

  config.vm.define "bionic" do |bionic|
    bionic.vm.box = "ubuntu/bionic64"
    bionic.ssh.insert_key = true
    bionic.vm.network "private_network", ip: "10.7.8.45"
    bionic.vm.hostname = "bionic"
    if ARGV[0] == "up" && ! File.exist?(bionic_disk01)
      bionic.vm.provision "shell", path: "createPartitions.sh"
    end
  end

  config.vm.provider "virtualbox" do |standard_disk|
    if not File.exists?(standard_disk01)
      standard_disk.customize ['createhd', '--filename', standard_disk01, '--variant', 'Standard', '--size', 5 * 1024]
    end
    standard_disk.customize ['storageattach', :id, '--storagectl', 'SCSI', '--port', 2, '--device', 0, '--type', 'hdd', '--medium', standard_disk01]
  end

  config.vm.define "standard" do |standard|
    standard.vm.box = "ubuntu/bionic64"
    standard.ssh.insert_key = true
    standard.vm.network "private_network", ip: "10.7.8.46"
    standard.vm.hostname = "standard"
    if ARGV[0] == "up" && ! File.exist?(standard_disk01)
      standard.vm.provision "shell", path: "createPartitions.sh"
    end
  end
end

Even I have seen the same behavior. Do we have some updates on this issue ?

@konstruktoid - Nothing has changed with your if-statements and Vagrant. That is actually Ruby executing. We did upgrade ruby in a recent release, but that shouldn't change anything. Be advised that doing things like if ARGV[0] is outside of the scope for what Vagrantfiles should really be handling, and you may encounter some odd behavior. The Vagrantfile isn't a ruby script, and it gets evaluated more than one time during any given Vagrant command.

I'm going to go ahead and close this, since the original fix was already mentioned on this issue. If you have any other issues please feel free to open a new one, thanks!

I'm going to lock this issue because it has been closed for _30 days_ โณ. This helps our maintainers find and focus on the active issues.

If you have found a problem that seems similar to this, please open a new issue and complete the issue template so we can capture all the details necessary to investigate further.

Was this page helpful?
0 / 5 - 0 ratings