Skip to content

Commit

Permalink
Merge commit 'cd3909d7cede3a58a2b3439add3f8cb53a770919'
Browse files Browse the repository at this point in the history
* commit 'cd3909d7cede3a58a2b3439add3f8cb53a770919':
  Update CHANGELOG
  Update CHANGELOG
  Update CHANGELOG
  Move up doc string for `vagrant snapshot pop`
  Ensure non-existent machines do not attempt to list snapshots
  Do not rely on IPAddr#prefix as it's not available on older rubies
  Update guest capabilities for coreos
  Fixing bug I introduced. Thanks @chrisroberts!
  Updated based on recommended changes per review.
  Updated documentation. Fixes hashicorp#9584.
  Handling the cases for UNSET_VALUE, i.e., config is not finalized.
  Config has pip_install_cmd for Provisioner to pick it up. Tests updated.
  Ubuntu code updated because it calls Debian code.
  Exposing pip_install_cmd to callers as optional.
  Handling empty strings passed as pip_install_command.
  Adding pip_install_cmd as a default parameter to get_pip. Unit Tests.
  • Loading branch information
jojohans committed Apr 10, 2019
2 parents f221ca9 + cd3909d commit 28f6bdf
Show file tree
Hide file tree
Showing 19 changed files with 417 additions and 121 deletions.
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ IMPROVEMENTS:
- core: Use consistent settings when unpacking boxes as root [GH-10707]
- core: Write metadata.json file when packaging box [GH-10706]
- core: Remove whitespace from id file on load [GH-10727]
- guest/coreos: Update network configuration and hostname setting [GH-10752]
- guest/freebsd: Add proper VirtualBox share folders support for FreeBSD guests [GH-10717]
- guest/freebsd: Add unmount share folder for VirtualBox guests [GH-10761]
- guest/freebsd: Simplify network interface listing when configuring networks [GH-10763]
Expand All @@ -19,6 +20,8 @@ BUG FIXES:
- communicator/ssh: Remove net/sftp loading to prevent loading errors [GH-10745]
- core/triggers: Fix typo in UI output [GH-10748]
- guest/void: Fix NFS capability detection [GH-10713]
- provider/virtualbox: Ensure non-existent machines do not attempt to list snapshots [GH-10784]
- provisioner/ansible: Fix pip installer hardcoded curl get_pip.py piped to python [GH-10625]

## 2.2.4 (February 27, 2019)

Expand Down
19 changes: 19 additions & 0 deletions lib/vagrant/util/guest_inspection.rb
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,25 @@ def systemd_networkd?(comm)
comm.test("systemctl -q is-active systemd-networkd.service", sudo: true)
end

# Check if a unit file with the given name is defined. Name can
# be a pattern or explicit name.
#
# @param [Vagrant::Plugin::V2::Communicator] comm Guest communicator
# @param [String] name Name or pattern to search
# @return [Boolean]
def systemd_unit_file?(comm, name)
comm.test("systemctl -q list-unit-files | grep \"#{name}\"")
end

# Check if a unit is currently active within systemd
#
# @param [Vagrant::Plugin::V2::Communicator] comm Guest communicator
# @param [String] name Name or pattern to search
# @return [Boolean]
def systemd_unit?(comm, name)
comm.test("systemctl -q list-units | grep \"#{name}\"")
end

# Check if given service is controlled by systemd
#
# @param [Vagrant::Plugin::V2::Communicator] comm Guest communicator
Expand Down
4 changes: 3 additions & 1 deletion plugins/commands/snapshot/command/pop.rb
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,10 @@ def execute
opts = OptionParser.new do |o|
o.banner = "Usage: vagrant snapshot pop [options] [vm-name]"
o.separator ""
o.separator "Restore state that was pushed onto the snapshot stack"
o.separator "with `vagrant snapshot push`."
o.separator ""
build_start_options(o, options)
o.separator "Restore state that was pushed with `vagrant snapshot push`."

o.on("--no-delete", "Don't delete the snapshot after the restore") do
options[:snapshot_delete] = false
Expand Down
31 changes: 24 additions & 7 deletions plugins/guests/coreos/cap/change_host_name.rb
Original file line number Diff line number Diff line change
@@ -1,18 +1,35 @@
require "tempfile"
require "yaml"

module VagrantPlugins
module GuestCoreOS
module Cap
class ChangeHostName
extend Vagrant::Util::GuestInspection::Linux

def self.change_host_name(machine, name)
comm = machine.communicate

if !comm.test("hostname -f | grep '^#{name}$'", sudo: false)
basename = name.split(".", 2)[0]
comm.sudo("hostname '#{basename}'")
if systemd_unit_file?(comm, "system-cloudinit*")
file = Tempfile.new("vagrant-coreos-hostname")
file.puts("#cloud-config\n")
file.puts({"hostname" => name}.to_yaml)
file.close

dst = "/var/tmp/hostname.yml"
svc_path = dst.tr("/", "-")[1..-1]
comm.upload(file.path, dst)
comm.sudo("systemctl start system-cloudinit@#{svc_path}.service")
else
if !comm.test("hostname -f | grep '^#{name}$'", sudo: false)
basename = name.split(".", 2)[0]
comm.sudo("hostname '#{basename}'")

# Note that when working with CoreOS, we explicitly do not add the
# entry to /etc/hosts because this file does not exist on CoreOS.
# We could create it, but the recommended approach on CoreOS is to
# use Fleet to manage /etc/hosts files.
# Note that when working with CoreOS, we explicitly do not add the
# entry to /etc/hosts because this file does not exist on CoreOS.
# We could create it, but the recommended approach on CoreOS is to
# use Fleet to manage /etc/hosts files.
end
end
end
end
Expand Down
112 changes: 48 additions & 64 deletions plugins/guests/coreos/cap/configure_networks.rb
Original file line number Diff line number Diff line change
Expand Up @@ -6,79 +6,63 @@ module VagrantPlugins
module GuestCoreOS
module Cap
class ConfigureNetworks
include Vagrant::Util
extend Vagrant::Util::GuestInspection::Linux

def self.configure_networks(machine, networks)
machine.communicate.tap do |comm|
# Read network interface names
interfaces = []
comm.sudo("ifconfig | grep -E '(e[n,t][h,s,p][[:digit:]]([a-z][[:digit:]])?)' | cut -f1 -d:") do |_, result|
interfaces = result.split("\n")
end

primary_machine_config = machine.env.active_machines.first
primary_machine = machine.env.machine(*primary_machine_config, true)
DEFAULT_ENVIRONMENT_IP = "127.0.0.1".freeze

primary_machine_ip = get_ip(primary_machine)
current_ip = get_ip(machine)
if current_ip == primary_machine_ip
entry = TemplateRenderer.render("guests/coreos/etcd.service", options: {
my_ip: current_ip,
})
else
connection_string = "#{primary_machine_ip}:7001"
entry = TemplateRenderer.render("guests/coreos/etcd.service", options: {
connection_string: connection_string,
my_ip: current_ip,
})
end

Tempfile.open("vagrant-coreos-configure-networks") do |f|
f.binmode
f.write(entry)
f.fsync
f.close
comm.upload(f.path, "/tmp/etcd-cluster.service")
def self.configure_networks(machine, networks)
cloud_config = {}
# Locate configured IP addresses to drop in /etc/environment
# for export. If no addresses found, fall back to default
public_ip = catch(:public_ip) do
machine.config.vm.networks.each do |type, opts|
next if type != :public_network
throw(:public_ip, opts[:ip]) if opts[:ip]
end

# Build a list of commands
commands = []

# Stop default systemd
commands << "systemctl stop etcd"

# Configure interfaces
# FIXME: fix matching of interfaces with IP addresses
networks.each do |network|
iface = interfaces[network[:interface].to_i]
commands << "ifconfig #{iface} #{network[:ip]} netmask #{network[:netmask]}".squeeze(" ")
DEFAULT_ENVIRONMENT_IP
end
private_ip = catch(:private_ip) do
machine.config.vm.networks.each do |type, opts|
next if type != :private_network
throw(:private_ip, opts[:ip]) if opts[:ip]
end

commands << <<-EOH.gsub(/^ {14}/, '')
mv /tmp/etcd-cluster.service /media/state/units/
systemctl restart local-enable.service
# Restart default etcd
systemctl start etcd
EOH

# Run all network configuration commands in one communicator session.
comm.sudo(commands.join("\n"))
public_ip
end
end

private
cloud_config["write_files"] = [
{"path" => "/etc/environment",
"content" => "COREOS_PUBLIC_IPV4=#{public_ip}\nCOREOS_PRIVATE_IPV4=#{private_ip}"}
]

def self.get_ip(machine)
ip = nil
machine.config.vm.networks.each do |type, opts|
if type == :private_network && opts[:ip]
ip = opts[:ip]
break
# Generate configuration for any static network interfaces
# which have been defined
interfaces = machine.guest.capability(:network_interfaces)
units = networks.map do |network|
iface = network[:interface].to_i
unit_name = "50-vagrant#{iface}.network"
device = interfaces[iface]
if network[:type].to_s == "dhcp"
network_content = "DHCP=yes"
else
prefix = IPAddr.new("255.255.255.255/#{network[:netmask]}").to_i.to_s(2).count("1")
address = "#{network[:ip]}/#{prefix}"
network_content = "Address=#{address}"
end
{"name" => unit_name,
"runtime" => "no",
"content" => "[Match]\nName=#{device}\n[Network]\n#{network_content}"}
end
cloud_config["coreos"] = {"units" => units.compact}

# Upload configuration and apply
file = Tempfile.new("vagrant-coreos-networks")
file.puts("#cloud-config\n")
file.puts(cloud_config.to_yaml)
file.close

ip
dst = "/var/tmp/networks.yml"
svc_path = dst.tr("/", "-")[1..-1]
machine.communicate.upload(file.path, dst)
machine.communicate.sudo("systemctl start system-cloudinit@#{svc_path}.service")
end
end
end
Expand Down
1 change: 1 addition & 0 deletions plugins/providers/virtualbox/cap.rb
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ def self.nic_mac_addresses(machine)
#
# @return [Array<String>] Snapshot Name
def self.snapshot_list(machine)
return [] if machine.id.nil?
machine.provider.driver.list_snapshots(machine.id)
end
end
Expand Down
10 changes: 5 additions & 5 deletions plugins/provisioners/ansible/cap/guest/debian/ansible_install.rb
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,13 @@ module Debian
module AnsibleInstall


def self.ansible_install(machine, install_mode, ansible_version, pip_args)
def self.ansible_install(machine, install_mode, ansible_version, pip_args, pip_install_cmd="")
case install_mode
when :pip
pip_setup machine
pip_setup machine, pip_install_cmd
Pip::pip_install machine, "ansible", ansible_version, pip_args, true
when :pip_args_only
pip_setup machine
pip_setup machine, pip_install_cmd
Pip::pip_install machine, "", "", pip_args, false
else
ansible_apt_install machine
Expand All @@ -36,10 +36,10 @@ def self.ansible_apt_install(machine)
machine.communicate.sudo "apt-get install -y -qq ansible"
end

def self.pip_setup(machine)
def self.pip_setup(machine, pip_install_cmd="")
machine.communicate.sudo "apt-get update -y -qq"
machine.communicate.sudo "apt-get install -y -qq build-essential curl git libssl-dev libffi-dev python-dev"
Pip::get_pip machine
Pip::get_pip machine, pip_install_cmd
end

end
Expand Down
10 changes: 5 additions & 5 deletions plugins/provisioners/ansible/cap/guest/fedora/ansible_install.rb
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,13 @@ module Guest
module Fedora
module AnsibleInstall

def self.ansible_install(machine, install_mode, ansible_version, pip_args)
def self.ansible_install(machine, install_mode, ansible_version, pip_args, pip_install_cmd="")
case install_mode
when :pip
pip_setup machine
pip_setup machine, pip_install_cmd
Pip::pip_install machine, "ansible", ansible_version, pip_args, true
when :pip_args_only
pip_setup machine
pip_setup machine, pip_install_cmd
Pip::pip_install machine, "", "", pip_args, false
else
rpm_package_manager = Facts::rpm_package_manager(machine)
Expand All @@ -25,11 +25,11 @@ def self.ansible_install(machine, install_mode, ansible_version, pip_args)

private

def self.pip_setup(machine)
def self.pip_setup(machine, pip_install_cmd="")
rpm_package_manager = Facts::rpm_package_manager(machine)

machine.communicate.sudo "#{rpm_package_manager} install -y curl gcc gmp-devel libffi-devel openssl-devel python-crypto python-devel python-dnf python-setuptools redhat-rpm-config"
Pip::get_pip machine
Pip::get_pip machine, pip_install_cmd
end

end
Expand Down
17 changes: 15 additions & 2 deletions plugins/provisioners/ansible/cap/guest/pip/pip.rb
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ module Cap
module Guest
module Pip

DEFAULT_PIP_INSTALL_CMD = "curl https://bootstrap.pypa.io/get-pip.py | sudo python".freeze

def self.pip_install(machine, package = "", version = "", pip_args = "", upgrade = true)
upgrade_arg = "--upgrade" if upgrade
version_arg = ""
Expand All @@ -18,9 +20,20 @@ def self.pip_install(machine, package = "", version = "", pip_args = "", upgrade
machine.communicate.sudo "pip install #{args_array.join(' ')}"
end

def self.get_pip(machine)
def self.get_pip(machine, pip_install_cmd=DEFAULT_PIP_INSTALL_CMD)

# The objective here is to get pip either by default
# or by the argument passed in. The objective is not
# to circumvent the pip setup by passing in nothing.
# Thus, we stick with the default on an empty string.
# Typecast added in the check for safety.

if pip_install_cmd.to_s.empty?
pip_install_cmd=DEFAULT_PIP_INSTALL_CMD
end

machine.ui.detail I18n.t("vagrant.provisioners.ansible.installing_pip")
machine.communicate.execute "curl https://bootstrap.pypa.io/get-pip.py | sudo python"
machine.communicate.execute pip_install_cmd
end

end
Expand Down
10 changes: 5 additions & 5 deletions plugins/provisioners/ansible/cap/guest/redhat/ansible_install.rb
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,13 @@ module Guest
module RedHat
module AnsibleInstall

def self.ansible_install(machine, install_mode, ansible_version, pip_args)
def self.ansible_install(machine, install_mode, ansible_version, pip_args, pip_install_cmd="")
case install_mode
when :pip
pip_setup machine
pip_setup machine, pip_install_cmd
Pip::pip_install machine, "ansible", ansible_version, pip_args, true
when :pip_args_only
pip_setup machine
pip_setup machine, pip_install_cmd
Pip::pip_install machine, "", "", pip_args, false
else
ansible_rpm_install machine
Expand All @@ -33,11 +33,11 @@ def self.ansible_rpm_install(machine)
machine.communicate.sudo "#{rpm_package_manager} -y --enablerepo=epel install ansible"
end

def self.pip_setup(machine)
def self.pip_setup(machine, pip_install_cmd="")
rpm_package_manager = Facts::rpm_package_manager(machine)

machine.communicate.sudo("#{rpm_package_manager} -y install curl gcc libffi-devel openssl-devel python-crypto python-devel python-setuptools")
Pip::get_pip machine
Pip::get_pip machine, pip_install_cmd
end

end
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,9 @@ module Guest
module Ubuntu
module AnsibleInstall

def self.ansible_install(machine, install_mode, ansible_version, pip_args)
def self.ansible_install(machine, install_mode, ansible_version, pip_args, pip_install_cmd="")
if install_mode != :default
Debian::AnsibleInstall::ansible_install machine, install_mode, ansible_version, pip_args
Debian::AnsibleInstall::ansible_install machine, install_mode, ansible_version, pip_args, pip_install_cmd
else
ansible_apt_install machine
end
Expand Down
3 changes: 3 additions & 0 deletions plugins/provisioners/ansible/config/guest.rb
Original file line number Diff line number Diff line change
Expand Up @@ -11,13 +11,15 @@ class Guest < Base
attr_accessor :install
attr_accessor :install_mode
attr_accessor :pip_args
attr_accessor :pip_install_cmd

def initialize
super

@install = UNSET_VALUE
@install_mode = UNSET_VALUE
@pip_args = UNSET_VALUE
@pip_install_cmd = UNSET_VALUE
@provisioning_path = UNSET_VALUE
@tmp_path = UNSET_VALUE
end
Expand All @@ -28,6 +30,7 @@ def finalize!
@install = true if @install == UNSET_VALUE
@install_mode = :default if @install_mode == UNSET_VALUE
@pip_args = "" if @pip_args == UNSET_VALUE
@pip_install_cmd = "" if @pip_args == UNSET_VALUE
@provisioning_path = "/vagrant" if provisioning_path == UNSET_VALUE
@tmp_path = "/tmp/vagrant-ansible" if tmp_path == UNSET_VALUE
end
Expand Down

0 comments on commit 28f6bdf

Please sign in to comment.