kanrisuru 0.16.3 → 0.16.7
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 +4 -4
- data/CHANGELOG.md +12 -0
- data/README.md +4 -7
- data/kanrisuru.gemspec +1 -1
- data/lib/kanrisuru/core/dmi/parsers/dmi.rb +14 -10
- data/lib/kanrisuru/mode/permission.rb +1 -1
- data/lib/kanrisuru/remote/fstab/entry.rb +154 -0
- data/lib/kanrisuru/remote/fstab/options.rb +143 -0
- data/lib/kanrisuru/remote/fstab.rb +9 -283
- data/lib/kanrisuru/version.rb +1 -1
- data/logo/kanrisuru-logo.png +0 -0
- data/spec/functional/remote/fstab_spec.rb +21 -0
- metadata +7 -5
- data/.rubocop_todo.yml +0 -0
- data/.travis.yml +0 -6
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 1dad2f67bc43f63f08358733b56f5f2c60b0badba2fad40072b5fd856bcd0f00
|
|
4
|
+
data.tar.gz: 84a2b6a7a85bcbd2282fed9540e70a86517605e2681a64e231681a5d156f3332
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: a9cc599d2f48f0d3643489b87c850be0972b217e67b4e488531f5e6de0727fe265460f8af0023917bd65920805d763047b801a23fb49bf5abc78f745a8900d14
|
|
7
|
+
data.tar.gz: de40ab48a6758caa3ae9d4f8de9a71b0c15723d5921bb065054003e9756b874a7f248da34c2b7721b78f29b967aa5c61d9a07ac7582a1c994df0261bf3714028
|
data/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,15 @@
|
|
|
1
|
+
## Kanrisuru 0.16.7 (December 27, 2021) ##
|
|
2
|
+
* Update homepage to docs website.
|
|
3
|
+
|
|
4
|
+
## Kanrisuru 0.16.6 (December 26, 2021) ##
|
|
5
|
+
* Add `delete` to fstab class to delete an entry from the fstab.
|
|
6
|
+
|
|
7
|
+
## Kanrisuru 0.16.5 (December 25, 2021) ##
|
|
8
|
+
* Refactor `dmi_field_translate` to reduce complexity.
|
|
9
|
+
|
|
10
|
+
## Kanrisuru 0.16.4 (December 25, 2021) ##
|
|
11
|
+
* Refactor `Kanrisuru::Fstab::Entry` and `Kanrisuru::Fstab::Options` classes into separate files.
|
|
12
|
+
|
|
1
13
|
## Kanrisuru 0.16.3 (December 25, 2021) ##
|
|
2
14
|
* Refactor `Kanrisuru::Mode::Permission` class into separate file.
|
|
3
15
|
|
data/README.md
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
<
|
|
2
|
-
<img src="
|
|
3
|
-
</
|
|
1
|
+
<h1>
|
|
2
|
+
<img src="./logo/kanrisuru-logo.png" alt="Kanrisuru" width="400" height="100%"/>
|
|
3
|
+
</h1>
|
|
4
4
|
|
|
5
|
-
<p
|
|
5
|
+
<p>
|
|
6
6
|
<a href="https://rubygems.org/gems/kanrisuru">
|
|
7
7
|
<img src="https://img.shields.io/gem/v/kanrisuru?style=flat-square" alt="Latest version" />
|
|
8
8
|
</a>
|
|
@@ -15,8 +15,6 @@
|
|
|
15
15
|
<img src="https://img.shields.io/codeclimate/maintainability/avamia/kanrisuru?style=flat-square" alt="Code Climate maintainability" />
|
|
16
16
|
</p>
|
|
17
17
|
|
|
18
|
-
# Kanrisuru
|
|
19
|
-
|
|
20
18
|
Kanrisuru (manage) helps you remotely control infrastructure using Ruby. This is done over SSH. I'm working on building up some basic functionality to help quickly provision, deploy and manage a single host or cluster of hosts.
|
|
21
19
|
|
|
22
20
|
The idea behind this project is not to replace the numerous other projects to manage your infrastrucutre, however, I've found there usually meant to be a standalone project that have their own ecosystem. With Kanrisuru, you essentailly plug the library directly into your ruby project.
|
|
@@ -104,7 +102,6 @@ HOSTS=ubuntu,debian,centos rspec
|
|
|
104
102
|
|
|
105
103
|
This will run tests on the ubuntu, debian and centos instances.
|
|
106
104
|
|
|
107
|
-
|
|
108
105
|
Then, run `rake spec` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
|
|
109
106
|
|
|
110
107
|
To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).
|
data/kanrisuru.gemspec
CHANGED
|
@@ -8,7 +8,7 @@ Gem::Specification.new do |gem|
|
|
|
8
8
|
gem.author = 'Ryan Mammina'
|
|
9
9
|
gem.email = 'ryan@avamia.com'
|
|
10
10
|
gem.license = 'MIT'
|
|
11
|
-
gem.homepage = 'https://
|
|
11
|
+
gem.homepage = 'https://kanrisuru.com'
|
|
12
12
|
gem.summary = 'Manage remote servers over ssh with ruby.'
|
|
13
13
|
gem.description = <<-EOF
|
|
14
14
|
Kanrisuru helps manage remote servers with objected oriented ruby.#{' '}
|
|
@@ -93,37 +93,41 @@ module Kanrisuru
|
|
|
93
93
|
end
|
|
94
94
|
|
|
95
95
|
def dmi_field_translate(struct, field)
|
|
96
|
-
field = field
|
|
97
|
-
field = field.gsub(/\s/, '_')
|
|
98
|
-
field = field.gsub('-', '_')
|
|
99
|
-
field = field.gsub(':', '')
|
|
96
|
+
field = dmi_scrub_field(field)
|
|
100
97
|
|
|
101
98
|
case struct.dmi_type
|
|
102
99
|
when 'Memory Device'
|
|
103
100
|
case field
|
|
104
101
|
when 'size'
|
|
105
|
-
|
|
102
|
+
'mem_size'
|
|
106
103
|
end
|
|
107
104
|
when 'System Slots'
|
|
108
105
|
case field
|
|
109
106
|
when 'length'
|
|
110
|
-
|
|
107
|
+
'slot_length'
|
|
111
108
|
end
|
|
112
109
|
when 'OEM Strings'
|
|
113
110
|
case field
|
|
114
111
|
when /^string/
|
|
115
|
-
|
|
112
|
+
'strings'
|
|
116
113
|
end
|
|
117
114
|
when 'Boot Integrity Services'
|
|
118
115
|
case field
|
|
119
116
|
when '16_bit_entry_point_address'
|
|
120
|
-
|
|
117
|
+
'sixteen_bit_entry_point_address'
|
|
121
118
|
when '32_bit_entry_point_address'
|
|
122
|
-
|
|
119
|
+
'thirty_two_bit_entry_point_address'
|
|
123
120
|
end
|
|
121
|
+
else
|
|
122
|
+
field
|
|
124
123
|
end
|
|
124
|
+
end
|
|
125
125
|
|
|
126
|
-
|
|
126
|
+
def dmi_scrub_field(field)
|
|
127
|
+
field = field.downcase
|
|
128
|
+
field = field.gsub(/\s/, '_')
|
|
129
|
+
field = field.gsub('-', '_')
|
|
130
|
+
field.gsub(':', '')
|
|
127
131
|
end
|
|
128
132
|
|
|
129
133
|
def dmi_type_to_struct(type)
|
|
@@ -0,0 +1,154 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Kanrisuru
|
|
4
|
+
module Remote
|
|
5
|
+
class Fstab
|
|
6
|
+
class Entry
|
|
7
|
+
attr_reader :device, :uuid, :invalid, :label, :type, :opts, :freq, :passno
|
|
8
|
+
attr_accessor :mount_point
|
|
9
|
+
|
|
10
|
+
def initialize(opts = {})
|
|
11
|
+
@host = opts[:host]
|
|
12
|
+
@line = opts[:line]
|
|
13
|
+
|
|
14
|
+
@default = nil
|
|
15
|
+
|
|
16
|
+
@device = opts[:device] || nil
|
|
17
|
+
@opts = opts[:opts] || nil
|
|
18
|
+
@label = opts[:label] || nil
|
|
19
|
+
@uuid = opts[:uuid] || nil
|
|
20
|
+
@mount_point = opts[:mount_point] || nil
|
|
21
|
+
@type = opts[:type] || nil
|
|
22
|
+
@freq = opts[:freq] || nil
|
|
23
|
+
@passno = opts[:passno] || nil
|
|
24
|
+
|
|
25
|
+
@changed = false
|
|
26
|
+
|
|
27
|
+
@ucount = 0
|
|
28
|
+
@special = false
|
|
29
|
+
@invalid = false
|
|
30
|
+
|
|
31
|
+
if Kanrisuru::Util.present?(@line) && @line.instance_of?(String)
|
|
32
|
+
parse_line!
|
|
33
|
+
elsif (Kanrisuru::Util.present?(@opts) && @opts.instance_of?(String)) || @opts.instance_of?(Hash)
|
|
34
|
+
@opts = Kanrisuru::Remote::Fstab::Options.new(@type, @opts)
|
|
35
|
+
end
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
def inspect
|
|
39
|
+
str = '#<Kanrisuru::Remote::Fstab::Entry:0x%<object_id>s ' \
|
|
40
|
+
'@line=%<line>s @device=%<device>s @label=%<label>s' \
|
|
41
|
+
'@uuid=%<uuid>s @freq=%<freq>s @pasno=%<passno>s' \
|
|
42
|
+
'@opts=%<opts>s}>'
|
|
43
|
+
|
|
44
|
+
format(
|
|
45
|
+
str,
|
|
46
|
+
object_id: object_id,
|
|
47
|
+
line: @line,
|
|
48
|
+
device: @device,
|
|
49
|
+
label: @label,
|
|
50
|
+
uuid: @uuid,
|
|
51
|
+
freq: @freq,
|
|
52
|
+
passno: @passno,
|
|
53
|
+
opts: @opts.inspect
|
|
54
|
+
)
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
def valid?
|
|
58
|
+
!@invalid
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
def to_s(override = nil)
|
|
62
|
+
mode = override || @default
|
|
63
|
+
|
|
64
|
+
case mode
|
|
65
|
+
when 'uuid'
|
|
66
|
+
"UUID=#{@uuid} #{@mount_point} #{@type} #{@opts} #{@freq} #{@passno}"
|
|
67
|
+
when 'label'
|
|
68
|
+
"LABEL=#{@label} #{@mount_point} #{@type} #{@opts} #{@freq} #{@passno}"
|
|
69
|
+
else
|
|
70
|
+
"#{@device} #{@mount_point} #{@type} #{@opts} #{@freq} #{@passno}"
|
|
71
|
+
end
|
|
72
|
+
end
|
|
73
|
+
|
|
74
|
+
private
|
|
75
|
+
|
|
76
|
+
def parse_line!
|
|
77
|
+
fsline, mp, @type, opts, freq, passno = @line.split
|
|
78
|
+
|
|
79
|
+
@mount_point = mp
|
|
80
|
+
@freq = freq || '0'
|
|
81
|
+
@passno = passno || '0'
|
|
82
|
+
|
|
83
|
+
@opts = Fstab::Options.new(@type, opts)
|
|
84
|
+
|
|
85
|
+
case @line
|
|
86
|
+
when /^\s*LABEL=/
|
|
87
|
+
@default = 'label'
|
|
88
|
+
parse_label(fsline)
|
|
89
|
+
when /^\s*UUID=/
|
|
90
|
+
@default = 'uuid'
|
|
91
|
+
parse_uuid(fsline)
|
|
92
|
+
when %r{^\s*/dev}
|
|
93
|
+
@default = 'dev'
|
|
94
|
+
parse_dev(fsline)
|
|
95
|
+
else
|
|
96
|
+
# TODO: somewhat risky to assume that everything else
|
|
97
|
+
# can be considered a special device, but validating this
|
|
98
|
+
# is really tricky.
|
|
99
|
+
@special = true
|
|
100
|
+
@device = fsline
|
|
101
|
+
end
|
|
102
|
+
|
|
103
|
+
# Fstab entries not matching real devices have device unknown
|
|
104
|
+
@invalid = (@line.split.count != 6) # invalid entry if < 6 columns
|
|
105
|
+
|
|
106
|
+
if (@uuid.nil? && @label.nil? && !@special) ||
|
|
107
|
+
@device =~ /^unknown_/ ||
|
|
108
|
+
(!@host.inode?(@device) && !@special)
|
|
109
|
+
@invalid = true
|
|
110
|
+
@ucount += 1
|
|
111
|
+
end
|
|
112
|
+
|
|
113
|
+
@invalid = true unless @freq =~ /0|1|2/ && @passno =~ /0|1|2/
|
|
114
|
+
end
|
|
115
|
+
|
|
116
|
+
def parse_label(fsline)
|
|
117
|
+
@label = fsline.split('=').last.strip.chomp
|
|
118
|
+
path = @host.realpath("/dev/disk/by-label/#{@label}").path
|
|
119
|
+
|
|
120
|
+
@device = begin
|
|
121
|
+
"/dev/#{path.split('/').last}"
|
|
122
|
+
rescue StandardError
|
|
123
|
+
"unknown_#{@ucount}"
|
|
124
|
+
end
|
|
125
|
+
|
|
126
|
+
result = @host.blkid(device: @device)
|
|
127
|
+
@uuid = result.success? ? result[0].uuid : nil
|
|
128
|
+
end
|
|
129
|
+
|
|
130
|
+
def parse_uuid(fsline)
|
|
131
|
+
@uuid = fsline.split('=').last.strip.chomp
|
|
132
|
+
path = @host.realpath("/dev/disk/by-uuid/#{uuid}").path
|
|
133
|
+
|
|
134
|
+
@device = begin
|
|
135
|
+
"/dev/#{path.split('/').last}"
|
|
136
|
+
rescue StandardError
|
|
137
|
+
"unknown_#{@ucount}"
|
|
138
|
+
end
|
|
139
|
+
|
|
140
|
+
result = @host.blkid(device: @device)
|
|
141
|
+
@label = result.success? ? result[0].label : nil
|
|
142
|
+
end
|
|
143
|
+
|
|
144
|
+
def parse_dev(fsline)
|
|
145
|
+
@device = fsline
|
|
146
|
+
result = @host.blkid(device: @device)
|
|
147
|
+
|
|
148
|
+
@label = result.success? ? result[0].label : nil
|
|
149
|
+
@uuid = result.success? ? result[0].uuid : nil
|
|
150
|
+
end
|
|
151
|
+
end
|
|
152
|
+
end
|
|
153
|
+
end
|
|
154
|
+
end
|
|
@@ -0,0 +1,143 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Kanrisuru
|
|
4
|
+
module Remote
|
|
5
|
+
class Fstab
|
|
6
|
+
class Options
|
|
7
|
+
def initialize(type, opts)
|
|
8
|
+
@type = type
|
|
9
|
+
@valid = false
|
|
10
|
+
|
|
11
|
+
if opts.instance_of?(String)
|
|
12
|
+
@opts = parse_opts(opts)
|
|
13
|
+
elsif opts.instance_of?(Hash)
|
|
14
|
+
@opts = opts.transform_keys(&:to_s)
|
|
15
|
+
else
|
|
16
|
+
raise ArgumentError, 'Invalid option type'
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
validate_opts!
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
def inspect
|
|
23
|
+
format('<Kanrisuru::Remote::Fstab::Options:0x%<object_id>s @opts=%<opts>s @type=%<type>s>',
|
|
24
|
+
object_id: object_id, opts: @opts, type: @type)
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
def [](option)
|
|
28
|
+
@opts[option]
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
def []=(option, value)
|
|
32
|
+
option = option.to_s
|
|
33
|
+
|
|
34
|
+
unless Kanrisuru::Remote::Fstab::Options.option_exists?(option, @type)
|
|
35
|
+
raise ArgumentError,
|
|
36
|
+
"Invalid option: #{option} for #{@type} file system."
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
unless Kanrisuru::Remote::Fstab::Options.valid_option?(option, value, @type)
|
|
40
|
+
raise ArgumentError,
|
|
41
|
+
"Invalid option value: #{value} for #{option} on #{@type} file system."
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
@opts[option] = value
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
def to_s
|
|
48
|
+
string = ''
|
|
49
|
+
opts_length = @opts.length
|
|
50
|
+
|
|
51
|
+
@opts.each_with_index do |(key, value), index|
|
|
52
|
+
append_comma = true
|
|
53
|
+
|
|
54
|
+
if value == true
|
|
55
|
+
string += key.to_s
|
|
56
|
+
elsif value.instance_of?(String) || value.instance_of?(Integer) || value.instance_of?(Float)
|
|
57
|
+
string += "#{key}=#{value}"
|
|
58
|
+
else
|
|
59
|
+
append_comma = false
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
string += ',' if append_comma && index < opts_length - 1
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
string
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
def to_h
|
|
69
|
+
@opts
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
def self.option_exists?(value, type = nil)
|
|
73
|
+
value = value.to_sym
|
|
74
|
+
type = type ? type.to_sym : nil
|
|
75
|
+
|
|
76
|
+
common = Kanrisuru::Util::FsMountOpts[:common]
|
|
77
|
+
fs_opts = Kanrisuru::Util::FsMountOpts[type]
|
|
78
|
+
|
|
79
|
+
common.key?(value) ||
|
|
80
|
+
fs_opts&.key?(value)
|
|
81
|
+
end
|
|
82
|
+
|
|
83
|
+
def self.valid_option?(value, field, type = nil)
|
|
84
|
+
value = value.to_sym
|
|
85
|
+
type = type ? type.to_sym : nil
|
|
86
|
+
|
|
87
|
+
common = Kanrisuru::Util::FsMountOpts[:common]
|
|
88
|
+
fs_opts = Kanrisuru::Util::FsMountOpts[type]
|
|
89
|
+
|
|
90
|
+
if common.key?(value)
|
|
91
|
+
case common[value]
|
|
92
|
+
when 'boolean'
|
|
93
|
+
[true, false].include?(field)
|
|
94
|
+
when 'value'
|
|
95
|
+
field.instance_of?(String) || field.instance_of?(Float) || field.instance_of?(Integer)
|
|
96
|
+
else
|
|
97
|
+
false
|
|
98
|
+
end
|
|
99
|
+
elsif fs_opts&.key?(value)
|
|
100
|
+
case fs_opts[value]
|
|
101
|
+
when 'boolean'
|
|
102
|
+
[true, false].include?(field)
|
|
103
|
+
when 'value'
|
|
104
|
+
field.instance_of?(String) || field.instance_of?(Float) || field.instance_of?(Integer)
|
|
105
|
+
else
|
|
106
|
+
false
|
|
107
|
+
end
|
|
108
|
+
else
|
|
109
|
+
raise ArgumentError, 'Invalid option'
|
|
110
|
+
end
|
|
111
|
+
end
|
|
112
|
+
|
|
113
|
+
private
|
|
114
|
+
|
|
115
|
+
def validate_opts!
|
|
116
|
+
@opts.each do |key, value|
|
|
117
|
+
unless Kanrisuru::Remote::Fstab::Options.valid_option?(key, value, @type)
|
|
118
|
+
raise ArgumentError, "Invalid option: #{key} for #{@type}"
|
|
119
|
+
end
|
|
120
|
+
end
|
|
121
|
+
|
|
122
|
+
@valid = true
|
|
123
|
+
end
|
|
124
|
+
|
|
125
|
+
def parse_opts(string)
|
|
126
|
+
opts = {}
|
|
127
|
+
|
|
128
|
+
options = string.split(',')
|
|
129
|
+
options.each do |option|
|
|
130
|
+
if option.include?('=')
|
|
131
|
+
opt, value = option.split('=')
|
|
132
|
+
opts[opt] = value
|
|
133
|
+
else
|
|
134
|
+
opts[option] = true
|
|
135
|
+
end
|
|
136
|
+
end
|
|
137
|
+
|
|
138
|
+
opts
|
|
139
|
+
end
|
|
140
|
+
end
|
|
141
|
+
end
|
|
142
|
+
end
|
|
143
|
+
end
|
|
@@ -1,5 +1,8 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
+
require_relative 'fstab/entry'
|
|
4
|
+
require_relative 'fstab/options'
|
|
5
|
+
|
|
3
6
|
module Kanrisuru
|
|
4
7
|
module Remote
|
|
5
8
|
class Fstab
|
|
@@ -18,6 +21,12 @@ module Kanrisuru
|
|
|
18
21
|
get_entry(device)
|
|
19
22
|
end
|
|
20
23
|
|
|
24
|
+
def delete(device)
|
|
25
|
+
return false unless @entries.key?(device)
|
|
26
|
+
|
|
27
|
+
@entries.delete(device)
|
|
28
|
+
end
|
|
29
|
+
|
|
21
30
|
def get_entry(device)
|
|
22
31
|
result = @entries[device]
|
|
23
32
|
|
|
@@ -133,289 +142,6 @@ module Kanrisuru
|
|
|
133
142
|
}
|
|
134
143
|
end
|
|
135
144
|
end
|
|
136
|
-
|
|
137
|
-
class Entry
|
|
138
|
-
attr_reader :device, :uuid, :invalid, :label, :type, :opts, :freq, :passno
|
|
139
|
-
attr_accessor :mount_point
|
|
140
|
-
|
|
141
|
-
def initialize(opts = {})
|
|
142
|
-
@host = opts[:host]
|
|
143
|
-
@line = opts[:line]
|
|
144
|
-
|
|
145
|
-
@default = nil
|
|
146
|
-
|
|
147
|
-
@device = opts[:device] || nil
|
|
148
|
-
@opts = opts[:opts] || nil
|
|
149
|
-
@label = opts[:label] || nil
|
|
150
|
-
@uuid = opts[:uuid] || nil
|
|
151
|
-
@mount_point = opts[:mount_point] || nil
|
|
152
|
-
@type = opts[:type] || nil
|
|
153
|
-
@freq = opts[:freq] || nil
|
|
154
|
-
@passno = opts[:passno] || nil
|
|
155
|
-
|
|
156
|
-
@changed = false
|
|
157
|
-
|
|
158
|
-
@ucount = 0
|
|
159
|
-
@special = false
|
|
160
|
-
@invalid = false
|
|
161
|
-
|
|
162
|
-
if Kanrisuru::Util.present?(@line) && @line.instance_of?(String)
|
|
163
|
-
parse_line!
|
|
164
|
-
elsif (Kanrisuru::Util.present?(@opts) && @opts.instance_of?(String)) || @opts.instance_of?(Hash)
|
|
165
|
-
@opts = Kanrisuru::Remote::Fstab::Options.new(@type, @opts)
|
|
166
|
-
end
|
|
167
|
-
end
|
|
168
|
-
|
|
169
|
-
def inspect
|
|
170
|
-
str = '#<Kanrisuru::Remote::Fstab::Entry:0x%<object_id>s ' \
|
|
171
|
-
'@line=%<line>s @device=%<device>s @label=%<label>s' \
|
|
172
|
-
'@uuid=%<uuid>s @freq=%<freq>s @pasno=%<passno>s' \
|
|
173
|
-
'@opts=%<opts>s}>'
|
|
174
|
-
|
|
175
|
-
format(
|
|
176
|
-
str,
|
|
177
|
-
object_id: object_id,
|
|
178
|
-
line: @line,
|
|
179
|
-
device: @device,
|
|
180
|
-
label: @label,
|
|
181
|
-
uuid: @uuid,
|
|
182
|
-
freq: @freq,
|
|
183
|
-
passno: @passno,
|
|
184
|
-
opts: @opts.inspect
|
|
185
|
-
)
|
|
186
|
-
end
|
|
187
|
-
|
|
188
|
-
def valid?
|
|
189
|
-
!@invalid
|
|
190
|
-
end
|
|
191
|
-
|
|
192
|
-
def to_s(override = nil)
|
|
193
|
-
mode = override || @default
|
|
194
|
-
|
|
195
|
-
case mode
|
|
196
|
-
when 'uuid'
|
|
197
|
-
"UUID=#{@uuid} #{@mount_point} #{@type} #{@opts} #{@freq} #{@passno}"
|
|
198
|
-
when 'label'
|
|
199
|
-
"LABEL=#{@label} #{@mount_point} #{@type} #{@opts} #{@freq} #{@passno}"
|
|
200
|
-
else
|
|
201
|
-
"#{@device} #{@mount_point} #{@type} #{@opts} #{@freq} #{@passno}"
|
|
202
|
-
end
|
|
203
|
-
end
|
|
204
|
-
|
|
205
|
-
private
|
|
206
|
-
|
|
207
|
-
def parse_line!
|
|
208
|
-
fsline, mp, @type, opts, freq, passno = @line.split
|
|
209
|
-
|
|
210
|
-
@mount_point = mp
|
|
211
|
-
@freq = freq || '0'
|
|
212
|
-
@passno = passno || '0'
|
|
213
|
-
|
|
214
|
-
@opts = Fstab::Options.new(@type, opts)
|
|
215
|
-
|
|
216
|
-
case @line
|
|
217
|
-
when /^\s*LABEL=/
|
|
218
|
-
@default = 'label'
|
|
219
|
-
parse_label(fsline)
|
|
220
|
-
when /^\s*UUID=/
|
|
221
|
-
@default = 'uuid'
|
|
222
|
-
parse_uuid(fsline)
|
|
223
|
-
when %r{^\s*/dev}
|
|
224
|
-
@default = 'dev'
|
|
225
|
-
parse_dev(fsline)
|
|
226
|
-
else
|
|
227
|
-
# TODO: somewhat risky to assume that everything else
|
|
228
|
-
# can be considered a special device, but validating this
|
|
229
|
-
# is really tricky.
|
|
230
|
-
@special = true
|
|
231
|
-
@device = fsline
|
|
232
|
-
end
|
|
233
|
-
|
|
234
|
-
# Fstab entries not matching real devices have device unknown
|
|
235
|
-
@invalid = (@line.split.count != 6) # invalid entry if < 6 columns
|
|
236
|
-
|
|
237
|
-
if (@uuid.nil? && @label.nil? && !@special) ||
|
|
238
|
-
@device =~ /^unknown_/ ||
|
|
239
|
-
(!@host.inode?(@device) && !@special)
|
|
240
|
-
@invalid = true
|
|
241
|
-
@ucount += 1
|
|
242
|
-
end
|
|
243
|
-
|
|
244
|
-
@invalid = true unless @freq =~ /0|1|2/ && @passno =~ /0|1|2/
|
|
245
|
-
end
|
|
246
|
-
|
|
247
|
-
def parse_label(fsline)
|
|
248
|
-
@label = fsline.split('=').last.strip.chomp
|
|
249
|
-
path = @host.realpath("/dev/disk/by-label/#{@label}").path
|
|
250
|
-
|
|
251
|
-
@device = begin
|
|
252
|
-
"/dev/#{path.split('/').last}"
|
|
253
|
-
rescue StandardError
|
|
254
|
-
"unknown_#{@ucount}"
|
|
255
|
-
end
|
|
256
|
-
|
|
257
|
-
result = @host.blkid(device: @device)
|
|
258
|
-
@uuid = result.success? ? result[0].uuid : nil
|
|
259
|
-
end
|
|
260
|
-
|
|
261
|
-
def parse_uuid(fsline)
|
|
262
|
-
@uuid = fsline.split('=').last.strip.chomp
|
|
263
|
-
path = @host.realpath("/dev/disk/by-uuid/#{uuid}").path
|
|
264
|
-
|
|
265
|
-
@device = begin
|
|
266
|
-
"/dev/#{path.split('/').last}"
|
|
267
|
-
rescue StandardError
|
|
268
|
-
"unknown_#{@ucount}"
|
|
269
|
-
end
|
|
270
|
-
|
|
271
|
-
result = @host.blkid(device: @device)
|
|
272
|
-
@label = result.success? ? result[0].label : nil
|
|
273
|
-
end
|
|
274
|
-
|
|
275
|
-
def parse_dev(fsline)
|
|
276
|
-
@device = fsline
|
|
277
|
-
result = @host.blkid(device: @device)
|
|
278
|
-
|
|
279
|
-
@label = result.success? ? result[0].label : nil
|
|
280
|
-
@uuid = result.success? ? result[0].uuid : nil
|
|
281
|
-
end
|
|
282
|
-
end
|
|
283
|
-
|
|
284
|
-
class Options
|
|
285
|
-
def initialize(type, opts)
|
|
286
|
-
@type = type
|
|
287
|
-
@valid = false
|
|
288
|
-
|
|
289
|
-
if opts.instance_of?(String)
|
|
290
|
-
@opts = parse_opts(opts)
|
|
291
|
-
elsif opts.instance_of?(Hash)
|
|
292
|
-
@opts = opts.transform_keys(&:to_s)
|
|
293
|
-
else
|
|
294
|
-
raise ArgumentError, 'Invalid option type'
|
|
295
|
-
end
|
|
296
|
-
|
|
297
|
-
validate_opts!
|
|
298
|
-
end
|
|
299
|
-
|
|
300
|
-
def inspect
|
|
301
|
-
format('<Kanrisuru::Remote::Fstab::Options:0x%<object_id>s @opts=%<opts>s @type=%<type>s>',
|
|
302
|
-
object_id: object_id, opts: @opts, type: @type)
|
|
303
|
-
end
|
|
304
|
-
|
|
305
|
-
def [](option)
|
|
306
|
-
@opts[option]
|
|
307
|
-
end
|
|
308
|
-
|
|
309
|
-
def []=(option, value)
|
|
310
|
-
option = option.to_s
|
|
311
|
-
|
|
312
|
-
unless Kanrisuru::Remote::Fstab::Options.option_exists?(option, @type)
|
|
313
|
-
raise ArgumentError,
|
|
314
|
-
"Invalid option: #{option} for #{@type} file system."
|
|
315
|
-
end
|
|
316
|
-
|
|
317
|
-
unless Kanrisuru::Remote::Fstab::Options.valid_option?(option, value, @type)
|
|
318
|
-
raise ArgumentError,
|
|
319
|
-
"Invalid option value: #{value} for #{option} on #{@type} file system."
|
|
320
|
-
end
|
|
321
|
-
|
|
322
|
-
@opts[option] = value
|
|
323
|
-
end
|
|
324
|
-
|
|
325
|
-
def to_s
|
|
326
|
-
string = ''
|
|
327
|
-
opts_length = @opts.length
|
|
328
|
-
|
|
329
|
-
@opts.each_with_index do |(key, value), index|
|
|
330
|
-
append_comma = true
|
|
331
|
-
|
|
332
|
-
if value == true
|
|
333
|
-
string += key.to_s
|
|
334
|
-
elsif value.instance_of?(String) || value.instance_of?(Integer) || value.instance_of?(Float)
|
|
335
|
-
string += "#{key}=#{value}"
|
|
336
|
-
else
|
|
337
|
-
append_comma = false
|
|
338
|
-
end
|
|
339
|
-
|
|
340
|
-
string += ',' if append_comma && index < opts_length - 1
|
|
341
|
-
end
|
|
342
|
-
|
|
343
|
-
string
|
|
344
|
-
end
|
|
345
|
-
|
|
346
|
-
def to_h
|
|
347
|
-
@opts
|
|
348
|
-
end
|
|
349
|
-
|
|
350
|
-
def self.option_exists?(value, type = nil)
|
|
351
|
-
value = value.to_sym
|
|
352
|
-
type = type ? type.to_sym : nil
|
|
353
|
-
|
|
354
|
-
common = Kanrisuru::Util::FsMountOpts[:common]
|
|
355
|
-
fs_opts = Kanrisuru::Util::FsMountOpts[type]
|
|
356
|
-
|
|
357
|
-
common.key?(value) ||
|
|
358
|
-
fs_opts&.key?(value)
|
|
359
|
-
end
|
|
360
|
-
|
|
361
|
-
def self.valid_option?(value, field, type = nil)
|
|
362
|
-
value = value.to_sym
|
|
363
|
-
type = type ? type.to_sym : nil
|
|
364
|
-
|
|
365
|
-
common = Kanrisuru::Util::FsMountOpts[:common]
|
|
366
|
-
fs_opts = Kanrisuru::Util::FsMountOpts[type]
|
|
367
|
-
|
|
368
|
-
if common.key?(value)
|
|
369
|
-
case common[value]
|
|
370
|
-
when 'boolean'
|
|
371
|
-
[true, false].include?(field)
|
|
372
|
-
when 'value'
|
|
373
|
-
field.instance_of?(String) || field.instance_of?(Float) || field.instance_of?(Integer)
|
|
374
|
-
else
|
|
375
|
-
false
|
|
376
|
-
end
|
|
377
|
-
elsif fs_opts&.key?(value)
|
|
378
|
-
case fs_opts[value]
|
|
379
|
-
when 'boolean'
|
|
380
|
-
[true, false].include?(field)
|
|
381
|
-
when 'value'
|
|
382
|
-
field.instance_of?(String) || field.instance_of?(Float) || field.instance_of?(Integer)
|
|
383
|
-
else
|
|
384
|
-
false
|
|
385
|
-
end
|
|
386
|
-
else
|
|
387
|
-
raise ArgumentError, 'Invalid option'
|
|
388
|
-
end
|
|
389
|
-
end
|
|
390
|
-
|
|
391
|
-
private
|
|
392
|
-
|
|
393
|
-
def validate_opts!
|
|
394
|
-
@opts.each do |key, value|
|
|
395
|
-
unless Kanrisuru::Remote::Fstab::Options.valid_option?(key, value, @type)
|
|
396
|
-
raise ArgumentError, "Invalid option: #{key} for #{@type}"
|
|
397
|
-
end
|
|
398
|
-
end
|
|
399
|
-
|
|
400
|
-
@valid = true
|
|
401
|
-
end
|
|
402
|
-
|
|
403
|
-
def parse_opts(string)
|
|
404
|
-
opts = {}
|
|
405
|
-
|
|
406
|
-
options = string.split(',')
|
|
407
|
-
options.each do |option|
|
|
408
|
-
if option.include?('=')
|
|
409
|
-
opt, value = option.split('=')
|
|
410
|
-
opts[opt] = value
|
|
411
|
-
else
|
|
412
|
-
opts[option] = true
|
|
413
|
-
end
|
|
414
|
-
end
|
|
415
|
-
|
|
416
|
-
opts
|
|
417
|
-
end
|
|
418
|
-
end
|
|
419
145
|
end
|
|
420
146
|
end
|
|
421
147
|
end
|
data/lib/kanrisuru/version.rb
CHANGED
|
Binary file
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'spec_helper'
|
|
4
|
+
|
|
5
|
+
RSpec.describe Kanrisuru::Remote::Fstab do
|
|
6
|
+
before(:all) do
|
|
7
|
+
StubNetwork.stub!
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
after(:all) do
|
|
11
|
+
StubNetwork.unstub!
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
let(:host) do
|
|
15
|
+
Kanrisuru::Remote::Host.new(
|
|
16
|
+
host: 'localhost',
|
|
17
|
+
username: 'ubuntu',
|
|
18
|
+
keys: ['id_rsa']
|
|
19
|
+
)
|
|
20
|
+
end
|
|
21
|
+
end
|
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: kanrisuru
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.16.
|
|
4
|
+
version: 0.16.7
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Ryan Mammina
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: bin
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date: 2021-12-
|
|
11
|
+
date: 2021-12-27 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: parallel_tests
|
|
@@ -149,8 +149,6 @@ files:
|
|
|
149
149
|
- ".gitignore"
|
|
150
150
|
- ".rspec"
|
|
151
151
|
- ".rubocop.yml"
|
|
152
|
-
- ".rubocop_todo.yml"
|
|
153
|
-
- ".travis.yml"
|
|
154
152
|
- CHANGELOG.md
|
|
155
153
|
- CODE_OF_CONDUCT.md
|
|
156
154
|
- Gemfile
|
|
@@ -428,6 +426,8 @@ files:
|
|
|
428
426
|
- lib/kanrisuru/remote/env.rb
|
|
429
427
|
- lib/kanrisuru/remote/file.rb
|
|
430
428
|
- lib/kanrisuru/remote/fstab.rb
|
|
429
|
+
- lib/kanrisuru/remote/fstab/entry.rb
|
|
430
|
+
- lib/kanrisuru/remote/fstab/options.rb
|
|
431
431
|
- lib/kanrisuru/remote/host.rb
|
|
432
432
|
- lib/kanrisuru/remote/memory.rb
|
|
433
433
|
- lib/kanrisuru/remote/os.rb
|
|
@@ -440,6 +440,7 @@ files:
|
|
|
440
440
|
- lib/kanrisuru/util/os_family.rb
|
|
441
441
|
- lib/kanrisuru/util/signal.rb
|
|
442
442
|
- lib/kanrisuru/version.rb
|
|
443
|
+
- logo/kanrisuru-logo.png
|
|
443
444
|
- spec/functional/core/apt_spec.rb
|
|
444
445
|
- spec/functional/core/archive_spec.rb
|
|
445
446
|
- spec/functional/core/disk_spec.rb
|
|
@@ -468,6 +469,7 @@ files:
|
|
|
468
469
|
- spec/functional/remote/cluster_spec.rb
|
|
469
470
|
- spec/functional/remote/cpu_spec.rb
|
|
470
471
|
- spec/functional/remote/env_spec.rb
|
|
472
|
+
- spec/functional/remote/fstab_spec.rb
|
|
471
473
|
- spec/functional/result_spec.rb
|
|
472
474
|
- spec/helper/expect_helpers.rb
|
|
473
475
|
- spec/helper/hosts.json
|
|
@@ -681,7 +683,7 @@ files:
|
|
|
681
683
|
- spec/unit/remote/fstab_spec.rb
|
|
682
684
|
- spec/unit/template_spec.rb
|
|
683
685
|
- spec/unit/util_spec.rb
|
|
684
|
-
homepage: https://
|
|
686
|
+
homepage: https://kanrisuru.com
|
|
685
687
|
licenses:
|
|
686
688
|
- MIT
|
|
687
689
|
metadata:
|
data/.rubocop_todo.yml
DELETED
|
File without changes
|