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 is in used
# systemd is in use
#
# @return [Boolean]
def systemd?(comm)

View File

@ -448,6 +448,19 @@ module Vagrant
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
# Reset the cached values for platform. This is not considered a public
# API and should only be used for testing.

View File

@ -6,30 +6,23 @@ module VagrantPlugins
module Cap
class NFS
def self.nfs_check_command(env)
if systemd?
return "#{systemctl_path} status --no-pager nfs-server.service"
if Vagrant::Util::Platform.systemd?
"#{systemctl_path} status --no-pager nfs-server.service"
else
return "/etc/init.d/nfs status"
"/etc/init.d/nfs status"
end
end
def self.nfs_start_command(env)
if systemd?
return "#{systemctl_path} start rpcbind nfs-server.service"
if Vagrant::Util::Platform.systemd?
"#{systemctl_path} start rpcbind nfs-server.service"
else
return "/etc/init.d/nfs restart"
"/etc/init.d/nfs restart"
end
end
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
path = Vagrant::Util::Which.which("systemctl")
return path if path

View File

@ -1,3 +1,4 @@
require "shellwords"
require "vagrant/util"
require "vagrant/util/shell_quote"
require "vagrant/util/retryable"
@ -15,11 +16,19 @@ module VagrantPlugins
end
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
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
def self.nfs_export(env, ui, id, ips, folders)
@ -44,16 +53,20 @@ module VagrantPlugins
nfs_write_exports(output)
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
system("sudo #{nfs_start_command}")
Vagrant::Util::Subprocess.execute("sudo", *Shellwords.split(nfs_start_command)).exit_code == 0
end
end
def self.nfs_installed(environment)
retryable(tries: 10, on: TypeError) do
# Check procfs to see if NFSd is a supported filesystem
system("cat /proc/filesystems | grep nfsd > /dev/null 2>&1")
if Vagrant::Util::Platform.systemd?
Vagrant::Util::Subprocess.execute("/bin/sh", "-c",
"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
@ -218,7 +231,7 @@ module VagrantPlugins
end
def self.nfs_running?(check_command)
system(check_command)
Vagrant::Util::Subprocess.execute(*Shellwords.split(check_command)).exit_code == 0
end
end
end

View File

@ -5,11 +5,19 @@ module VagrantPlugins
module Cap
class NFS
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
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
protected

View File

@ -33,6 +33,44 @@ describe VagrantPlugins::HostLinux::Cap::NFS do
@tmp_exports = nil
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
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_start_command).and_return("/bin/true")
allow(ui).to receive(:info)
allow(cap).to receive(:system).with("sudo /bin/true").and_return(true)
allow(cap).to receive(:system).with("/bin/true").and_return(true)
allow(Vagrant::Util::Subprocess).to receive(:execute).and_call_original
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
it "should export new entries" do

View File

@ -133,4 +133,27 @@ describe Vagrant::Util::Platform do
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