kanrisuru 0.1.0 → 0.2.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (81) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +17 -0
  3. data/.rubocop.yml +47 -0
  4. data/.rubocop_todo.yml +0 -0
  5. data/CHANGELOG.md +0 -0
  6. data/Gemfile +2 -5
  7. data/LICENSE.txt +1 -1
  8. data/README.md +143 -7
  9. data/Rakefile +5 -3
  10. data/bin/console +4 -3
  11. data/kanrisuru.gemspec +21 -12
  12. data/lib/kanrisuru.rb +41 -2
  13. data/lib/kanrisuru/command.rb +99 -0
  14. data/lib/kanrisuru/core.rb +53 -0
  15. data/lib/kanrisuru/core/archive.rb +154 -0
  16. data/lib/kanrisuru/core/disk.rb +302 -0
  17. data/lib/kanrisuru/core/file.rb +332 -0
  18. data/lib/kanrisuru/core/find.rb +108 -0
  19. data/lib/kanrisuru/core/group.rb +97 -0
  20. data/lib/kanrisuru/core/ip.rb +1032 -0
  21. data/lib/kanrisuru/core/mount.rb +138 -0
  22. data/lib/kanrisuru/core/path.rb +140 -0
  23. data/lib/kanrisuru/core/socket.rb +168 -0
  24. data/lib/kanrisuru/core/stat.rb +104 -0
  25. data/lib/kanrisuru/core/stream.rb +121 -0
  26. data/lib/kanrisuru/core/system.rb +348 -0
  27. data/lib/kanrisuru/core/transfer.rb +203 -0
  28. data/lib/kanrisuru/core/user.rb +198 -0
  29. data/lib/kanrisuru/logger.rb +8 -0
  30. data/lib/kanrisuru/mode.rb +277 -0
  31. data/lib/kanrisuru/os_package.rb +235 -0
  32. data/lib/kanrisuru/remote.rb +10 -0
  33. data/lib/kanrisuru/remote/cluster.rb +95 -0
  34. data/lib/kanrisuru/remote/cpu.rb +68 -0
  35. data/lib/kanrisuru/remote/env.rb +33 -0
  36. data/lib/kanrisuru/remote/file.rb +354 -0
  37. data/lib/kanrisuru/remote/fstab.rb +412 -0
  38. data/lib/kanrisuru/remote/host.rb +191 -0
  39. data/lib/kanrisuru/remote/memory.rb +19 -0
  40. data/lib/kanrisuru/remote/os.rb +87 -0
  41. data/lib/kanrisuru/result.rb +78 -0
  42. data/lib/kanrisuru/template.rb +32 -0
  43. data/lib/kanrisuru/util.rb +40 -0
  44. data/lib/kanrisuru/util/bits.rb +203 -0
  45. data/lib/kanrisuru/util/fs_mount_opts.rb +655 -0
  46. data/lib/kanrisuru/util/os_family.rb +213 -0
  47. data/lib/kanrisuru/util/signal.rb +161 -0
  48. data/lib/kanrisuru/version.rb +3 -1
  49. data/spec/functional/core/archive_spec.rb +228 -0
  50. data/spec/functional/core/disk_spec.rb +80 -0
  51. data/spec/functional/core/file_spec.rb +341 -0
  52. data/spec/functional/core/find_spec.rb +52 -0
  53. data/spec/functional/core/group_spec.rb +65 -0
  54. data/spec/functional/core/ip_spec.rb +71 -0
  55. data/spec/functional/core/path_spec.rb +93 -0
  56. data/spec/functional/core/socket_spec.rb +31 -0
  57. data/spec/functional/core/stat_spec.rb +98 -0
  58. data/spec/functional/core/stream_spec.rb +99 -0
  59. data/spec/functional/core/system_spec.rb +96 -0
  60. data/spec/functional/core/transfer_spec.rb +108 -0
  61. data/spec/functional/core/user_spec.rb +76 -0
  62. data/spec/functional/os_package_spec.rb +75 -0
  63. data/spec/functional/remote/cluster_spec.rb +45 -0
  64. data/spec/functional/remote/cpu_spec.rb +41 -0
  65. data/spec/functional/remote/env_spec.rb +36 -0
  66. data/spec/functional/remote/fstab_spec.rb +76 -0
  67. data/spec/functional/remote/host_spec.rb +68 -0
  68. data/spec/functional/remote/memory_spec.rb +29 -0
  69. data/spec/functional/remote/os_spec.rb +63 -0
  70. data/spec/functional/remote/remote_file_spec.rb +180 -0
  71. data/spec/helper/test_hosts.rb +68 -0
  72. data/spec/hosts.json +92 -0
  73. data/spec/spec_helper.rb +11 -3
  74. data/spec/unit/fstab_spec.rb +22 -0
  75. data/spec/unit/kanrisuru_spec.rb +9 -0
  76. data/spec/unit/mode_spec.rb +183 -0
  77. data/spec/unit/template_spec.rb +13 -0
  78. data/spec/unit/util_spec.rb +177 -0
  79. data/spec/zz_reboot_spec.rb +46 -0
  80. metadata +136 -13
  81. data/spec/kanrisuru_spec.rb +0 -9
@@ -0,0 +1,96 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'spec_helper'
4
+
5
+ RSpec.describe Kanrisuru::Core::System do
6
+ TestHosts.each_os do |os_name|
7
+ context "with #{os_name}" do
8
+ let(:host_json) { TestHosts.host(os_name) }
9
+ let(:host) do
10
+ Kanrisuru::Remote::Host.new(
11
+ host: host_json['hostname'],
12
+ username: host_json['username'],
13
+ keys: [host_json['ssh_key']]
14
+ )
15
+ end
16
+
17
+ after do
18
+ host.disconnect
19
+ end
20
+
21
+ it 'gets environment variables' do
22
+ result = host.load_env
23
+
24
+ expect(result.success?).to be(true)
25
+ expect(result.data).to be_instance_of(Hash)
26
+ end
27
+
28
+ it 'gets uptime' do
29
+ result = host.uptime
30
+ expect(result.success?).to eq(true)
31
+
32
+ expect(result).to respond_to(
33
+ :boot_time, :uptime, :seconds,
34
+ :hours, :minutes, :days
35
+ )
36
+
37
+ expect(result.seconds).to be > 0
38
+ expect(result.minutes).to be >= 0
39
+ expect(result.hours).to be >= 0
40
+ expect(result.days).to be >= 0
41
+ end
42
+
43
+ it 'kills pids' do
44
+ command = 'sleep 100000 > /dev/null 2>&1 &'
45
+
46
+ host.execute_shell("nohup #{command}")
47
+ result = host.ps(user: host_json['username'])
48
+ expect(result.success?).to eq(true)
49
+
50
+ process = result.select do |proc|
51
+ proc.command == 'sleep 100000'
52
+ end
53
+
54
+ pids = process.map(&:pid)
55
+ result = host.kill('SIGKILL', pids)
56
+ expect(result.success?).to eq(true)
57
+
58
+ result = host.ps(user: host_json['username'])
59
+ process = result.select do |proc|
60
+ proc.command == 'sleep 100000'
61
+ end
62
+
63
+ expect(process).to be_empty
64
+ end
65
+
66
+ it 'gets process details' do
67
+ result = host.ps
68
+
69
+ expect(result.data).to be_instance_of(Array)
70
+ process = result[0]
71
+
72
+ expect(process).to respond_to(
73
+ :uid, :user, :gid, :group,
74
+ :pid, :ppid, :cpu_usage, :memory_usage,
75
+ :stat, :priority, :flags, :policy_abbr, :policy,
76
+ :cpu_time, :command
77
+ )
78
+
79
+ result = host.ps(user: [host_json['username']])
80
+
81
+ expect(result.data).to be_instance_of(Array)
82
+
83
+ process = result.find do |proc|
84
+ proc.command == result.command.raw_command
85
+ end
86
+
87
+ expect(process.command).to eq(result.command.raw_command)
88
+ end
89
+
90
+ it 'gets information for users' do
91
+ result = host.who
92
+ expect(result.success?).to eq(true)
93
+ end
94
+ end
95
+ end
96
+ end
@@ -0,0 +1,108 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'spec_helper'
4
+
5
+ RSpec.describe Kanrisuru::Core::File do
6
+ TestHosts.each_os do |os_name|
7
+ context "with #{os_name}" do
8
+ before(:all) do
9
+ host_json = TestHosts.host(os_name)
10
+ host = Kanrisuru::Remote::Host.new(
11
+ host: host_json['hostname'],
12
+ username: host_json['username'],
13
+ keys: [host_json['ssh_key']]
14
+ )
15
+
16
+ host.mkdir("#{host_json['home']}/.kanrisuru_spec_files", silent: true)
17
+ host.disconnect
18
+ end
19
+
20
+ let(:host_json) { TestHosts.host(os_name) }
21
+ let(:host) do
22
+ Kanrisuru::Remote::Host.new(
23
+ host: host_json['hostname'],
24
+ username: host_json['username'],
25
+ keys: [host_json['ssh_key']]
26
+ )
27
+ end
28
+
29
+ let(:spec_dir) { "#{host_json['home']}/.kanrisuru_spec_files" }
30
+
31
+ after do
32
+ host.disconnect
33
+ end
34
+
35
+ after(:all) do
36
+ host_json = TestHosts.host(os_name)
37
+ host = Kanrisuru::Remote::Host.new(
38
+ host: host_json['hostname'],
39
+ username: host_json['username'],
40
+ keys: [host_json['ssh_key']]
41
+ )
42
+
43
+ host.rmdir("#{host_json['home']}/.kanrisuru_spec_files")
44
+ host.disconnect
45
+ end
46
+
47
+ it 'uploads a template file' do
48
+ path = '../templates/test.conf.erb'
49
+ dest_path = "#{spec_dir}/test.conf"
50
+
51
+ template = Kanrisuru::Template.new(path, array: %w[this is an array])
52
+ result = host.upload(template.read, dest_path)
53
+
54
+ expect(result).to be_success
55
+ expect(result.mode.numeric).to eq('640')
56
+ expect(result.user).to eq(host_json['username'])
57
+
58
+ case os_name
59
+ when 'sles', 'opensuse'
60
+ expect(result.gid).to eq(100)
61
+ expect(result.group).to eq('users')
62
+ else
63
+ expect(result.gid).to eq(1000)
64
+ expect(result.group).to eq(host_json['username'])
65
+ end
66
+
67
+ expect(host.cat(dest_path).to_a).to eq([
68
+ '<h1>Hello World</h1>',
69
+ 'this',
70
+ 'is',
71
+ 'an',
72
+ 'array'
73
+ ])
74
+ end
75
+
76
+ it 'uploads a dir' do
77
+ path = '../meta/'
78
+ dest_path = "#{spec_dir}/meta"
79
+
80
+ result = host.upload(path, dest_path, recursive: true)
81
+ expect(result).to be_success
82
+ end
83
+
84
+ it 'downloads a file to local fs' do
85
+ path = '../hosts-file'
86
+ src_path = '/etc/hosts'
87
+
88
+ result = host.download(src_path, path)
89
+ expect(result).to eq(path)
90
+ FileUtils.rm(path)
91
+ end
92
+
93
+ it 'downloads a file directly' do
94
+ src_path = '/etc/hosts'
95
+
96
+ result = host.download(src_path)
97
+ expect(result).to be_instance_of(String)
98
+ lines = result.split("\n")
99
+ expect(lines.length).to be >= 1
100
+ end
101
+
102
+ it 'wgets url' do
103
+ result = host.wget('https://example.com', directory_prefix: spec_dir)
104
+ expect(result).to be_success
105
+ end
106
+ end
107
+ end
108
+ end
@@ -0,0 +1,76 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'spec_helper'
4
+
5
+ RSpec.describe Kanrisuru::Core::User do
6
+ TestHosts.each_os do |os_name|
7
+ context "with #{os_name}" do
8
+ let(:host_json) { TestHosts.host(os_name) }
9
+ let(:host) do
10
+ Kanrisuru::Remote::Host.new(
11
+ host: host_json['hostname'],
12
+ username: host_json['username'],
13
+ keys: [host_json['ssh_key']]
14
+ )
15
+ end
16
+
17
+ after do
18
+ host.disconnect
19
+ end
20
+
21
+ after(:all) do
22
+ host_json = TestHosts.host(os_name)
23
+ host = Kanrisuru::Remote::Host.new(
24
+ host: host_json['hostname'],
25
+ username: host_json['username'],
26
+ keys: [host_json['ssh_key']]
27
+ )
28
+
29
+ host.su('root')
30
+ host.user?('rails')
31
+ host.delete_user('rails').inspect if host.user?('rails')
32
+ host.rmdir('/home/rails') if host.dir?('/home/rails')
33
+ host.disconnect
34
+ end
35
+
36
+ it 'gets uid for user' do
37
+ expect(host.get_uid(host_json['uername']).to_i).to eq(1000)
38
+ expect(host.get_uid('asdf').to_i).to eq(nil)
39
+ end
40
+
41
+ it 'gets a user details' do
42
+ result = host.get_user(host_json['username'])
43
+ expect(result.uid).to eq(1000)
44
+ expect(result.name).to eq(host_json['username'])
45
+ expect(result.home.path).to eq(host_json['home'])
46
+
47
+ case os_name
48
+ when 'opensuse', 'sles'
49
+ expect(result.groups[0]).to have_attributes(gid: 100, name: 'users')
50
+ else
51
+ expect(result.groups[0]).to have_attributes(gid: 1000, name: host_json['username'])
52
+ end
53
+ end
54
+
55
+ it 'manages a user' do
56
+ ## Need priviledge escalation to manage group
57
+ host.su('root')
58
+
59
+ result = host.create_user('rails', password: '123456', groups: %w[mail tty])
60
+ expect(result.success?).to eq(true)
61
+ expect(result.uid).to eq(1001)
62
+ expect(result.groups.length).to eq(3)
63
+ expect(result.shell.path).to eq('/bin/false')
64
+ expect(result.home.path).to eq('/home/rails')
65
+
66
+ result = host.update_user('rails', uid: 1002, shell: '/bin/bash', groups: ['audio'], append: true)
67
+
68
+ expect(result.uid).to eq(1002)
69
+ expect(result.shell.path).to eq('/bin/bash')
70
+ expect(result.groups.length).to eq(4)
71
+
72
+ expect(host.delete_user('rails').success?).to eq(true) if host.user?('rails')
73
+ end
74
+ end
75
+ end
76
+ end
@@ -0,0 +1,75 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'spec_helper'
4
+
5
+ module Kanrisuru
6
+ module TestInclude
7
+ extend Kanrisuru::OsPackage::Define
8
+
9
+ os_define :ubuntu, :tester
10
+
11
+ def tester
12
+ 'hello ubuntu'
13
+ end
14
+ end
15
+
16
+ module TestNamespace
17
+ extend Kanrisuru::OsPackage::Define
18
+
19
+ os_define :unix_like, :tester
20
+ os_define :centos, :test_not_correct
21
+
22
+ def tester
23
+ 'hello namespace'
24
+ end
25
+
26
+ def test_not_correct; end
27
+ end
28
+ end
29
+
30
+ module Kanrisuru
31
+ module Remote
32
+ class Host
33
+ os_include Kanrisuru::TestInclude
34
+ os_include Kanrisuru::TestNamespace, namespace: :asdf
35
+ end
36
+
37
+ class Cluster
38
+ os_collection Kanrisuru::TestInclude
39
+ os_collection Kanrisuru::TestNamespace, namespace: :asdf
40
+ end
41
+ end
42
+ end
43
+
44
+ RSpec.describe Kanrisuru::OsPackage do
45
+ it 'includes with os_include' do
46
+ host = Kanrisuru::Remote::Host.new(host: '127.0.0.1', username: 'ubuntu', keys: ['~/.ssh/id_rsa'])
47
+ host2 = Kanrisuru::Remote::Host.new(host: 'localhost', username: 'ubuntu', keys: ['~/.ssh/id_rsa'])
48
+
49
+ cluster = Kanrisuru::Remote::Cluster.new([host, host2])
50
+
51
+ expect(host).to respond_to(:tester)
52
+ expect(host.tester).to eq('hello ubuntu')
53
+ expect(cluster.tester).to be_instance_of(Array)
54
+
55
+ host.disconnect
56
+ cluster.disconnect
57
+ end
58
+
59
+ it 'includes a namespaced os_include' do
60
+ host = Kanrisuru::Remote::Host.new(host: '127.0.0.1', username: 'ubuntu', keys: ['~/.ssh/id_rsa'])
61
+ host2 = Kanrisuru::Remote::Host.new(host: 'localhost', username: 'ubuntu', keys: ['~/.ssh/id_rsa'])
62
+
63
+ cluster = Kanrisuru::Remote::Cluster.new([host, host2])
64
+
65
+ expect(host).to respond_to(:asdf)
66
+ expect(host.asdf).to respond_to(:tester)
67
+ expect(host.asdf.tester).to eq 'hello namespace'
68
+ expect(host.tester).to eq('hello ubuntu')
69
+ expect { host.asdf.test_not_correct }.to raise_error(NoMethodError)
70
+ expect(cluster.asdf.tester).to be_instance_of(Array)
71
+
72
+ host.disconnect
73
+ cluster.disconnect
74
+ end
75
+ end
@@ -0,0 +1,45 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'spec_helper'
4
+
5
+ RSpec.describe Kanrisuru::Remote::Cluster do
6
+ context 'with ubuntu' do
7
+ it 'gets hostname for cluster' do
8
+ cluster = described_class.new([{
9
+ host: 'localhost',
10
+ username: 'ubuntu',
11
+ keys: ['~/.ssh/id_rsa']
12
+ }, {
13
+ host: '127.0.0.1',
14
+ username: 'ubuntu',
15
+ keys: ['~/.ssh/id_rsa']
16
+ }])
17
+
18
+ expect(cluster.hostname).to match([
19
+ { host: 'localhost', result: 'ubuntu' },
20
+ { host: '127.0.0.1', result: 'ubuntu' }
21
+ ])
22
+
23
+ cluster.disconnect
24
+ end
25
+
26
+ it 'can ping host cluster' do
27
+ cluster = described_class.new([{
28
+ host: 'localhost',
29
+ username: 'ubuntu',
30
+ keys: ['~/.ssh/id_rsa']
31
+ }, {
32
+ host: '127.0.0.1',
33
+ username: 'ubuntu',
34
+ keys: ['~/.ssh/id_rsa']
35
+ }])
36
+
37
+ expect(cluster.ping?).to match([
38
+ { host: 'localhost', result: true },
39
+ { host: '127.0.0.1', result: true }
40
+ ])
41
+
42
+ cluster.disconnect
43
+ end
44
+ end
45
+ end
@@ -0,0 +1,41 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'spec_helper'
4
+
5
+ RSpec.describe Kanrisuru::Remote::Cpu do
6
+ TestHosts.each_os do |os_name|
7
+ context "with #{os_name}" do
8
+ let(:host_json) { TestHosts.host(os_name) }
9
+ let(:host) do
10
+ Kanrisuru::Remote::Host.new(
11
+ host: host_json['hostname'],
12
+ username: host_json['username'],
13
+ keys: [host_json['ssh_key']]
14
+ )
15
+ end
16
+
17
+ after do
18
+ host.disconnect
19
+ end
20
+
21
+ it 'gets cpu details' do
22
+ expect(host.cpu.cores).to eq(1)
23
+ expect(host.cpu.total).to eq(1)
24
+ expect(host.cpu.count).to eq(1)
25
+
26
+ expect(host.cpu.threads_per_core).to eq(1)
27
+ expect(host.cpu.cores_per_socket).to eq(1)
28
+ expect(host.cpu.sockets).to eq(1)
29
+
30
+ expect(host.cpu.hyperthreading?).to eq(false)
31
+ end
32
+
33
+ it 'gets cpu load average' do
34
+ expect(host.cpu.load_average).to be_instance_of(Array)
35
+ expect(host.cpu.load_average1).to be_instance_of(Float)
36
+ expect(host.cpu.load_average5).to be_instance_of(Float)
37
+ expect(host.cpu.load_average15).to be_instance_of(Float)
38
+ end
39
+ end
40
+ end
41
+ end