plat4m 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/LICENSE +21 -0
- data/README.md +11 -0
- data/lib/plat4m/pkgman.rb +60 -0
- data/lib/plat4m/sniff/darwin.rb +206 -0
- data/lib/plat4m/sniff/freebsd.rb +51 -0
- data/lib/plat4m/sniff/linux.rb +260 -0
- data/lib/plat4m/sniff/windows.rb +55 -0
- data/lib/plat4m/system.rb +179 -0
- data/lib/plat4m/version.rb +13 -0
- data/lib/plat4m.rb +15 -0
- metadata +55 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 9df6b644a5e122916e8230965e4e4999441bd067706d2679e905008f0000c0f8
|
4
|
+
data.tar.gz: 0efb88c4163e04fef3499e3f542d9a003ffb7fdd28ced4ff0db4a1d8fb3aa8d8
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: e7101d9e5feba298a1b945b010996a7d48f26d3267f31da53b041cf5b4e936eeff29ed8e5ff6277d6548c5d4efda9de05b2779000d3100d611474a99196c5bd7
|
7
|
+
data.tar.gz: d8c7db00c80acc09fe3308b04a33a522263ffe71b40b01096ab5da4614b9b0486c349907d9f66a440feb738e82ef15e96f10f146a93b451f9f2c970450213e1a
|
data/LICENSE
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
MIT License
|
2
|
+
|
3
|
+
Copyright (c) 2024 Martin Corino
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
7
|
+
in the Software without restriction, including without limitation the rights
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
10
|
+
furnished to do so, subject to the following conditions:
|
11
|
+
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
13
|
+
copies or substantial portions of the Software.
|
14
|
+
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
21
|
+
SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,11 @@
|
|
1
|
+
[![License](https://img.shields.io/badge/license-MIT-yellowgreen.svg)](LICENSE)
|
2
|
+
[![Gem Version](https://badge.fury.io/rb/plat4m.svg)](https://badge.fury.io/rb/plat4m)
|
3
|
+
|
4
|
+
# Plat4m
|
5
|
+
|
6
|
+
Plat4m is a simple runtime system platform scouting and support library specially intended to
|
7
|
+
be used with other Ruby projects to provide light weight runtime system detection and provide
|
8
|
+
support for simple system package management (install/uninstall) support.
|
9
|
+
|
10
|
+
Plat4m is definitely not intended as a full fledged runtime system detection system and/or a
|
11
|
+
complete system management solution.
|
@@ -0,0 +1,60 @@
|
|
1
|
+
# Copyright (c) 2023 M.J.N. Corino, The Netherlands
|
2
|
+
#
|
3
|
+
# This software is released under the MIT license.
|
4
|
+
#
|
5
|
+
# Plat4m PkgManager
|
6
|
+
|
7
|
+
|
8
|
+
module Plat4m
|
9
|
+
|
10
|
+
class PkgManager
|
11
|
+
|
12
|
+
def initialize
|
13
|
+
@has_sudo = false
|
14
|
+
end
|
15
|
+
|
16
|
+
def installed?(pkg)
|
17
|
+
raise NoMethodError
|
18
|
+
end
|
19
|
+
|
20
|
+
def select_uninstalled(*pkgs)
|
21
|
+
pkgs.flatten.select { |pkg| !installed?(pkg) }
|
22
|
+
end
|
23
|
+
|
24
|
+
def available?(pkg)
|
25
|
+
raise NoMethodError
|
26
|
+
end
|
27
|
+
|
28
|
+
def select_available(*pkgs)
|
29
|
+
pkgs.flatten.select { |pkg| available?(pkg) }
|
30
|
+
end
|
31
|
+
|
32
|
+
def make_install_command(*pkgs)
|
33
|
+
raise NoMethodError
|
34
|
+
end
|
35
|
+
|
36
|
+
def install(*pkgs, silent: false)
|
37
|
+
cmd = make_install_command
|
38
|
+
silent ? system("#{cmd} >/dev/null 2>&1") : system(cmd)
|
39
|
+
end
|
40
|
+
|
41
|
+
def make_uninstall_command(*pkgs)
|
42
|
+
raise NoMethodError
|
43
|
+
end
|
44
|
+
|
45
|
+
def uninstall(*pkgs, silent: false)
|
46
|
+
cmd = make_uninstall_command
|
47
|
+
silent ? system("#{cmd} >/dev/null 2>&1") : system(cmd)
|
48
|
+
end
|
49
|
+
|
50
|
+
def is_root?
|
51
|
+
false
|
52
|
+
end
|
53
|
+
|
54
|
+
def has_sudo?
|
55
|
+
@has_sudo
|
56
|
+
end
|
57
|
+
|
58
|
+
end
|
59
|
+
|
60
|
+
end
|
@@ -0,0 +1,206 @@
|
|
1
|
+
# Copyright (c) 2023 M.J.N. Corino, The Netherlands
|
2
|
+
#
|
3
|
+
# This software is released under the MIT license.
|
4
|
+
#
|
5
|
+
# Plat4m Linux sniffer
|
6
|
+
|
7
|
+
|
8
|
+
module Plat4m
|
9
|
+
|
10
|
+
module Sniffer
|
11
|
+
|
12
|
+
module Darwin
|
13
|
+
|
14
|
+
class << self
|
15
|
+
|
16
|
+
def detect_system
|
17
|
+
# determine system platform
|
18
|
+
System.new(System::Platform.new(arch: get_arch, cpus: get_cpu_count),
|
19
|
+
System::OS.new(id: :darwin, **get_distro))
|
20
|
+
end
|
21
|
+
|
22
|
+
private
|
23
|
+
|
24
|
+
def get_arch
|
25
|
+
arch, _ = RbConfig::CONFIG['arch'].split('-')
|
26
|
+
arch = 'x86' if arch =~ /i\d86/
|
27
|
+
arch
|
28
|
+
end
|
29
|
+
|
30
|
+
def get_cpu_count
|
31
|
+
(system('command -v nproc > /dev/null 2>&1') ? `nproc` : `getconf _NPROCESSORS_ONLN`).to_i
|
32
|
+
end
|
33
|
+
|
34
|
+
def get_distro
|
35
|
+
distro = {
|
36
|
+
distro: 'macosx'
|
37
|
+
}
|
38
|
+
ver = `sw_vers --productVersion`.strip
|
39
|
+
distro[:release] = ver.split('.').first
|
40
|
+
distro[:version] = ver
|
41
|
+
distro[:pkgman] = MacPkgManager.new
|
42
|
+
distro
|
43
|
+
end
|
44
|
+
|
45
|
+
def has_macports?
|
46
|
+
if @has_macports.nil?
|
47
|
+
@has_macports = system('command -v port>/dev/null')
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
def has_homebrew?
|
52
|
+
if @has_homebrew.nil?
|
53
|
+
@has_homebrew = system('command -v brew>/dev/null')
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
end
|
58
|
+
|
59
|
+
class MacPkgManager < PkgManager
|
60
|
+
|
61
|
+
def initialize
|
62
|
+
super
|
63
|
+
@has_sudo = system('command -v sudo > /dev/null')
|
64
|
+
@has_macports = system('command -v port>/dev/null')
|
65
|
+
@has_homebrew = system('command -v brew>/dev/null')
|
66
|
+
end
|
67
|
+
|
68
|
+
def installed?(pkg)
|
69
|
+
pkg_manager.installed?(pkg)
|
70
|
+
end
|
71
|
+
|
72
|
+
def available?(pkg)
|
73
|
+
pkg_manager.available?(pkg)
|
74
|
+
end
|
75
|
+
|
76
|
+
def make_install_command(*pkgs)
|
77
|
+
pkg_manager.make_install_command(*pkgs)
|
78
|
+
end
|
79
|
+
|
80
|
+
def make_uninstall_command(*pkgs)
|
81
|
+
pkg_manager.make_uninstall_command(*pkgs)
|
82
|
+
end
|
83
|
+
|
84
|
+
def macports?
|
85
|
+
MacPorts === pkg_manager
|
86
|
+
end
|
87
|
+
|
88
|
+
def homebrew?
|
89
|
+
Homebrew === pkg_manager
|
90
|
+
end
|
91
|
+
|
92
|
+
private
|
93
|
+
|
94
|
+
def is_root?
|
95
|
+
`id -u 2>/dev/null`.chomp == '0'
|
96
|
+
end
|
97
|
+
|
98
|
+
def has_macports?
|
99
|
+
if @has_macports.nil?
|
100
|
+
@has_macports = system('command -v port>/dev/null')
|
101
|
+
end
|
102
|
+
end
|
103
|
+
|
104
|
+
def has_homebrew?
|
105
|
+
if @has_homebrew.nil?
|
106
|
+
@has_homebrew = system('command -v brew>/dev/null')
|
107
|
+
end
|
108
|
+
end
|
109
|
+
|
110
|
+
class Homebrew < PkgManager
|
111
|
+
|
112
|
+
def initialize(owner)
|
113
|
+
super()
|
114
|
+
@owner = owner
|
115
|
+
@has_sudo = @owner.has_sudo?
|
116
|
+
end
|
117
|
+
|
118
|
+
def installed?(pkg)
|
119
|
+
`brew list -1 --formula`.strip.split("\n").include?(pkg) ||
|
120
|
+
`brew list -1 --cask`.strip.split("\n").include?(pkg)
|
121
|
+
end
|
122
|
+
|
123
|
+
def available?(pkg)
|
124
|
+
system(%Q[brew search "/^#{pkg}$/" >/dev/null 2>&1])
|
125
|
+
end
|
126
|
+
|
127
|
+
def make_install_command(*pkgs)
|
128
|
+
"brew install -q #{pkgs.join(' ')}"
|
129
|
+
end
|
130
|
+
|
131
|
+
def make_uninstall_command(*pkgs)
|
132
|
+
"brew uninstall -q #{pkgs.join(' ')}"
|
133
|
+
end
|
134
|
+
|
135
|
+
end
|
136
|
+
|
137
|
+
class MacPorts < PkgManager
|
138
|
+
|
139
|
+
def initialize(owner)
|
140
|
+
super()
|
141
|
+
@owner = owner
|
142
|
+
@has_sudo = @owner.has_sudo?
|
143
|
+
@privileged = File.stat(`which port`.strip).uid == 0
|
144
|
+
end
|
145
|
+
|
146
|
+
def installed?(pkg)
|
147
|
+
!(`port -q installed #{pkg}`.strip.empty?)
|
148
|
+
end
|
149
|
+
|
150
|
+
def available?(pkg)
|
151
|
+
!(`port -q search --exact #{pkg}`.strip.empty?)
|
152
|
+
end
|
153
|
+
|
154
|
+
def make_install_command(*pkgs)
|
155
|
+
auth_cmd("port install #{pkgs.join(' ')}")
|
156
|
+
end
|
157
|
+
|
158
|
+
def make_uninstall_command(*pkgs)
|
159
|
+
auth_cmd("port uninstall #{pkgs.join(' ')}")
|
160
|
+
end
|
161
|
+
|
162
|
+
private
|
163
|
+
|
164
|
+
def is_root?
|
165
|
+
@owner.is_root?
|
166
|
+
end
|
167
|
+
|
168
|
+
def auth_cmd(cmd)
|
169
|
+
raise "Cannot find 'sudo' for command [#{cmd}]" unless !@privileged || is_root? || @has_sudo
|
170
|
+
(!@privileged || is_root?) ? cmd : "sudo #{cmd}"
|
171
|
+
end
|
172
|
+
|
173
|
+
end
|
174
|
+
|
175
|
+
def pkg_manager
|
176
|
+
unless @pkg_manager
|
177
|
+
# # Has Ruby been installed through MacPorts?
|
178
|
+
# if has_macports? &&
|
179
|
+
# expand('port -q installed installed').strip.split("\n").find { |ln| ln.strip =~ /\Aruby\d+\s/ }
|
180
|
+
# @pkg_manager = MacPorts.new
|
181
|
+
|
182
|
+
# re we running without root privileges and have Homebrew installed?
|
183
|
+
# (Ruby may be installed using Homebrew itself or using a Ruby version manager like RVM)
|
184
|
+
if !is_root? && has_homebrew?
|
185
|
+
@pkg_manager = Homebrew.new(self)
|
186
|
+
|
187
|
+
# or do we have MacPorts (running either privileged or not).
|
188
|
+
elsif has_macports?
|
189
|
+
@pkg_manager = MacPorts.new(self)
|
190
|
+
|
191
|
+
else
|
192
|
+
raise RuntimeError, 'Unable to determine package manager to use!'
|
193
|
+
end
|
194
|
+
end
|
195
|
+
@pkg_manager
|
196
|
+
end
|
197
|
+
|
198
|
+
end
|
199
|
+
|
200
|
+
end
|
201
|
+
|
202
|
+
end
|
203
|
+
|
204
|
+
self.sniffers[:darwin] = Sniffer::Darwin
|
205
|
+
|
206
|
+
end
|
@@ -0,0 +1,51 @@
|
|
1
|
+
# Copyright (c) 2023 M.J.N. Corino, The Netherlands
|
2
|
+
#
|
3
|
+
# This software is released under the MIT license.
|
4
|
+
#
|
5
|
+
# Plat4m Freebsd sniffer
|
6
|
+
|
7
|
+
|
8
|
+
module Plat4m
|
9
|
+
|
10
|
+
module Sniffer
|
11
|
+
|
12
|
+
module Freebsd
|
13
|
+
|
14
|
+
class << self
|
15
|
+
|
16
|
+
def detect_system
|
17
|
+
# determine system platform
|
18
|
+
System.new(System::Platform.new(arch: get_arch, cpus: get_cpu_count),
|
19
|
+
System::OS.new(id: :freebsd, **get_distro))
|
20
|
+
end
|
21
|
+
|
22
|
+
private
|
23
|
+
|
24
|
+
def get_arch
|
25
|
+
arch, _ = RbConfig::CONFIG['arch'].split('-')
|
26
|
+
arch = 'x86' if arch =~ /i\d86/
|
27
|
+
arch
|
28
|
+
end
|
29
|
+
|
30
|
+
def get_cpu_count
|
31
|
+
(system('command -v nproc > /dev/null 2>&1') ? `nproc` : `getconf NPROCESSORS_ONLN`).to_i
|
32
|
+
end
|
33
|
+
|
34
|
+
def get_distro
|
35
|
+
distro = {
|
36
|
+
distro: 'freebsd'
|
37
|
+
}
|
38
|
+
distro[:release] = 0
|
39
|
+
distro[:pkgman] = nil
|
40
|
+
distro
|
41
|
+
end
|
42
|
+
|
43
|
+
end
|
44
|
+
|
45
|
+
end
|
46
|
+
|
47
|
+
end
|
48
|
+
|
49
|
+
self.sniffers[:freebsd] = Sniffer::Freebsd
|
50
|
+
|
51
|
+
end
|
@@ -0,0 +1,260 @@
|
|
1
|
+
# Copyright (c) 2023 M.J.N. Corino, The Netherlands
|
2
|
+
#
|
3
|
+
# This software is released under the MIT license.
|
4
|
+
#
|
5
|
+
# Plat4m Linux sniffer
|
6
|
+
|
7
|
+
|
8
|
+
module Plat4m
|
9
|
+
|
10
|
+
module Sniffer
|
11
|
+
|
12
|
+
module Linux
|
13
|
+
|
14
|
+
class << self
|
15
|
+
|
16
|
+
def detect_system
|
17
|
+
# determine system platform
|
18
|
+
System.new(System::Platform.new(arch: get_arch, cpus: get_cpu_count),
|
19
|
+
System::OS.new(id: :linux, **get_distro))
|
20
|
+
end
|
21
|
+
|
22
|
+
private
|
23
|
+
|
24
|
+
def get_arch
|
25
|
+
arch, _ = RbConfig::CONFIG['arch'].split('-')
|
26
|
+
arch = 'x86' if arch =~ /i\d86/
|
27
|
+
arch
|
28
|
+
end
|
29
|
+
|
30
|
+
def get_cpu_count
|
31
|
+
(system('command -v nproc > /dev/null 2>&1') ? `nproc` : `getconf _NPROCESSORS_ONLN`).to_i
|
32
|
+
end
|
33
|
+
|
34
|
+
def get_distro
|
35
|
+
distro = if File.file?('/etc/os-release') # works with most (if not all) recent distro releases
|
36
|
+
data = File.readlines('/etc/os-release').reduce({}) do |hash, line|
|
37
|
+
val, var = line.split('=')
|
38
|
+
hash[val] = var.strip.gsub(/(\A")|("\Z)/, '')
|
39
|
+
hash
|
40
|
+
end
|
41
|
+
{
|
42
|
+
variant: if data['ID_LIKE']
|
43
|
+
data['ID_LIKE'].split.first.to_sym
|
44
|
+
elsif File.file?('/etc/redhat-release')
|
45
|
+
:rhel
|
46
|
+
elsif File.file?('/etc/SUSE-brand') || File.file?('/etc/SuSE-release')
|
47
|
+
:suse
|
48
|
+
elsif File.file?('/etc/debian_version')
|
49
|
+
:debian
|
50
|
+
else
|
51
|
+
data['ID'].to_sym
|
52
|
+
end,
|
53
|
+
distro: data['ID'].downcase,
|
54
|
+
release: data['VERSION_ID']
|
55
|
+
}
|
56
|
+
elsif File.file?('/etc/redhat-release')
|
57
|
+
data = File.read('/etc/redhat-release').strip
|
58
|
+
{
|
59
|
+
variant: :rhel,
|
60
|
+
distro: data.split.shift.downcase,
|
61
|
+
release: data =~ /\d+(\.\d+)*/ ? $~[0] : ''
|
62
|
+
}
|
63
|
+
elsif File.file?('/etc/SUSE-brand') || File.file?('/etc/SuSE-release')
|
64
|
+
data = File.readlines(File.file?('/etc/SUSE-brand') ? '/etc/SUSE-brand' : '/etc/SuSE-release')
|
65
|
+
{
|
66
|
+
variant: :suse,
|
67
|
+
distro: data.shift.split.shift.downcase,
|
68
|
+
release: (data.find { |s| s.strip =~ /\AVERSION\s*=/ } || '').split('=').last || ''
|
69
|
+
}
|
70
|
+
elsif File.file?('/etc/debian_version')
|
71
|
+
{
|
72
|
+
variant: :debian,
|
73
|
+
distro: 'generic',
|
74
|
+
release: File.read('/etc/debian_version').strip.split('.').shift
|
75
|
+
}
|
76
|
+
else
|
77
|
+
{
|
78
|
+
}
|
79
|
+
end
|
80
|
+
distro[:pkgman] = case distro[:variant]
|
81
|
+
when :debian
|
82
|
+
Apt.new(distro)
|
83
|
+
when :rhel
|
84
|
+
Dnf.new(distro)
|
85
|
+
when :suse
|
86
|
+
Zypper.new(distro)
|
87
|
+
when :arch
|
88
|
+
Pacman.new(distro)
|
89
|
+
end
|
90
|
+
distro
|
91
|
+
end
|
92
|
+
|
93
|
+
end
|
94
|
+
|
95
|
+
class NixManager < PkgManager
|
96
|
+
|
97
|
+
def initialize(_distro)
|
98
|
+
super()
|
99
|
+
@has_sudo = system('command -v sudo > /dev/null')
|
100
|
+
end
|
101
|
+
|
102
|
+
def make_install_command(*pkgs)
|
103
|
+
auth_cmd(get_install_command(*pkgs))
|
104
|
+
end
|
105
|
+
|
106
|
+
def make_uninstall_command(*pkgs)
|
107
|
+
auth_cmd(get_uninstall_command(*pkgs))
|
108
|
+
end
|
109
|
+
|
110
|
+
protected
|
111
|
+
|
112
|
+
def get_install_command(*pkgs)
|
113
|
+
raise NoMethodError
|
114
|
+
end
|
115
|
+
|
116
|
+
def get_uninstall_command(*pkgs)
|
117
|
+
raise NoMethodError
|
118
|
+
end
|
119
|
+
|
120
|
+
def is_root?
|
121
|
+
`id -u 2>/dev/null`.chomp == '0'
|
122
|
+
end
|
123
|
+
|
124
|
+
def auth_cmd(cmd)
|
125
|
+
raise "Cannot find 'sudo' for command [#{cmd}]" unless is_root? || has_sudo?
|
126
|
+
is_root? ? cmd : "sudo #{cmd}"
|
127
|
+
end
|
128
|
+
|
129
|
+
end
|
130
|
+
|
131
|
+
class Apt < NixManager
|
132
|
+
|
133
|
+
def installed?(pkg)
|
134
|
+
# get architecture
|
135
|
+
system("dpkg-query -s \"#{pkg}:#{pkg_arch}\" >/dev/null 2>&1") ||
|
136
|
+
system("dpkg-query -s \"#{pkg}:all\" >/dev/null 2>&1") ||
|
137
|
+
(`dpkg-query -s \"#{pkg}\" 2>/dev/null`.strip =~ /Architecture: (#{pkg_arch}|all)/)
|
138
|
+
end
|
139
|
+
|
140
|
+
def available?(pkg)
|
141
|
+
apt_cache.include?(pkg)
|
142
|
+
end
|
143
|
+
|
144
|
+
protected
|
145
|
+
|
146
|
+
def apt_cmd(cmd)
|
147
|
+
"DEBIAN_FRONTEND=noninteractive apt-get -q -o=Dpkg::Use-Pty=0 #{cmd}"
|
148
|
+
end
|
149
|
+
|
150
|
+
def get_install_command(*pkgs)
|
151
|
+
apt_cmd("install -y #{pkgs.flatten.join(' ')}")
|
152
|
+
end
|
153
|
+
|
154
|
+
def get_uninstall_command(*pkgs)
|
155
|
+
apt_cmd("remove -y #{pkgs.flatten.join(' ')}")
|
156
|
+
end
|
157
|
+
|
158
|
+
def update_pkgs
|
159
|
+
system(auth_cmd(apt_cmd('update')))
|
160
|
+
end
|
161
|
+
|
162
|
+
def apt_cache
|
163
|
+
unless @apt_cache
|
164
|
+
update_pkgs
|
165
|
+
@apt_cache = `apt-cache pkgnames`.chomp.split("\n").collect { |s| s.strip }
|
166
|
+
end
|
167
|
+
@apt_cache
|
168
|
+
end
|
169
|
+
|
170
|
+
def pkg_arch
|
171
|
+
@pkg_arch ||= `dpkg --print-architecture`.strip
|
172
|
+
end
|
173
|
+
|
174
|
+
end
|
175
|
+
|
176
|
+
class Dnf < NixManager
|
177
|
+
|
178
|
+
def installed?(pkg)
|
179
|
+
system("dnf list installed #{pkg} >/dev/null 2>&1")
|
180
|
+
end
|
181
|
+
|
182
|
+
def available?(pkg)
|
183
|
+
!!(`dnf repoquery --info #{pkg} 2>/dev/null`.strip =~ /Name\s*:\s*#{pkg}/)
|
184
|
+
end
|
185
|
+
|
186
|
+
protected
|
187
|
+
|
188
|
+
def dnf_cmd(cmd)
|
189
|
+
"dnf #{cmd}"
|
190
|
+
end
|
191
|
+
|
192
|
+
def get_install_command(*pkgs)
|
193
|
+
dnf_cmd("install -y #{pkgs.flatten.join(' ')}")
|
194
|
+
end
|
195
|
+
|
196
|
+
def get_uninstall_command(*pkgs)
|
197
|
+
dnf_cmd("remove -y #{pkgs.flatten.join(' ')}")
|
198
|
+
end
|
199
|
+
|
200
|
+
end
|
201
|
+
|
202
|
+
class Zypper < NixManager
|
203
|
+
|
204
|
+
def installed?(pkg)
|
205
|
+
system("rpm -q --whatprovides #{pkg} >/dev/null 2>&1")
|
206
|
+
end
|
207
|
+
|
208
|
+
def available?(pkg)
|
209
|
+
system("zypper -x -t package #{pkg} >/dev/null 2>&1")
|
210
|
+
end
|
211
|
+
|
212
|
+
protected
|
213
|
+
|
214
|
+
def zypper_cmd(cmd)
|
215
|
+
"zypper -t -i #{cmd}"
|
216
|
+
end
|
217
|
+
|
218
|
+
def get_install_command(*pkgs)
|
219
|
+
zypper_cmd("install -y #{pkgs.flatten.join(' ')}")
|
220
|
+
end
|
221
|
+
|
222
|
+
def get_uninstall_command(*pkgs)
|
223
|
+
zypper_cmd("remove -y #{pkgs.flatten.join(' ')}")
|
224
|
+
end
|
225
|
+
|
226
|
+
end
|
227
|
+
|
228
|
+
class Pacman < NixManager
|
229
|
+
|
230
|
+
def installed?(pkg)
|
231
|
+
system("pacman -Qq #{pkg} >/dev/null 2>&1")
|
232
|
+
end
|
233
|
+
|
234
|
+
def available?(pkg)
|
235
|
+
system(%Q[pacman -Ss "^#{pkg}$" >/dev/null 2>&1])
|
236
|
+
end
|
237
|
+
|
238
|
+
protected
|
239
|
+
|
240
|
+
def pacman_cmd(cmd)
|
241
|
+
"pacman --noconfirm #{cmd}"
|
242
|
+
end
|
243
|
+
|
244
|
+
def get_install_command(*pkgs)
|
245
|
+
pacman_cmd("-S --needed #{ pkgs.join(' ') }")
|
246
|
+
end
|
247
|
+
|
248
|
+
def get_uninstall_command(*pkgs)
|
249
|
+
pacman_cmd("-Rsu #{pkgs.flatten.join(' ')}")
|
250
|
+
end
|
251
|
+
|
252
|
+
end
|
253
|
+
|
254
|
+
end
|
255
|
+
|
256
|
+
end
|
257
|
+
|
258
|
+
self.sniffers[:linux] = Sniffer::Linux
|
259
|
+
|
260
|
+
end
|
@@ -0,0 +1,55 @@
|
|
1
|
+
# Copyright (c) 2023 M.J.N. Corino, The Netherlands
|
2
|
+
#
|
3
|
+
# This software is released under the MIT license.
|
4
|
+
#
|
5
|
+
# Plat4m Windows sniffer
|
6
|
+
|
7
|
+
|
8
|
+
module Plat4m
|
9
|
+
|
10
|
+
module Sniffer
|
11
|
+
|
12
|
+
module Windows
|
13
|
+
|
14
|
+
class << self
|
15
|
+
|
16
|
+
def detect_system
|
17
|
+
# determine system platform
|
18
|
+
System.new(System::Platform.new(arch: get_arch, cpus: get_cpu_count),
|
19
|
+
System::OS.new(id: :windows, **get_distro))
|
20
|
+
end
|
21
|
+
|
22
|
+
private
|
23
|
+
|
24
|
+
def get_arch
|
25
|
+
arch, _ = RbConfig::CONFIG['arch'].split('-')
|
26
|
+
arch = 'x86' if arch =~ /i\d86/
|
27
|
+
arch
|
28
|
+
end
|
29
|
+
|
30
|
+
def get_cpu_count
|
31
|
+
ENV['NUMBER_OF_PROCESSORS'].to_i
|
32
|
+
end
|
33
|
+
|
34
|
+
def get_distro
|
35
|
+
distro = {
|
36
|
+
distro: 'windows'
|
37
|
+
}
|
38
|
+
# the 'ver' command returns something like "Microsoft Windows [Version xx.xx.xx.xx]"
|
39
|
+
match = `ver`.strip.match(/\[(.*)\]/)
|
40
|
+
ver = match[1].split.last
|
41
|
+
distro[:release] = ver.split('.').shift
|
42
|
+
distro[:version] = ver
|
43
|
+
distro[:pkgman] = nil
|
44
|
+
distro
|
45
|
+
end
|
46
|
+
|
47
|
+
end
|
48
|
+
|
49
|
+
end
|
50
|
+
|
51
|
+
end
|
52
|
+
|
53
|
+
self.sniffers[:windows] = Sniffer::Darwin
|
54
|
+
|
55
|
+
end
|
@@ -0,0 +1,179 @@
|
|
1
|
+
# Copyright (c) 2023 M.J.N. Corino, The Netherlands
|
2
|
+
#
|
3
|
+
# This software is released under the MIT license.
|
4
|
+
#
|
5
|
+
# Plat4m System class
|
6
|
+
|
7
|
+
|
8
|
+
module Plat4m
|
9
|
+
|
10
|
+
# Instances of this class identify a system and provide access to system management support.
|
11
|
+
class System
|
12
|
+
|
13
|
+
# Provides information about the hardware platform.
|
14
|
+
class Platform
|
15
|
+
|
16
|
+
def initialize(arch: nil, cpus: nil)
|
17
|
+
@arch = arch
|
18
|
+
@bits = @arch.to_s =~ /64/ ? 64 : 32
|
19
|
+
@cpus = cpus
|
20
|
+
end
|
21
|
+
|
22
|
+
attr_reader :arch, :bits, :cpus
|
23
|
+
|
24
|
+
def complete?
|
25
|
+
::String === @arch && !@arch.empty? &&
|
26
|
+
::Integer === cpus && @cpus>0
|
27
|
+
end
|
28
|
+
|
29
|
+
def to_s
|
30
|
+
"[#{@arch}: #{@bits}bits, #{cpus} cpu]"
|
31
|
+
end
|
32
|
+
|
33
|
+
end
|
34
|
+
|
35
|
+
# Provides information about the operating system.
|
36
|
+
class OS
|
37
|
+
|
38
|
+
def initialize(id: nil, distro: nil, variant: nil, release: nil, pkgman: nil, **other)
|
39
|
+
@id = id
|
40
|
+
@distro = distro
|
41
|
+
@variant = variant
|
42
|
+
@release = release
|
43
|
+
@pkgman = pkgman
|
44
|
+
@other = other
|
45
|
+
@other.each_key do |key|
|
46
|
+
unless self.method(key.to_sym)
|
47
|
+
singleton_class.class_eval <<~__CODE
|
48
|
+
define_method(:#{key}) do
|
49
|
+
@other['#{key}']
|
50
|
+
end
|
51
|
+
__CODE
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
attr_reader :id, :distro, :release, :pkgman
|
57
|
+
|
58
|
+
def variant
|
59
|
+
@variant || @distro
|
60
|
+
end
|
61
|
+
|
62
|
+
alias :distribution :distro
|
63
|
+
|
64
|
+
def complete?
|
65
|
+
::Symbol === @id &&
|
66
|
+
::String === @distro && !@distro.empty?
|
67
|
+
::String === @release && !@release.empty?
|
68
|
+
end
|
69
|
+
|
70
|
+
def is_root?
|
71
|
+
@pkgman ? @pkgman.is_root? : false
|
72
|
+
end
|
73
|
+
|
74
|
+
def has_sudo?
|
75
|
+
@pkgman ? @pkgman.has_sudo? : false
|
76
|
+
end
|
77
|
+
|
78
|
+
def to_s
|
79
|
+
"#{@distro}-#{@release}[#{@id}#{@variant ? " #{@variant}" : ''}}]"
|
80
|
+
end
|
81
|
+
|
82
|
+
end
|
83
|
+
|
84
|
+
def initialize(platform, os)
|
85
|
+
unless platform && platform.complete? && os && os.complete?
|
86
|
+
raise "Invalid system specification [#{os} @ #{platform}]"
|
87
|
+
end
|
88
|
+
@platform = platform
|
89
|
+
@os = os
|
90
|
+
end
|
91
|
+
|
92
|
+
attr_reader :platform, :os
|
93
|
+
|
94
|
+
def kind
|
95
|
+
"#{@platform.arch}-#{@os.id}"
|
96
|
+
end
|
97
|
+
|
98
|
+
def intel?
|
99
|
+
@platform.arch =~ /x86/
|
100
|
+
end
|
101
|
+
|
102
|
+
def arm?
|
103
|
+
@platform.arch =~ /arm/
|
104
|
+
end
|
105
|
+
|
106
|
+
def bits
|
107
|
+
@platform.bits
|
108
|
+
end
|
109
|
+
|
110
|
+
def cpu_count
|
111
|
+
@platform.cpus
|
112
|
+
end
|
113
|
+
|
114
|
+
def linux?
|
115
|
+
@os.id == :linux
|
116
|
+
end
|
117
|
+
|
118
|
+
def windows?
|
119
|
+
@os.id == :windows
|
120
|
+
end
|
121
|
+
|
122
|
+
def darwin?
|
123
|
+
@os.id == :darwin
|
124
|
+
end
|
125
|
+
|
126
|
+
def macosx?
|
127
|
+
darwin? && @os.distro == 'MacOSX'
|
128
|
+
end
|
129
|
+
alias :osx? :macosx?
|
130
|
+
|
131
|
+
def freebsd?
|
132
|
+
@os.id == :freebsd
|
133
|
+
end
|
134
|
+
|
135
|
+
def dev_null
|
136
|
+
windows? ? 'NUL' : '/dev/null'
|
137
|
+
end
|
138
|
+
|
139
|
+
end
|
140
|
+
|
141
|
+
class << self
|
142
|
+
|
143
|
+
# Returns System instance for current system.
|
144
|
+
def current
|
145
|
+
@current ||= detect_current
|
146
|
+
end
|
147
|
+
|
148
|
+
# System sniffer registry.
|
149
|
+
def sniffers
|
150
|
+
@sniffers ||= {}
|
151
|
+
end
|
152
|
+
|
153
|
+
def detect_current
|
154
|
+
case RbConfig::CONFIG['host_os']
|
155
|
+
when /linux/
|
156
|
+
sniffers[:linux].detect_system
|
157
|
+
when /darwin/
|
158
|
+
sniffers[:darwin].detect_system
|
159
|
+
when /freebsd/
|
160
|
+
sniffers[:freebsd].detect_system
|
161
|
+
else
|
162
|
+
if ENV['OS'] =~ /windows/i
|
163
|
+
sniffers[:windows].detect_system
|
164
|
+
else
|
165
|
+
raise "Unknown system!"
|
166
|
+
end
|
167
|
+
end
|
168
|
+
end
|
169
|
+
private :detect_current
|
170
|
+
|
171
|
+
end
|
172
|
+
|
173
|
+
end
|
174
|
+
|
175
|
+
require_relative 'pkgman'
|
176
|
+
require_relative 'sniff/darwin'
|
177
|
+
require_relative 'sniff/linux'
|
178
|
+
require_relative 'sniff/windows'
|
179
|
+
require_relative 'sniff/freebsd'
|
data/lib/plat4m.rb
ADDED
@@ -0,0 +1,15 @@
|
|
1
|
+
# Copyright (c) 2023 M.J.N. Corino, The Netherlands
|
2
|
+
#
|
3
|
+
# This software is released under the MIT license.
|
4
|
+
#
|
5
|
+
# Plat4m loader
|
6
|
+
|
7
|
+
|
8
|
+
# Plat4m provides methods and classes to scout the details of the computer system and
|
9
|
+
# support system management tasks.
|
10
|
+
module Plat4m
|
11
|
+
|
12
|
+
end
|
13
|
+
|
14
|
+
require_relative 'plat4m/version'
|
15
|
+
require_relative 'plat4m/system'
|
metadata
ADDED
@@ -0,0 +1,55 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: plat4m
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 1.0.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Martin Corino
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2024-02-20 00:00:00.000000000 Z
|
12
|
+
dependencies: []
|
13
|
+
description: Plat4m is a simple runtime system platform scouting and support library.
|
14
|
+
email: mcorino@m2c-software.nl
|
15
|
+
executables: []
|
16
|
+
extensions: []
|
17
|
+
extra_rdoc_files: []
|
18
|
+
files:
|
19
|
+
- LICENSE
|
20
|
+
- README.md
|
21
|
+
- lib/plat4m.rb
|
22
|
+
- lib/plat4m/pkgman.rb
|
23
|
+
- lib/plat4m/sniff/darwin.rb
|
24
|
+
- lib/plat4m/sniff/freebsd.rb
|
25
|
+
- lib/plat4m/sniff/linux.rb
|
26
|
+
- lib/plat4m/sniff/windows.rb
|
27
|
+
- lib/plat4m/system.rb
|
28
|
+
- lib/plat4m/version.rb
|
29
|
+
homepage: https://github.com/mcorino/plat4m
|
30
|
+
licenses:
|
31
|
+
- MIT
|
32
|
+
metadata:
|
33
|
+
bug_tracker_uri: https://github.com/mcorino/plat4m/issues
|
34
|
+
homepage_uri: https://github.com/mcorino/plat4m
|
35
|
+
github_repo: https://github.com/mcorino/plat4m
|
36
|
+
post_install_message:
|
37
|
+
rdoc_options: []
|
38
|
+
require_paths:
|
39
|
+
- lib
|
40
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
41
|
+
requirements:
|
42
|
+
- - ">="
|
43
|
+
- !ruby/object:Gem::Version
|
44
|
+
version: '2.5'
|
45
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
46
|
+
requirements:
|
47
|
+
- - ">="
|
48
|
+
- !ruby/object:Gem::Version
|
49
|
+
version: '0'
|
50
|
+
requirements: []
|
51
|
+
rubygems_version: 3.5.3
|
52
|
+
signing_key:
|
53
|
+
specification_version: 4
|
54
|
+
summary: Runtime system detection.
|
55
|
+
test_files: []
|