yasysdui 1.0.0

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 ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: dc6996d90288b984473de433a8fc90e844aa0befdf4dac1a3cfd0bce05f8b675
4
+ data.tar.gz: 00442c19eab41de2c19b92eaeb84862510d1663b0db49270f53020f0db07fd29
5
+ SHA512:
6
+ metadata.gz: 0bedfb66c7e346bdaf8b0fe4e67809570a670005cbbc3d659d6d5d49ccc19bded39e6e250308fa53484d5ae67519555aab0919502194c078e7577dde6515ea75
7
+ data.tar.gz: 9ca1e5c4a163c7fe0b5d91340b2382b56a60617ec3a2fc12134abfd3844022adad8a757cfe249f88781159dd6f602b01363474ccf3eedd8927f2161763924f01
data/bin/yasysdui ADDED
@@ -0,0 +1,210 @@
1
+ #!/usr/bin/env ruby
2
+ =begin
3
+ Start/stop systemd service **on demand**
4
+ =end
5
+
6
+
7
+ require 'gtk3'
8
+ require 'yasysdui'
9
+
10
+ # Obsolete
11
+ #$MANAGED_SERVICES = Array.new
12
+ # Personalisation of managed services:
13
+ #
14
+ # syntax:
15
+ # $MANAGED_SERVICES << "service_name"
16
+ #$MANAGED_SERVICES << "vpnagentd"
17
+ #$MANAGED_SERVICES << "naclient"
18
+
19
+ #*********** List of services************************
20
+ def load_service_list
21
+
22
+ lsto = ServiceListStore.new_all_service
23
+
24
+ # lsto = ServiceListStore.new
25
+ # $MANAGED_SERVICES.each{|s| lsto.append_managed_service(s) }
26
+
27
+ lsto.sort_by_unit
28
+
29
+ $list=FilteredServiceListStore.new(lsto)
30
+ sci = ServiceCatalog.instance
31
+
32
+ # quick and dirty but working fast search (uses a full text index)
33
+ $list.set_visible_func( ){|model, iter|
34
+
35
+ if $list.filterstr
36
+ if $list.filterstr.length >= 2
37
+ servname = iter.get_value( Column_ID::Unit )
38
+ if servname
39
+ if rset = sci.idx[$list.filterstr]
40
+ rset.include?(servname)
41
+ end
42
+ else
43
+ false
44
+ end
45
+ else
46
+ true
47
+ end
48
+ else
49
+ true
50
+ end
51
+ }
52
+ end
53
+ ### a search field
54
+ class FastSearchEntry < Gtk::SearchEntry
55
+ attr_accessor :tool_item
56
+ def initialize
57
+ super
58
+ @tool_item = Gtk::ToolItem.new
59
+ @tool_item.add(self)
60
+ end
61
+ end
62
+
63
+ #*********************************************************
64
+ #The application toolbar, migh contain only global actions, like
65
+ # reload/exit/search ...
66
+ class AppToolbar < Gtk::Toolbar
67
+ def initialize
68
+ super
69
+ @item_count = 0
70
+ set_toolbar_style Gtk::ToolbarStyle::ICONS
71
+ @quit_bt = Gtk::ToolButton.new :stock_id => Gtk::Stock::QUIT
72
+ @reload_bt = Gtk::ToolButton.new :stock_id => Gtk::Stock::REFRESH
73
+ @fastsearch_in = FastSearchEntry.new
74
+ self.append(@reload_bt)
75
+ sep_start = Gtk::SeparatorToolItem.new
76
+ sep_start.draw = true; sep_start.expand = false
77
+ self.append(sep_start)
78
+ self.append(@fastsearch_in.tool_item)
79
+ sep_end = Gtk::SeparatorToolItem.new
80
+ sep_end.draw = false; sep_end.expand = true
81
+ self.append(sep_end)
82
+ self.append(@quit_bt)
83
+ end
84
+ def append(w)
85
+ self.insert(w, @item_count)
86
+ @item_count = @item_count + 1
87
+ end
88
+ def signal_quit_bt_clicked_connect(app)
89
+ @quit_bt.signal_connect("clicked"){ app.destroy; Gtk.main_quit }
90
+ end
91
+ def signal_reload_bt_clicked_connect(app)
92
+ @reload_bt.signal_connect("clicked"){ app.reload }
93
+ end
94
+ def signal_fastsearch_changed_connect(app)
95
+ @fastsearch_in.signal_connect("search_changed"){
96
+ app.do_fastsearch(@fastsearch_in.text)
97
+ }
98
+ end
99
+ end
100
+
101
+ # the area to display informations about your units/services
102
+ # will have a scrolled list and a detail view parts
103
+ class InformationArea < Gtk::Paned
104
+ def initialize(scrolled_list, detail_area)
105
+ super(:vertical)
106
+ add1(scrolled_list)
107
+ add2(detail_area)
108
+ end
109
+ end
110
+
111
+ # The area to display a scrolled list of a part or all of your services
112
+ class ListArea < Gtk::ScrolledWindow
113
+ attr_accessor :trv
114
+ def initialize
115
+ super
116
+ load_service_list
117
+ @trv = ServiceListView.new($list)
118
+ add(@trv)
119
+ self.height_request=(300)
120
+ self.hscrollbar_policy = self.vscrollbar_policy = :automatic
121
+ # self.max_content_height = 400
122
+ # self.min_content_height = 300
123
+ end
124
+ end
125
+ # The area to display detailled information about a selected service
126
+ # and a service toolbar with some actions to be performed on
127
+ # the selected service
128
+ class DetailArea < Gtk::Box
129
+ def initialize(service_controler)
130
+
131
+ super(:vertical)
132
+
133
+ @tev = Gtk::TextView.new(service_controler.txtv)
134
+ @tev.editable = false
135
+ @tev.cursor_visible = false
136
+
137
+
138
+ @service_toolbar = ServiceToolbar.new(service_controler)
139
+
140
+ @tev_scroll = Gtk::ScrolledWindow.new
141
+ @tev_scroll.add(@tev)
142
+ @tev_scroll.height_request=(120)
143
+ @tev_scroll.hscrollbar_policy = @tev_scroll.vscrollbar_policy = :automatic
144
+ pack_start(@service_toolbar, :expand => false)
145
+ pack_end(@tev_scroll, :expand => true)
146
+
147
+ end
148
+ end
149
+
150
+ class ServiceToolbar < Gtk::ButtonBox
151
+ def initialize(service_controler)
152
+ super(:horizontal)
153
+
154
+ self.layout_style = :start
155
+ pack_start(service_controler.start_bt, :expand => false, :fill => false)
156
+ pack_start(service_controler.stop_bt, :expand =>false, :fill => false)
157
+ pack_start(service_controler.status_bt, :expand =>false, :fill => false)
158
+ pack_start(service_controler.restart_bt, :expand =>false, :fill => false)
159
+
160
+ end
161
+ end
162
+ # the thing that everybody would call main Window
163
+
164
+ # This will have:
165
+ # a global toolbar for global actions
166
+ # an information area (cf. below)
167
+ # a filter area (planned)
168
+ # no menubar yet
169
+ class Application < Gtk::Window
170
+ def initialize
171
+ super
172
+ signal_connect("delete_event") { false }
173
+ signal_connect("destroy") { puts "Bye Bye"; Gtk.main_quit }
174
+ self.border_width = 1
175
+
176
+ @list_area = ListArea.new
177
+
178
+ @txtv = Gtk::TextBuffer.new
179
+
180
+ @service_controler = ServiceControler.new(@txtv, @list_area.trv)
181
+ @detail_area = DetailArea.new(@service_controler)
182
+ @info_area = InformationArea.new(@list_area, @detail_area)
183
+
184
+ @vbox = Gtk::Box.new(:vertical)
185
+ @toolbar = AppToolbar.new
186
+ @toolbar.signal_quit_bt_clicked_connect(self)
187
+ @toolbar.signal_reload_bt_clicked_connect(self)
188
+ @toolbar.signal_fastsearch_changed_connect(self)
189
+ @vbox.pack_start(@toolbar, :expand => false)
190
+ @vbox.pack_end(@info_area, :expand => true)
191
+
192
+ add(@vbox)
193
+ self.set_default_size(800, 500)
194
+ end
195
+ def reload
196
+ $list.child_model.reload
197
+ @service_controler.connect_list_sel_to_textv
198
+ end
199
+ def do_fastsearch(text)
200
+ @list_area.trv.model.filterstr = text
201
+ @list_area.trv.model.refilter
202
+ end
203
+ end
204
+
205
+ app = Application.new
206
+
207
+ app.show_all
208
+
209
+ Gtk.main
210
+
data/lib/yasysdui.rb ADDED
@@ -0,0 +1,3 @@
1
+ require 'pp'
2
+ require_relative 'yasysdui/service_controler'
3
+ require_relative 'yasysdui/service_list'
@@ -0,0 +1,13 @@
1
+ require 'gtk3'
2
+
3
+ class CommandButton < Gtk::Button
4
+
5
+ attr_accessor :ctrl
6
+ attr_accessor :actionStr
7
+ def initialize(actionStr, ctrl)
8
+ super(:label => actionStr)
9
+ @ctrl = ctrl
10
+ @actionStr = actionStr
11
+ self.signal_connect("clicked") {@ctrl.execute(@actionStr)}
12
+ end
13
+ end
@@ -0,0 +1,37 @@
1
+
2
+ require 'set'
3
+ # quick and dirty "Full text" indexer for fastsearch.
4
+ # works fine for small amounts of data
5
+
6
+ module Indexable
7
+
8
+ def each_word
9
+ each_sentence{|sen|
10
+ sen.split(%r{[[:space:]]+|[[:punct:]]+}).each{|w| yield w }
11
+ }
12
+ end
13
+
14
+ def each_wordstart
15
+ each_word{|w|
16
+ wstart = ''
17
+ w.downcase.each_char{|c|
18
+ wstart << c
19
+ yield wstart
20
+ }
21
+ }
22
+ end
23
+
24
+ end
25
+
26
+
27
+
28
+ class SimpleIndex < Hash
29
+ def compile(obj)
30
+ obj.each_wordstart {|ws|
31
+ unless self.has_key?(ws)
32
+ self[ws] = Set.new
33
+ end
34
+ self[ws].add(obj)
35
+ }
36
+ end
37
+ end
@@ -0,0 +1,118 @@
1
+ require 'singleton'
2
+ require_relative 'system_service'
3
+
4
+
5
+ class ServiceCatalog < Hash
6
+ include Singleton
7
+ attr_accessor :idx
8
+ def initialize
9
+ super
10
+ @idx = SimpleIndex.new
11
+ self.get_all_service
12
+ self.build_index
13
+ end
14
+ def rebuild
15
+ clear
16
+ self.get_all_service
17
+ self.build_index
18
+ end
19
+ def build_index
20
+ print "Building fast search index... "
21
+ self.each_value{|srv|
22
+ @idx.compile(srv)
23
+ }
24
+ print "done\n"
25
+
26
+ end
27
+ @@cmd_know_units = "sudo systemctl list-units -a -l -t service --no-pager --no-legend"
28
+ @@initd= "/etc/init.d"
29
+ @@initd_ignore = /README|.+~/
30
+ ## UNIT LOAD ACTIVE SUB DESCRIPTION
31
+ @@rgx_ku = Regexp.new('\A([[:graph:]]+)\.service\s+' +
32
+ '([[:graph:]]+)\s+'+
33
+ '([[:alnum:]]+)\s+'+
34
+ '([[:alnum:]]+)\s+'+
35
+ '([[:print:]]+)\Z')
36
+ @@cmd_list_unit_files = "sudo systemctl list-unit-files -a -l -t service --no-pager --no-legend"
37
+ ## UNIT STATE
38
+ @@rgx_li = Regexp.new('\A([[:graph:]]+)\.service\s+' +
39
+ '([[:graph:]]+)\Z')
40
+
41
+ # get all know systemd native units from systemctl list-units
42
+ def get_all_known_units
43
+
44
+ match = nil; srv = nil
45
+ stdout_str, status = Open3.capture2( @@cmd_know_units )
46
+ if status.success?
47
+ stdout_str.each_line{|l|
48
+ match = @@rgx_ku.match(l.strip)
49
+ if match
50
+ srv = SystemService.new(match[1] )
51
+ srv.load = match[2]
52
+ srv.active = match[3]
53
+ srv.sub = match[4]
54
+ srv.descr = match[5]
55
+ self[srv] = srv
56
+ else
57
+ puts l
58
+ raise "Failed parsing line printed above"
59
+ end
60
+ }
61
+
62
+ end
63
+ end
64
+ # add all know systemd units files from systemctl list-unit-files
65
+ def add_units_from_file_list
66
+
67
+ match = nil; srv = nil
68
+ stdout_str, status = Open3.capture2( @@cmd_list_unit_files )
69
+ if status.success?
70
+ stdout_str.each_line{|l|
71
+ match = @@rgx_li.match(l.strip)
72
+ if match
73
+ f = match[1]
74
+ unless f.end_with?('@') # ignore template units for now...
75
+ unless self.has_key?(f)
76
+ srv = SystemService.new( f )
77
+ srv.state = match[2]
78
+ srv.read_status_info
79
+ self[srv] = srv if srv
80
+ else
81
+ self[f].state = match[2]
82
+ end
83
+ end
84
+ else
85
+ puts l
86
+ raise "Failed parsing line printed above"
87
+ end
88
+ }
89
+
90
+ end
91
+ end
92
+ # get all legacy init.d scripts
93
+ def add_init_d_scripts
94
+ flist = Dir.glob("#@@initd/*").reject{|f| @@initd_ignore.match(f) }.map{|f| File.basename(f)}
95
+ flist.each{|f|
96
+ # only try to add an init script if it does not exist as an native systemd unit,
97
+ # as these have precedence
98
+ # these assumes we have to read native service before
99
+ if self.has_key?(f)
100
+ srv = self[f]
101
+ srv.overrides_legacy = true
102
+ srv.read_state
103
+ else
104
+ srv = SystemServiceLegacy.new( f )
105
+ self[srv] = srv if srv
106
+ end
107
+ }
108
+ end
109
+ # get all available units/scripts
110
+ def get_all_service
111
+ pp :getting_all_services
112
+ get_all_known_units; pp :got_all_known_units
113
+ add_units_from_file_list; pp :got_all_units_from_file
114
+ add_init_d_scripts; pp :got_all_init_scripts
115
+ puts "Built service catalog with #{self.size} item(s)"
116
+ self
117
+ end
118
+ end
@@ -0,0 +1,55 @@
1
+
2
+ require 'open3'
3
+ require_relative 'command_button'
4
+ require_relative 'service_list'
5
+ require_relative 'system_service'
6
+
7
+ class ServiceControler
8
+ attr_accessor :service
9
+ attr_accessor :start_bt
10
+ attr_accessor :stop_bt
11
+ attr_accessor :status_bt
12
+ attr_accessor :restart_bt
13
+ attr_accessor :txtv
14
+ attr_accessor :listv
15
+ @@cmd = "sudo systemctl"
16
+
17
+ def initialize(txtv, listv)
18
+ @txtv = txtv
19
+ self.init_textv
20
+ @listv = listv
21
+ @start_bt = CommandButton.new("Start", self)
22
+ @stop_bt = CommandButton.new("Stop",self)
23
+ @status_bt = CommandButton.new("Status", self)
24
+ @restart_bt = CommandButton.new("Restart", self)
25
+ connect_list_sel_to_textv
26
+ end
27
+ def init_textv
28
+ @txtv.text = "No service selected"
29
+ end
30
+ def connect_list_sel_to_textv
31
+ @listv.signal_connect_sel_changed(self)
32
+ end
33
+ def execute(action)
34
+ if @service then
35
+ @action_output, @action_call_status = Open3.capture2e("#@@cmd #{action.downcase} #@service" )
36
+ self.ui_update(action)
37
+ end
38
+ end
39
+ def ui_update(action)
40
+ # (always) update textView buffer text
41
+ result_text = "#{action}: #{@service.descr} "
42
+ result_text << "\n Result: #{@action_call_status}"
43
+ result_text << "\n" + @action_output
44
+ @txtv.text = result_text
45
+ # update status info in the result list
46
+ if action.downcase == 'status'
47
+ @status_output = @action_output
48
+ else # not sure if this makes senses in case systemctl call would be non-blocking
49
+ # but otherwise it makes
50
+ @status_output, status_call_status = Open3.capture2e("#@@cmd status #@service" )
51
+ end
52
+ @service.set_status_info_from_output( @status_output )
53
+ @listv.update_selected_row
54
+ end
55
+ end
@@ -0,0 +1,128 @@
1
+
2
+
3
+ require_relative 'service_catalog'
4
+
5
+ module Column_ID
6
+ Unit = 0
7
+ Load = 1
8
+ Active = 2
9
+ Sub = 3
10
+ Descr = 4
11
+ Native_info = 5
12
+ State = 6
13
+ end
14
+
15
+ class FilteredServiceListStore < Gtk::TreeModelFilter
16
+ attr_accessor :filterstr
17
+ end
18
+
19
+ class ServiceListStore < Gtk::ListStore
20
+ include Column_ID
21
+ def self.new_all_service
22
+ sl = ServiceListStore.new
23
+ sl.load_catalog
24
+ sl
25
+ end
26
+ def initialize
27
+ super(String, String, String, String, String, String, String)
28
+ end
29
+ def load_catalog
30
+ sci = ServiceCatalog.instance
31
+ puts "Loading Catalog with #{sci.size} item(s)"
32
+ sci.each_value{|s| append_service(s) }
33
+ end
34
+ def reload
35
+ clear # clear Gtk::ListStore
36
+ ServiceCatalog.instance.rebuild
37
+ load_catalog
38
+ end
39
+ def append_managed_service(name)
40
+ if service = ServiceCatalog.instance[name]
41
+ append_service(service)
42
+ end
43
+ end
44
+ def append_service(service)
45
+ row = self.append
46
+ row[ Unit ] = service
47
+ row[ Load ] = service.load
48
+ row[ Active ] = service.active
49
+ row[ Sub ] = service.sub
50
+ row[ Descr ] = service.descr
51
+ row[ Native_info ] = service.native_info
52
+ row[ State ] = service.state
53
+ end
54
+ def sort_by_unit
55
+ self.set_sort_column_id( Unit, :ascending)
56
+ end
57
+ end
58
+
59
+ class TreeViewColumnToggle < Gtk::TreeViewColumn
60
+ @@cell_renderer = Gtk::CellRendererToggle.new
61
+ def initialize(title, column_id )
62
+ attrs = { :active => column_id }
63
+ super(title, @@cell_renderer , attrs )
64
+ self.resizable = true
65
+ self.sort_column_id = column_id
66
+ end
67
+ end
68
+
69
+ class TreeViewColumnText < Gtk::TreeViewColumn
70
+ @@cell_renderer = Gtk::CellRendererText.new
71
+ def initialize(title, column_id )
72
+ attrs = { :text => column_id }
73
+ super(title, @@cell_renderer , attrs )
74
+ self.resizable = true
75
+ self.sort_column_id = column_id
76
+ end
77
+ end
78
+
79
+ class ServiceListView < Gtk::TreeView
80
+ include Column_ID
81
+ def initialize(list)
82
+ super(list)
83
+ @list = list
84
+ @col1 = TreeViewColumnText.new("Unit", Unit )
85
+
86
+ @col1.fixed_width = 200
87
+ @col1.sort_indicator = true
88
+
89
+ @col2 = TreeViewColumnText.new("Load", Load )
90
+ @col3 = TreeViewColumnText.new("Active", Active )
91
+ @col4 = TreeViewColumnText.new("Sub", Sub)
92
+ @col5 = TreeViewColumnText.new("Description", Descr)
93
+ @col6 = TreeViewColumnText.new("Native?", Native_info)
94
+ @col7 = TreeViewColumnText.new("State", State)
95
+
96
+
97
+ self.append_column(@col1)
98
+ self.append_column(@col6)
99
+ self.append_column(@col7)
100
+ self.append_column(@col2)
101
+ self.append_column(@col3)
102
+ self.append_column(@col4)
103
+ self.append_column(@col5)
104
+
105
+ self.enable_search = true
106
+ end
107
+
108
+ def signal_connect_sel_changed(sctrl)
109
+ @sel = self.selection
110
+ @sel.mode = :browse
111
+ @sel.signal_connect("changed"){
112
+ if @sel.selected
113
+ @service = ServiceCatalog.instance[@sel.selected[Unit] ]
114
+ sctrl.service = @service
115
+ sctrl.execute("Status")
116
+ else
117
+ sctrl.init_textv
118
+ end
119
+ }
120
+ end
121
+
122
+ def update_selected_row
123
+ iter = self.model.convert_iter_to_child_iter( @sel.selected )
124
+ iter.set_value(Load, @service.load)
125
+ iter.set_value(Active, @service.active)
126
+ iter.set_value(Sub, @service.sub)
127
+ end
128
+ end
@@ -0,0 +1,147 @@
1
+ require_relative 'index'
2
+ require 'pp'
3
+
4
+ class SystemService < String
5
+ include Indexable
6
+ attr_accessor :descr
7
+ attr_accessor :state
8
+ attr_accessor :load
9
+ attr_accessor :active
10
+ attr_accessor :sub
11
+ attr_accessor :overrides_legacy
12
+ attr_accessor :filename_full
13
+
14
+ @@cmd_info = "sudo systemctl status"
15
+ @@descr_rgx = /\A.+\.service\s+-\s+([[:print:]]+)\Z/
16
+ @@descr_masked_rgx = /\A.+\.service\Z/
17
+ @@loaded_rgx = /\ALoaded:\s+([[:graph:]]+)\s+\((.*)\)\Z/
18
+ @@active_rgx = /\AActive:\s+([[:graph:]]+)\s+\(([[:graph:]]+)\).*\Z/
19
+ @@warning_rgx = /\AWarning:/
20
+ @@status_read_failed_rgx = Regexp.new('\AFailed to get properties:.*\Z')
21
+ @@status_unit_notfound_rgx = Regexp.new('\AUnit\s[[:graph:]]+\scould\snot\sbe\sfound.\Z')
22
+ def set_status_info_from_output( action_output )
23
+ @status_info_raw = action_output
24
+ self.parse_status_info
25
+ end
26
+ # This provides the texts to index (module Indexable)
27
+ def each_sentence
28
+ yield self.to_str
29
+ yield @descr unless @descr.nil?
30
+ end
31
+ def parse_status_info
32
+ match = nil
33
+ return if self.handle_masked_info
34
+ info_tab = @status_info_raw.lines.reject{|l| @@warning_rgx.match(l) }
35
+ info_tab.map!{|r| r.strip}
36
+ if @@status_read_failed_rgx.match(info_tab[0])
37
+ return nil
38
+ end
39
+ if @@status_unit_notfound_rgx.match(info_tab[0])
40
+ return nil
41
+ end
42
+ if match = @@descr_rgx.match(info_tab[0])
43
+ self.descr = match[1]
44
+ else
45
+ # masked script/service without description returned
46
+ if match = @@descr_masked_rgx.match(info_tab[0])
47
+ else
48
+ puts info_tab[0]
49
+ raise "Failed parsing line printed above"
50
+ end
51
+
52
+ end
53
+ # complete data
54
+ if match
55
+ match = @@loaded_rgx.match(info_tab[1])
56
+ if match
57
+ self.load = match[1]
58
+ load_info = match[2].split(';')
59
+ self.filename_full = load_info[0]
60
+ self.state = load_info[1]
61
+ end
62
+ match = @@active_rgx.match(info_tab[2].strip)
63
+ if match
64
+ self.active = match[1]
65
+ self.sub = match[2]
66
+ end
67
+ end
68
+
69
+ end
70
+ def handle_masked_info
71
+ if self.state == 'masked'
72
+ @load = 'masked'
73
+ @active = 'inactive'
74
+ @sub = 'dead'
75
+ true
76
+ else
77
+ false
78
+ end
79
+ end
80
+ def read_status_info
81
+ return nil if self.end_with?("@")
82
+ return if self.handle_masked_info
83
+ @status_info_raw, status = Open3.capture2("#@@cmd_info #{self.to_s}" )
84
+ if @status_info_raw.lines.size > 0
85
+ self.parse_status_info
86
+ else
87
+ # TODO: a more decent error handling...
88
+ puts "Failed getting service status info for"
89
+ pp self
90
+ end
91
+ end
92
+ def read_state
93
+ return nil if self.end_with?("@")
94
+ match = nil
95
+ stdout_str, status = Open3.capture2("#@@cmd_info #{self.to_s}" )
96
+ if stdout_str.lines.size > 0
97
+
98
+ info_tab = stdout_str.lines.reject{|l| @@warning_rgx.match(l) }
99
+ if @@status_read_failed_rgx.match(info_tab[0].strip)
100
+ return nil
101
+ end
102
+ match = @@loaded_rgx.match(info_tab[1].strip)
103
+ if match
104
+ load_info = match[2].split(';')
105
+ self.filename_full = load_info[0]
106
+ self.state = load_info[1]
107
+ end
108
+
109
+
110
+ else
111
+ puts "Failed getting service state info for"
112
+ pp self
113
+
114
+ end
115
+ end
116
+ # default constructor, takes unit name
117
+ def initialize(str)
118
+ super(str)
119
+ @overrides_legacy = false
120
+ end
121
+ def native_info
122
+ # yes+ : native and overrides init script
123
+ # yes : native and no init script
124
+ # no : init script
125
+ if self.native?
126
+ @overrides_legacy ? "yes+" : "yes"
127
+ else
128
+ "no"
129
+ end
130
+ end
131
+ def native?
132
+ true
133
+ end
134
+
135
+ end
136
+
137
+ class SystemServiceLegacy < SystemService
138
+
139
+ def initialize(str)
140
+ super(str)
141
+ self.read_status_info
142
+ end
143
+ def native?
144
+ false
145
+ end
146
+ end
147
+
metadata ADDED
@@ -0,0 +1,66 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: yasysdui
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.0.0
5
+ platform: ruby
6
+ authors:
7
+ - Denis Mertz
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2018-09-09 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: gtk3
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '3.2'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '3.2'
27
+ description: A quick and dirty gtk3 ui wrapper around systemd/systemctl
28
+ email: dev@familie-mertz.eu
29
+ executables:
30
+ - yasysdui
31
+ extensions: []
32
+ extra_rdoc_files: []
33
+ files:
34
+ - bin/yasysdui
35
+ - lib/yasysdui.rb
36
+ - lib/yasysdui/command_button.rb
37
+ - lib/yasysdui/index.rb
38
+ - lib/yasysdui/service_catalog.rb
39
+ - lib/yasysdui/service_controler.rb
40
+ - lib/yasysdui/service_list.rb
41
+ - lib/yasysdui/system_service.rb
42
+ homepage: https://gitlab.com/d1mertz1/yasysdui
43
+ licenses:
44
+ - MIT
45
+ metadata: {}
46
+ post_install_message:
47
+ rdoc_options: []
48
+ require_paths:
49
+ - lib
50
+ required_ruby_version: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ">="
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ required_rubygems_version: !ruby/object:Gem::Requirement
56
+ requirements:
57
+ - - ">="
58
+ - !ruby/object:Gem::Version
59
+ version: '0'
60
+ requirements: []
61
+ rubyforge_project:
62
+ rubygems_version: 2.7.6
63
+ signing_key:
64
+ specification_version: 4
65
+ summary: Yet another systemd ui
66
+ test_files: []