guests/smartos: Add/fix various guest capabilities

This commit adds/changes the following for SmartOS guests:

- modifies the "Halt" capability to use /usr/sbin/poweroff in preference
  to /usr/sbin/shutdown with parameters, and modifies the associated
  test.

- adds an "InsertPublicKey" capability and tests.

- adds a "RemovePublicKey" capability and tests.

With this commit applied, the vast majority of typical Vagrant workflow
is available to SmartOS global zone guests (provided NFS mounts are used
rather than VMWare shared folders).
This commit is contained in:
James Nugent 2017-05-24 12:29:46 -05:00
parent 2995b60925
commit b84acaed3c
7 changed files with 138 additions and 2 deletions

View File

@ -10,7 +10,7 @@ module VagrantPlugins
# does not exist in /etc/user_attr. TODO # does not exist in /etc/user_attr. TODO
begin begin
machine.communicate.execute( machine.communicate.execute(
"#{machine.config.smartos.suexec_cmd} /usr/sbin/shutdown -y -i5 -g0") "#{machine.config.smartos.suexec_cmd} /usr/sbin/poweroff")
rescue IOError, Vagrant::Errors::SSHDisconnected rescue IOError, Vagrant::Errors::SSHDisconnected
# Ignore, this probably means connection closed because it # Ignore, this probably means connection closed because it
# shut down. # shut down.

View File

@ -0,0 +1,28 @@
require "vagrant/util/shell_quote"
module VagrantPlugins
module GuestSmartos
module Cap
class InsertPublicKey
def self.insert_public_key(machine, contents)
contents = contents.chomp
contents = Vagrant::Util::ShellQuote.escape(contents, "'")
machine.communicate.tap do |comm|
comm.execute <<-EOH.sub(/^ */, '')
if [ -d /usbkey ] && [ "$(zonename)" == "global" ] ; then
printf '#{contents}\\n' >> /usbkey/config.inc/authorized_keys
cp /usbkey/config.inc/authorized_keys ~/.ssh/authorized_keys
else
mkdir -p ~/.ssh
chmod 0700 ~/.ssh
printf '#{contents}\\n' >> ~/.ssh/authorized_keys
chmod 0600 ~/.ssh/authorized_keys
fi
EOH
end
end
end
end
end
end

View File

@ -0,0 +1,25 @@
require "vagrant/util/shell_quote"
module VagrantPlugins
module GuestSmartos
module Cap
class RemovePublicKey
def self.remove_public_key(machine, contents)
contents = contents.chomp
contents = Vagrant::Util::ShellQuote.escape(contents, "'")
machine.communicate.tap do |comm|
comm.execute <<-EOH.sub(/^ */, '')
if test -f /usbkey/config.inc/authorized_keys ; then
sed -i '' '/^.*#{contents}.*$/d' /usbkey/config.inc/authorized_keys
fi
if test -f ~/.ssh/authorized_keys ; then
sed -i '' '/^.*#{contents}.*$/d' ~/.ssh/authorized_keys
fi
EOH
end
end
end
end
end
end

View File

@ -31,11 +31,21 @@ module VagrantPlugins
Cap::Halt Cap::Halt
end end
guest_capability(:smartos, :insert_public_key) do
require_relative "cap/insert_public_key"
Cap::InsertPublicKey
end
guest_capability(:smartos, :mount_nfs_folder) do guest_capability(:smartos, :mount_nfs_folder) do
require_relative "cap/mount_nfs" require_relative "cap/mount_nfs"
Cap::MountNFS Cap::MountNFS
end end
guest_capability(:smartos, :remove_public_key) do
require_relative "cap/remove_public_key"
Cap::RemovePublicKey
end
guest_capability(:smartos, :rsync_installed) do guest_capability(:smartos, :rsync_installed) do
require_relative "cap/rsync" require_relative "cap/rsync"
Cap::RSync Cap::RSync
@ -58,3 +68,4 @@ module VagrantPlugins
end end
end end
end end

View File

@ -5,7 +5,7 @@ describe "VagrantPlugins::GuestSmartos::Cap::Halt" do
let(:machine) { double("machine") } let(:machine) { double("machine") }
let(:config) { double("config", smartos: double("smartos", suexec_cmd: 'pfexec')) } let(:config) { double("config", smartos: double("smartos", suexec_cmd: 'pfexec')) }
let(:communicator) { VagrantTests::DummyCommunicator::Communicator.new(machine) } let(:communicator) { VagrantTests::DummyCommunicator::Communicator.new(machine) }
let(:shutdown_command){ "pfexec /usr/sbin/shutdown -y -i5 -g0" } let(:shutdown_command){ "pfexec /usr/sbin/poweroff" }
before do before do
machine.stub(:communicate).and_return(communicator) machine.stub(:communicate).and_return(communicator)

View File

@ -0,0 +1,38 @@
require_relative "../../../../base"
describe "VagrantPlugins::GuestSmartos::Cap::InsertPublicKey" do
let(:caps) do
VagrantPlugins::GuestSmartos::Plugin
.components
.guest_capabilities[:smartos]
end
let(:machine) { double("machine") }
let(:comm) { VagrantTests::DummyCommunicator::Communicator.new(machine) }
before do
allow(machine).to receive(:communicate).and_return(comm)
end
after do
comm.verify_expectations!
end
describe ".insert_public_key" do
let(:cap) { caps.get(:insert_public_key) }
it "inserts the public key" do
cap.insert_public_key(machine, "ssh-rsa ...")
expect(comm.received_commands[0]).to match(/if \[ -d \/usbkey \] && \[ "\$\(zonename\)" == "global" \] ; then/)
expect(comm.received_commands[0]).to match(/printf 'ssh-rsa ...\\n' >> \/usbkey\/config.inc\/authorized_keys/)
expect(comm.received_commands[0]).to match(/cp \/usbkey\/config.inc\/authorized_keys ~\/.ssh\/authorized_keys/)
expect(comm.received_commands[0]).to match(/else/)
expect(comm.received_commands[0]).to match(/mkdir -p ~\/.ssh/)
expect(comm.received_commands[0]).to match(/chmod 0700 ~\/.ssh/)
expect(comm.received_commands[0]).to match(/printf 'ssh-rsa ...\\n' >> ~\/.ssh\/authorized_keys/)
expect(comm.received_commands[0]).to match(/chmod 0600 ~\/.ssh\/authorized_keys/)
expect(comm.received_commands[0]).to match(/fi/)
end
end
end

View File

@ -0,0 +1,34 @@
require_relative "../../../../base"
describe "VagrantPlugins::GuestSmartos::Cap::RemovePublicKey" do
let(:caps) do
VagrantPlugins::GuestSmartos::Plugin
.components
.guest_capabilities[:smartos]
end
let(:machine) { double("machine") }
let(:comm) { VagrantTests::DummyCommunicator::Communicator.new(machine) }
before do
allow(machine).to receive(:communicate).and_return(comm)
end
after do
comm.verify_expectations!
end
describe ".remove_public_key" do
let(:cap) { caps.get(:remove_public_key) }
it "removes the public key" do
cap.remove_public_key(machine, "ssh-rsa keyvalue comment")
expect(comm.received_commands[0]).to match(/if test -f \/usbkey\/config.inc\/authorized_keys ; then/)
expect(comm.received_commands[0]).to match(/sed -i '' '\/\^.*ssh-rsa keyvalue comment.*\$\/d' \/usbkey\/config.inc\/authorized_keys/)
expect(comm.received_commands[0]).to match(/fi/)
expect(comm.received_commands[0]).to match(/if test -f ~\/.ssh\/authorized_keys ; then/)
expect(comm.received_commands[0]).to match(/sed -i '' '\/\^.*ssh-rsa keyvalue comment.*\$\/d' ~\/.ssh\/authorized_keys/)
expect(comm.received_commands[0]).to match(/fi/)
end
end
end