From b84acaed3cc8ad60233c4887ef9b87ab72f111e4 Mon Sep 17 00:00:00 2001 From: James Nugent Date: Wed, 24 May 2017 12:29:46 -0500 Subject: [PATCH] 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). --- plugins/guests/smartos/cap/halt.rb | 2 +- .../guests/smartos/cap/insert_public_key.rb | 28 ++++++++++++++ .../guests/smartos/cap/remove_public_key.rb | 25 ++++++++++++ plugins/guests/smartos/plugin.rb | 11 ++++++ .../plugins/guests/smartos/cap/halt_test.rb | 2 +- .../smartos/cap/insert_public_key_test.rb | 38 +++++++++++++++++++ .../smartos/cap/remove_public_key_test.rb | 34 +++++++++++++++++ 7 files changed, 138 insertions(+), 2 deletions(-) create mode 100644 plugins/guests/smartos/cap/insert_public_key.rb create mode 100644 plugins/guests/smartos/cap/remove_public_key.rb create mode 100644 test/unit/plugins/guests/smartos/cap/insert_public_key_test.rb create mode 100644 test/unit/plugins/guests/smartos/cap/remove_public_key_test.rb diff --git a/plugins/guests/smartos/cap/halt.rb b/plugins/guests/smartos/cap/halt.rb index 7e10ee2cc..bb764b4c3 100644 --- a/plugins/guests/smartos/cap/halt.rb +++ b/plugins/guests/smartos/cap/halt.rb @@ -10,7 +10,7 @@ module VagrantPlugins # does not exist in /etc/user_attr. TODO begin 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 # Ignore, this probably means connection closed because it # shut down. diff --git a/plugins/guests/smartos/cap/insert_public_key.rb b/plugins/guests/smartos/cap/insert_public_key.rb new file mode 100644 index 000000000..6c0c38dff --- /dev/null +++ b/plugins/guests/smartos/cap/insert_public_key.rb @@ -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 diff --git a/plugins/guests/smartos/cap/remove_public_key.rb b/plugins/guests/smartos/cap/remove_public_key.rb new file mode 100644 index 000000000..d01363dd0 --- /dev/null +++ b/plugins/guests/smartos/cap/remove_public_key.rb @@ -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 diff --git a/plugins/guests/smartos/plugin.rb b/plugins/guests/smartos/plugin.rb index 0ed34941f..6f5365af2 100644 --- a/plugins/guests/smartos/plugin.rb +++ b/plugins/guests/smartos/plugin.rb @@ -31,11 +31,21 @@ module VagrantPlugins Cap::Halt end + guest_capability(:smartos, :insert_public_key) do + require_relative "cap/insert_public_key" + Cap::InsertPublicKey + end + guest_capability(:smartos, :mount_nfs_folder) do require_relative "cap/mount_nfs" Cap::MountNFS end + guest_capability(:smartos, :remove_public_key) do + require_relative "cap/remove_public_key" + Cap::RemovePublicKey + end + guest_capability(:smartos, :rsync_installed) do require_relative "cap/rsync" Cap::RSync @@ -58,3 +68,4 @@ module VagrantPlugins end end end + diff --git a/test/unit/plugins/guests/smartos/cap/halt_test.rb b/test/unit/plugins/guests/smartos/cap/halt_test.rb index 137749489..08b563c39 100644 --- a/test/unit/plugins/guests/smartos/cap/halt_test.rb +++ b/test/unit/plugins/guests/smartos/cap/halt_test.rb @@ -5,7 +5,7 @@ describe "VagrantPlugins::GuestSmartos::Cap::Halt" do let(:machine) { double("machine") } let(:config) { double("config", smartos: double("smartos", suexec_cmd: 'pfexec')) } 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 machine.stub(:communicate).and_return(communicator) diff --git a/test/unit/plugins/guests/smartos/cap/insert_public_key_test.rb b/test/unit/plugins/guests/smartos/cap/insert_public_key_test.rb new file mode 100644 index 000000000..917f0baa9 --- /dev/null +++ b/test/unit/plugins/guests/smartos/cap/insert_public_key_test.rb @@ -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 diff --git a/test/unit/plugins/guests/smartos/cap/remove_public_key_test.rb b/test/unit/plugins/guests/smartos/cap/remove_public_key_test.rb new file mode 100644 index 000000000..3984173bd --- /dev/null +++ b/test/unit/plugins/guests/smartos/cap/remove_public_key_test.rb @@ -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