hashicorp / vagrant

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

Docker provider: Add support for repeated scoped options #13269

Open silopolis opened 9 months ago

silopolis commented 9 months ago

Is your feature request related to a problem? Please describe.

Working on my first "involved" Vagrant project, I wanted to nicely name all the things, among which, bridges and container interfaces.

Sadly, I cannot use docker_network__opt two times like this:

adm.vm.network :private_network,
  docker_network__opt: "com.docker.network.bridge.name=br-#{ADM_NET_NAME}",
  docker_network__opt: "com.docker.network.container_iface_prefix=#{ADM_NET_NAME}",
  ip: "#{adm_net_ip}", netmask: "#{ENV['ADM_NET_CIDR']}"

The issue is that I'm getting the following warning:

warning: key :docker_network__opt is duplicated and overwritten on line 33

Describe the solution you'd like

I wish I were able to use the same scoped option several times in the same network statement and get the corresponding network create command with repeated flags/options.

Note that this may be specific to the --opt and --aux-addresses flags of docker create as they seem the only two that may need to be repeated to set driver options (https://docs.docker.com/engine/reference/commandline/network_create/#bridge-driver-options)

Describe alternatives you've considered

Maybe I could find some way to create the network(s) first to set bridge(s) name(s), then create interfaces and set their names in containers declarations... :thinking:

It could be a solution to my specific case, but wouldn't solve the general issue.

EDIT: This is what I found as came up with

  # Create networks beforehand so we can define containers interfaces names
  # Hack to circumvent Vagrant not supporting several scoped options of the same
  # type. See https://github.com/hashicorp/vagrant/issues/13269
  # Note: IP used to create the network is immediately freed as the dummy
  # container is transient
  load_env.vm.define "networks" do |net|
    net.vm.network :private_network,
      docker_network__opt: "com.docker.network.bridge.name=br-#{ADM_NET_NAME}",
      ip: "#{ADM_NET_ROOT}.#{ADM_NET_IPMAX}", netmask: "#{ADM_NET_CIDR}"
    net.vm.network :private_network,
      docker_network__opt: "com.docker.network.bridge.name=br-#{STO_NET_NAME}",
      ip: "#{STO_NET_ROOT}.#{STO_NET_IPMAX}", netmask: "#{STO_NET_CIDR}"
    net.vm.network :private_network,
      docker_network__opt: "com.docker.network.bridge.name=br-#{DBA_NET_NAME}",
      ip: "#{DBA_NET_ROOT}.#{DBA_NET_IPMAX}", netmask: "#{DBA_NET_CIDR}"
    net.vm.network :private_network,
      docker_network__opt: "com.docker.network.bridge.name=br-#{APP_NET_NAME}",
      ip: "#{APP_NET_ROOT}.#{APP_NET_IPMAX}", netmask: "#{APP_NET_CIDR}"
    net.vm.network :private_network,
      docker_network__opt: "com.docker.network.bridge.name=br-#{PXY_NET_NAME}",
      ip: "#{PXY_NET_ROOT}.#{PXY_NET_IPMAX}", netmask: "#{PXY_NET_CIDR}"
    net.vm.provider "docker" do |dkr|
      dkr.image="williamyeh/dummy"
      dkr.has_ssh = true
      dkr.privileged = true
      dkr.create_args = ["-v", "/sys/fs/cgroup:/sys/fs/cgroup:ro"]
      dkr.name = "net_dummy"
    end
  end
end

Thanks in advance J