Update linux host NFS capability

Add support for systemd detection and using correct method
for starting/checking host nfs service.
This commit is contained in:
Chris Roberts 2017-08-30 16:59:46 -07:00
parent 6673c14916
commit fcd1aee9bb
7 changed files with 115 additions and 26 deletions

View File

@ -8,7 +8,7 @@ module Vagrant
## systemd helpers ## systemd helpers
# systemd is in used # systemd is in use
# #
# @return [Boolean] # @return [Boolean]
def systemd?(comm) def systemd?(comm)

View File

@ -448,6 +448,19 @@ module Vagrant
end end
end end
# systemd is in use
def systemd?
if !defined?(@_systemd)
if !windows?
result = Vagrant::Util::Subprocess.execute("ps", "-o", "comm=", "1")
@_systemd = result.stdout.chomp == "systemd"
else
@_systemd = false
end
end
@_systemd
end
# @private # @private
# Reset the cached values for platform. This is not considered a public # Reset the cached values for platform. This is not considered a public
# API and should only be used for testing. # API and should only be used for testing.

View File

@ -6,30 +6,23 @@ module VagrantPlugins
module Cap module Cap
class NFS class NFS
def self.nfs_check_command(env) def self.nfs_check_command(env)
if systemd? if Vagrant::Util::Platform.systemd?
return "#{systemctl_path} status --no-pager nfs-server.service" "#{systemctl_path} status --no-pager nfs-server.service"
else else
return "/etc/init.d/nfs status" "/etc/init.d/nfs status"
end end
end end
def self.nfs_start_command(env) def self.nfs_start_command(env)
if systemd? if Vagrant::Util::Platform.systemd?
return "#{systemctl_path} start rpcbind nfs-server.service" "#{systemctl_path} start rpcbind nfs-server.service"
else else
return "/etc/init.d/nfs restart" "/etc/init.d/nfs restart"
end end
end end
protected protected
# This tests to see if systemd is used on the system. This is used
# in newer versions of Arch, and requires a change in behavior.
def self.systemd?
result = Vagrant::Util::Subprocess.execute("ps", "-o", "comm=", "1")
return result.stdout.chomp == "systemd"
end
def self.systemctl_path def self.systemctl_path
path = Vagrant::Util::Which.which("systemctl") path = Vagrant::Util::Which.which("systemctl")
return path if path return path if path

View File

@ -1,3 +1,4 @@
require "shellwords"
require "vagrant/util" require "vagrant/util"
require "vagrant/util/shell_quote" require "vagrant/util/shell_quote"
require "vagrant/util/retryable" require "vagrant/util/retryable"
@ -15,11 +16,19 @@ module VagrantPlugins
end end
def self.nfs_check_command(env) def self.nfs_check_command(env)
"/etc/init.d/nfs-kernel-server status" if Vagrant::Util::Platform.systemd?
"systemctl status --no-pager nfs-server.service"
else
"/etc/init.d/nfs-kernel-server status"
end
end end
def self.nfs_start_command(env) def self.nfs_start_command(env)
"/etc/init.d/nfs-kernel-server start" if Vagrant::Util::Platform.systemd?
"systemctl start nfs-server.service"
else
"/etc/init.d/nfs-kernel-server start"
end
end end
def self.nfs_export(env, ui, id, ips, folders) def self.nfs_export(env, ui, id, ips, folders)
@ -44,16 +53,20 @@ module VagrantPlugins
nfs_write_exports(output) nfs_write_exports(output)
if nfs_running?(nfs_check_command) if nfs_running?(nfs_check_command)
system("sudo #{nfs_apply_command}") Vagrant::Util::Subprocess.execute("sudo", *Shellwords.split(nfs_apply_command)).exit_code == 0
else else
system("sudo #{nfs_start_command}") Vagrant::Util::Subprocess.execute("sudo", *Shellwords.split(nfs_start_command)).exit_code == 0
end end
end end
def self.nfs_installed(environment) def self.nfs_installed(environment)
retryable(tries: 10, on: TypeError) do if Vagrant::Util::Platform.systemd?
# Check procfs to see if NFSd is a supported filesystem Vagrant::Util::Subprocess.execute("/bin/sh", "-c",
system("cat /proc/filesystems | grep nfsd > /dev/null 2>&1") "systemctl --no-pager --no-legend --plain list-unit-files --all --type=service " \
"| grep nfs-server.service").exit_code == 0
else
Vagrant::Util::Subprocess.execute("modinfo", "nfsd").exit_code == 0 ||
Vagrant::Util::Subprocess.execute("grep", "nfsd", "/proc/filesystems").exit_code == 0
end end
end end
@ -218,7 +231,7 @@ module VagrantPlugins
end end
def self.nfs_running?(check_command) def self.nfs_running?(check_command)
system(check_command) Vagrant::Util::Subprocess.execute(*Shellwords.split(check_command)).exit_code == 0
end end
end end
end end

View File

@ -5,11 +5,19 @@ module VagrantPlugins
module Cap module Cap
class NFS class NFS
def self.nfs_check_command(env) def self.nfs_check_command(env)
"#{nfs_server_binary} status" if Vagrant::Util::Platform.systemd?
"systemctl status --no-pager nfs-server.service"
else
"#{nfs_server_binary} status"
end
end end
def self.nfs_start_command(env) def self.nfs_start_command(env)
"#{nfs_server_binary} start" if Vagrant::Util::Platform.systemd?
"systemctl start nfs-server.service"
else
"#{nfs_server_binary} start"
end
end end
protected protected

View File

@ -33,6 +33,44 @@ describe VagrantPlugins::HostLinux::Cap::NFS do
@tmp_exports = nil @tmp_exports = nil
end end
describe ".nfs_check_command" do
let(:cap){ caps.get(:nfs_check_command) }
context "without systemd" do
before{ expect(Vagrant::Util::Platform).to receive(:systemd?).and_return(false) }
it "should use init.d script" do
expect(cap.nfs_check_command(env)).to include("init.d")
end
end
context "with systemd" do
before{ expect(Vagrant::Util::Platform).to receive(:systemd?).and_return(true) }
it "should use systemctl" do
expect(cap.nfs_check_command(env)).to include("systemctl")
end
end
end
describe ".nfs_start_command" do
let(:cap){ caps.get(:nfs_start_command) }
context "without systemd" do
before{ expect(Vagrant::Util::Platform).to receive(:systemd?).and_return(false) }
it "should use init.d script" do
expect(cap.nfs_start_command(env)).to include("init.d")
end
end
context "with systemd" do
before{ expect(Vagrant::Util::Platform).to receive(:systemd?).and_return(true) }
it "should use systemctl" do
expect(cap.nfs_start_command(env)).to include("systemctl")
end
end
end
describe ".nfs_export" do describe ".nfs_export" do
let(:cap){ caps.get(:nfs_export) } let(:cap){ caps.get(:nfs_export) }
@ -43,8 +81,9 @@ describe VagrantPlugins::HostLinux::Cap::NFS do
allow(host).to receive(:capability).with(:nfs_check_command).and_return("/bin/true") allow(host).to receive(:capability).with(:nfs_check_command).and_return("/bin/true")
allow(host).to receive(:capability).with(:nfs_start_command).and_return("/bin/true") allow(host).to receive(:capability).with(:nfs_start_command).and_return("/bin/true")
allow(ui).to receive(:info) allow(ui).to receive(:info)
allow(cap).to receive(:system).with("sudo /bin/true").and_return(true) allow(Vagrant::Util::Subprocess).to receive(:execute).and_call_original
allow(cap).to receive(:system).with("/bin/true").and_return(true) allow(Vagrant::Util::Subprocess).to receive(:execute).with("sudo", "/bin/true").and_return(double(:result, exit_code: 0))
allow(Vagrant::Util::Subprocess).to receive(:execute).with("/bin/true").and_return(double(:result, exit_code: 0))
end end
it "should export new entries" do it "should export new entries" do

View File

@ -133,4 +133,27 @@ describe Vagrant::Util::Platform do
end end
end end
end end
describe ".systemd?" do
before{ allow(subject).to receive(:windows?).and_return(false) }
after{ subject.reset! }
context "on windows" do
before{ expect(subject).to receive(:windows?).and_return(true) }
it "should return false" do
expect(subject.systemd?).to be_falsey
end
end
it "should return true if systemd is in use" do
expect(Vagrant::Util::Subprocess).to receive(:execute).and_return(double(:result, stdout: "systemd"))
expect(subject.systemd?).to be_truthy
end
it "should return false if systemd is not in use" do
expect(Vagrant::Util::Subprocess).to receive(:execute).and_return(double(:result, stdout: "other"))
expect(subject.systemd?).to be_falsey
end
end
end end