specinfra 2.88.0 → 2.88.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 5653294259d7e35a26af3b0841cb507c5a7bd69668d022af79f4f32ae7299810
4
- data.tar.gz: c0c2cef79bb876c01ce2dc8fbb21ab138a6a0e367186c34ba94e7f35772ec12d
3
+ metadata.gz: 48bd86bb191af636b611f48c76a248d5171bc0d54573fa7af8063ed6c43aa7ce
4
+ data.tar.gz: 249f7068c068d8ce33dea8388408e34eacafe48efe1c3df97392ba91b975ee62
5
5
  SHA512:
6
- metadata.gz: 18f97e98b911c4354b87de096cc6af94d8d4c7e793d8fab46ed72cea47b95ee4803cce160e2dcd54d7c61e3b076877018d904641050d99fa28b3a354afff4a58
7
- data.tar.gz: 14eebac1837c79a17e352eada2496dbea730463de4a94782fe366e6f72f172e37715ec7c6068bc1c63259882f0865124f8fafc12d61171e6dc586b2d8c462acf
6
+ metadata.gz: fd3e32a0d9f7157a131436dfb0d28f83cd4937ff01af7bde937c03ef11fe035af03f379d646f456810d5af2b7f404531e87c7a072fa1a06741624bd7b2e20f8d
7
+ data.tar.gz: c3daafc7d09fcdd4e665fc8c794a3e61b8267ca7a0b38edf1f6c34d290f80f23cdde69bd56dd49bbeab373e82880cfc40afd8459fe58f6fc33454cd16def6aef
data/Rakefile CHANGED
@@ -18,7 +18,7 @@ if defined?(RSpec)
18
18
 
19
19
  task :backend => 'backend:all'
20
20
  namespace :backend do
21
- backends = %w[exec ssh]
21
+ backends = Dir.glob("spec/backend/*").map { |path| File.basename(path) }
22
22
 
23
23
  task :all => backends
24
24
 
@@ -9,56 +9,30 @@ module Specinfra
9
9
  module Backend
10
10
  # LXD transport
11
11
  class Lxd < Exec
12
- def initialize(config = {})
13
- super
14
-
15
- raise 'Please specify lxd_instance' unless (@instance = get_config(:lxd_instance))
16
- raise 'Please specify lxd_remote' unless (@remote = get_config(:lxd_remote))
17
-
18
- @remote_instance = [@remote, @instance].compact.join(':')
12
+ def build_command(cmd)
13
+ lxc_cmd = %W[lxc exec #{instance}]
14
+ lxc_cmd << '-t' if get_config(:interactive_shell)
15
+ lxc_cmd << '--'
16
+ (lxc_cmd << super(cmd)).join(' ')
19
17
  end
20
18
 
21
- class << self
22
- protected
23
-
24
- def run_command(cmd, opts = {})
25
- cmd = build_command(cmd)
26
- run_pre_command(opts)
27
- stdout, stderr, exit_status = with_env do
28
- spawn_command(cmd)
29
- end
30
-
31
- if @example
32
- @example.metadata[:command] = cmd
33
- @example.metadata[:stdout] = stdout
34
- end
35
-
36
- CommandResult.new :stdout => stdout, :stderr => stderr, :exit_status => exit_status
37
- end
38
-
39
- def build_command(cmd)
40
- cmd = super(cmd)
41
- "lxc exec #{@remote_instance} -- #{cmd}"
42
- end
43
-
44
- def send_file(source, destination)
45
- flags = %w[--create-dirs]
46
- if File.directory?(source)
47
- flags << '--recursive'
48
- destination = Pathname.new(destination).dirname.to_s
49
- end
50
- cmd = %W[lxc file push #{source} #{@remote_instance}#{destination}] + flags
51
- spawn_command(cmd.join(' '))
19
+ def send_file(source, destination)
20
+ flags = %w[--create-dirs]
21
+ if File.directory?(source)
22
+ flags << '--recursive'
23
+ destination = Pathname.new(destination).dirname.to_s
52
24
  end
25
+ cmd = %W[lxc file push #{source} #{instance}#{destination}] + flags
26
+ spawn_command(cmd.join(' '))
27
+ end
53
28
 
54
- private
29
+ private
55
30
 
56
- def run_pre_command(_opts)
57
- return unless get_config(:pre_command)
31
+ def instance
32
+ raise 'Please specify lxd_instance' unless (instance = get_config(:lxd_instance))
33
+ raise 'Please specify lxd_remote' unless (remote = get_config(:lxd_remote))
58
34
 
59
- cmd = build_command(get_config(:pre_command))
60
- spawn_command(cmd)
61
- end
35
+ [remote, instance].compact.join(':')
62
36
  end
63
37
  end
64
38
  end
@@ -17,8 +17,8 @@ module Specinfra
17
17
 
18
18
  cmd = backend.command.get(:get_inventory_system_product_name)
19
19
  ret = backend.run_command(cmd)
20
- if ret.exit_status == 0 and ret.stdout.length > 0
21
- res[:system] = parse_system_product_name(ret.stdout)
20
+ if ret.success? and (parsed = parse_system_product_name(ret.stdout))
21
+ res[:system] = parsed
22
22
  return res
23
23
  end
24
24
 
@@ -1,5 +1,5 @@
1
1
  module Specinfra
2
- VERSION = "2.88.0"
2
+ VERSION = "2.88.2"
3
3
 
4
4
  def self.ruby_is_older_than?(*version)
5
5
  (RUBY_VERSION.split('.').map(&:to_i) <=> version) < 0
@@ -0,0 +1,113 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'spec_helper'
4
+
5
+ describe Specinfra::Backend::Lxd do
6
+ let(:lxd_instance) { 'instance' }
7
+ let(:lxd_remote) { 'remote' }
8
+ let(:lxc_exec) { "lxc exec #{lxd_remote}:#{lxd_instance}" }
9
+
10
+ before(:each) do
11
+ set :backend, :lxd
12
+ RSpec.configure do |c|
13
+ c.lxd_instance = lxd_instance
14
+ c.lxd_remote = lxd_remote
15
+ end
16
+ end
17
+
18
+ after(:each) do
19
+ Specinfra::Backend::Lxd.clear
20
+ end
21
+
22
+ describe '#build_command' do
23
+ context 'without required lxd_instance set' do
24
+ let(:lxd_instance) { nil }
25
+ it {
26
+ expect { subject.build_command('true') }.to raise_error(RuntimeError, /lxd_instance/)
27
+ }
28
+ end
29
+
30
+ context 'without required lxd_remote set' do
31
+ let(:lxd_remote) { nil }
32
+ it {
33
+ expect { subject.build_command('true') }.to raise_error(RuntimeError, /lxd_remote/)
34
+ }
35
+ end
36
+
37
+ context 'with simple command' do
38
+ it 'should escape spaces' do
39
+ expect(subject.build_command('test -f /etc/passwd')).to eq "#{lxc_exec} -- /bin/sh -c test\\ -f\\ /etc/passwd"
40
+ end
41
+ end
42
+
43
+ context 'with complex command' do
44
+ it 'should escape special chars' do
45
+ expect(subject.build_command('test ! -f /etc/selinux/config || (getenforce | grep -i -- disabled && grep -i -- ^SELINUX=disabled$ /etc/selinux/config)'))
46
+ .to eq "lxc exec #{lxd_remote}:#{lxd_instance} -- /bin/sh -c test\\ \\!\\ -f\\ /etc/selinux/config\\ \\|\\|\\ \\(getenforce\\ \\|\\ grep\\ -i\\ --\\ disabled\\ \\&\\&\\ grep\\ -i\\ --\\ \\^SELINUX\\=disabled\\$\\ /etc/selinux/config\\)"
47
+ end
48
+
49
+ it 'should escape quotes' do
50
+ if Gem::Version.new(RUBY_VERSION.dup) < Gem::Version.new('2.7')
51
+ expect(subject.build_command(%Q(find /etc/apt/ -name \*.list | xargs grep -o -E "^deb +[\\"']?http://ppa.launchpad.net/gluster/glusterfs-3.7"))).to eq("#{lxc_exec} -- /bin/sh -c find\\ /etc/apt/\\ -name\\ \\*.list\\ \\|\\ xargs\\ grep\\ -o\\ -E\\ \\\"\\^deb\\ \\+\\[\\\\\\\"\\'\\]\\?http://ppa.launchpad.net/gluster/glusterfs-3.7\\\"")
52
+ else
53
+ # Since Ruby 2.7, `+` is not escaped.
54
+ expect(subject.build_command(%Q(find /etc/apt/ -name \*.list | xargs grep -o -E "^deb +[\\"']?http://ppa.launchpad.net/gluster/glusterfs-3.7"))).to eq("#{lxc_exec} -- /bin/sh -c find\\ /etc/apt/\\ -name\\ \\*.list\\ \\|\\ xargs\\ grep\\ -o\\ -E\\ \\\"\\^deb\\ +\\[\\\\\\\"\\'\\]\\?http://ppa.launchpad.net/gluster/glusterfs-3.7\\\"")
55
+ end
56
+ end
57
+ end
58
+
59
+ context 'with custom shell' do
60
+ before { RSpec.configure { |c| c.shell = '/usr/local/bin/tcsh' } }
61
+ after { RSpec.configure { |c| c.shell = nil } }
62
+
63
+ it 'should use custom shell' do
64
+ expect(subject.build_command('test -f /etc/passwd')).to eq "#{lxc_exec} -- /usr/local/bin/tcsh -c test\\ -f\\ /etc/passwd"
65
+ end
66
+ end
67
+
68
+ context 'with custom shell that needs escaping' do
69
+ before { RSpec.configure { |c| c.shell = '/usr/test & spec/bin/sh' } }
70
+ after { RSpec.configure { |c| c.shell = nil } }
71
+
72
+ it 'should use custom shell' do
73
+ expect(subject.build_command('test -f /etc/passwd')).to eq "#{lxc_exec} -- /usr/test\\ \\&\\ spec/bin/sh -c test\\ -f\\ /etc/passwd"
74
+ end
75
+ end
76
+
77
+ context 'with an interactive shell' do
78
+ before { RSpec.configure { |c| c.interactive_shell = true } }
79
+ after { RSpec.configure { |c| c.interactive_shell = nil } }
80
+
81
+ it 'should emulate an interactive shell' do
82
+ expect(subject.build_command('test -f /etc/passwd')).to eq "#{lxc_exec} -t -- /bin/sh -i -c test\\ -f\\ /etc/passwd"
83
+ end
84
+ end
85
+
86
+ context 'with an login shell' do
87
+ before { RSpec.configure { |c| c.login_shell = true } }
88
+ after { RSpec.configure { |c| c.login_shell = nil } }
89
+
90
+ it 'should emulate an login shell' do
91
+ expect(subject.build_command('test -f /etc/passwd')).to eq "#{lxc_exec} -- /bin/sh -l -c test\\ -f\\ /etc/passwd"
92
+ end
93
+ end
94
+
95
+ context 'with custom path' do
96
+ before { RSpec.configure { |c| c.path = '/opt/bin:/opt/foo/bin:$PATH' } }
97
+ after { RSpec.configure { |c| c.path = nil } }
98
+
99
+ it 'should use custom path' do
100
+ expect(subject.build_command('test -f /etc/passwd')).to eq "#{lxc_exec} -- env PATH=\"/opt/bin:/opt/foo/bin:$PATH\" /bin/sh -c test\\ -f\\ /etc/passwd"
101
+ end
102
+ end
103
+
104
+ context 'with custom path that needs escaping' do
105
+ before { RSpec.configure { |c| c.path = '/opt/bin:/opt/test & spec/bin:$PATH' } }
106
+ after { RSpec.configure { |c| c.path = nil } }
107
+
108
+ it 'should use custom path' do
109
+ expect(subject.build_command('test -f /etc/passwd')).to eq "#{lxc_exec} -- env PATH=\"/opt/bin:/opt/test & spec/bin:$PATH\" /bin/sh -c test\\ -f\\ /etc/passwd"
110
+ end
111
+ end
112
+ end
113
+ end
@@ -25,6 +25,22 @@ describe Specinfra::HostInventory::Virtualization do
25
25
  expect(virt.get).to include(:system => 'openvz')
26
26
  end
27
27
 
28
+ it 'Debian on QEMU KVM should return :system => "kvm"' do
29
+ allow(virt.backend).to receive(:run_command).with('grep -Eqa \'docker(/|-[0-9a-f]+)\' /proc/1/cgroup||test -e /.dockerinit') do
30
+ CommandResult.new(:stdout => '', :exit_status => 1)
31
+ end
32
+ allow(virt.backend).to receive(:run_command).with('test -d /proc/vz -a ! -d /proc/bc') do
33
+ CommandResult.new(:stdout => '', :exit_status => 1)
34
+ end
35
+ allow(virt.backend).to receive(:run_command).with('dmidecode -s system-product-name') do
36
+ CommandResult.new(:stdout => "Standard PC (Q35 + ICH9, 2009)\n", :exit_status => 0)
37
+ end
38
+ allow(virt.backend).to receive(:run_command).with('systemd-detect-virt') do
39
+ CommandResult.new(:stdout => "kvm\n", :exit_status => 0)
40
+ end
41
+ expect(virt.get).to include(:system => 'kvm')
42
+ end
43
+
28
44
  let(:host_inventory) { nil }
29
45
  it 'Debian Jessie on KVM should return :system => "kvm"' do
30
46
  ret = virt.parse_system_product_name("KVM\n")
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: specinfra
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.88.0
4
+ version: 2.88.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Gosuke Miyashita
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2024-02-07 00:00:00.000000000 Z
11
+ date: 2024-03-06 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: net-scp
@@ -521,6 +521,7 @@ files:
521
521
  - spec/backend/exec/env_spec.rb
522
522
  - spec/backend/exec/read_noblock_spec.rb
523
523
  - spec/backend/exec/stdxxx_handler_spec.rb
524
+ - spec/backend/lxd/build_command_spec.rb
524
525
  - spec/backend/ssh/build_command_spec.rb
525
526
  - spec/command/alpine/service_spec.rb
526
527
  - spec/command/amazon/interface_spec.rb
@@ -670,6 +671,7 @@ test_files:
670
671
  - spec/backend/exec/env_spec.rb
671
672
  - spec/backend/exec/read_noblock_spec.rb
672
673
  - spec/backend/exec/stdxxx_handler_spec.rb
674
+ - spec/backend/lxd/build_command_spec.rb
673
675
  - spec/backend/ssh/build_command_spec.rb
674
676
  - spec/command/alpine/service_spec.rb
675
677
  - spec/command/amazon/interface_spec.rb