Class: Do::Systemd

Inherits:
Object
  • Object
show all
Defined in:
lib/do/systemd.rb

Overview

Wraps systemd user session commands. All calls run through the current user's systemd user manager; do never touches system-wide units.

Defined Under Namespace

Classes: OpenStructish, SystemRaw

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(systemctl_bin: ENV.fetch('SYSTEMCTL', 'systemctl'), journalctl_bin: ENV.fetch('JOURNALCTL', 'journalctl')) ⇒ Systemd

Returns a new instance of Systemd.



78
79
80
81
82
# File 'lib/do/systemd.rb', line 78

def initialize(systemctl_bin: ENV.fetch('SYSTEMCTL', 'systemctl'),
               journalctl_bin: ENV.fetch('JOURNALCTL', 'journalctl'))
  @systemctl_bin = systemctl_bin
  @journalctl_bin = journalctl_bin
end

Instance Attribute Details

#journalctl_binObject (readonly)

Returns the value of attribute journalctl_bin.



76
77
78
# File 'lib/do/systemd.rb', line 76

def journalctl_bin
  @journalctl_bin
end

#systemctl_binObject (readonly)

Returns the value of attribute systemctl_bin.



76
77
78
# File 'lib/do/systemd.rb', line 76

def systemctl_bin
  @systemctl_bin
end

Instance Method Details

#active?(unit) ⇒ Boolean

Returns:

  • (Boolean)


103
104
105
# File 'lib/do/systemd.rb', line 103

def active?(unit)
  run(['is-active', '--no-pager', unit]).success?
end

#active_state(unit) ⇒ Object



154
155
156
# File 'lib/do/systemd.rb', line 154

def active_state(unit)
  show_prop(unit, 'ActiveState')
end

#daemon_reloadObject



123
124
125
# File 'lib/do/systemd.rb', line 123

def daemon_reload
  run(['daemon-reload'])
end

#disable(unit) ⇒ Object



111
112
113
# File 'lib/do/systemd.rb', line 111

def disable(unit)
  run(['disable', '--now', unit])
end

#enable(unit) ⇒ Object



107
108
109
# File 'lib/do/systemd.rb', line 107

def enable(unit)
  run(['enable', '--now', unit])
end

#enabled?(unit) ⇒ Boolean

Returns:

  • (Boolean)


99
100
101
# File 'lib/do/systemd.rb', line 99

def enabled?(unit)
  run(['is-enabled', '--no-pager', unit]).success?
end

#exists?(unit) ⇒ Boolean

Returns:

  • (Boolean)


95
96
97
# File 'lib/do/systemd.rb', line 95

def exists?(unit)
  run(['show', '-p', 'Id', '--no-pager', unit]).success?
end

#last_active(unit) ⇒ Time?

Returns when the service last transitioned to active.

Returns:

  • (Time, nil)

    when the service last transitioned to active.



143
144
145
146
# File 'lib/do/systemd.rb', line 143

def last_active(unit)
  value = show_prop(unit, 'ActiveEnterTimestamp')
  value.nil? || value.empty? ? nil : Time.parse(value).localtime
end

#last_exit_status(unit) ⇒ Integer?

Returns exit status of the last run of a service.

Returns:

  • (Integer, nil)

    exit status of the last run of a service.



149
150
151
152
# File 'lib/do/systemd.rb', line 149

def last_exit_status(unit)
  value = show_prop(unit, 'ExecMainStatus')
  value.nil? || value.empty? ? nil : value.to_i
end

#logs(unit, follow: false, tail: nil) ⇒ Object



166
167
168
169
170
171
# File 'lib/do/systemd.rb', line 166

def logs(unit, follow: false, tail: nil)
  args = ['-u', unit, '--no-pager']
  args << '-f' if follow
  args << "-n #{tail}" if tail
  system(*[@journalctl_bin, '--user', *args].flatten)
end

#next_time(unit) ⇒ Time?

Returns formatted next-elapsed time from a timer unit.

Returns:

  • (Time, nil)

    formatted next-elapsed time from a timer unit.



132
133
134
135
136
137
138
139
140
# File 'lib/do/systemd.rb', line 132

def next_time(unit)
  require 'time'
  value = show_prop(unit, 'NextElapseUSecRealtime')
  return nil if value.nil? || value.empty?

  Time.parse(value).localtime
rescue ArgumentError
  nil
end

#run(args) ⇒ Object

Run a systemctl --user command, returning an Open3 result-like struct exposing #success?, #out, #err, #exitstatus.



175
176
177
178
179
# File 'lib/do/systemd.rb', line 175

def run(args)
  require 'open3'
  @out, @err, @status = Open3.capture3(@systemctl_bin, '--user', *args)
  OpenStructish.new(@status.exitstatus, @out, @err, @status.success?)
end

#show_prop(unit, prop) ⇒ String?

Returns a whitespace-trimmed value for prop.

Returns:

  • (String, nil)

    a whitespace-trimmed value for prop.



159
160
161
162
163
164
# File 'lib/do/systemd.rb', line 159

def show_prop(unit, prop)
  require 'time'
  out = run(['show', '-p', prop, '--no-pager', unit]).out
  m = out.match(/^#{Regexp.escape(prop)}=(.+)$/)
  m ? m[1].strip : nil
end

#start(unit) ⇒ Object



115
116
117
# File 'lib/do/systemd.rb', line 115

def start(unit)
  run(['start', unit])
end

#status(unit, extra: '--no-pager') ⇒ Object



127
128
129
# File 'lib/do/systemd.rb', line 127

def status(unit, extra: '--no-pager')
  run(['status', unit, extra])
end

#stop(unit) ⇒ Object



119
120
121
# File 'lib/do/systemd.rb', line 119

def stop(unit)
  run(['stop', unit])
end

#unit_dirObject



89
90
91
92
93
# File 'lib/do/systemd.rb', line 89

def unit_dir
  dir = ENV.fetch('XDG_CONFIG_HOME', nil)
  dir = File.join(Dir.home, '.config') if dir.nil? || dir.empty?
  File.join(dir, 'systemd', 'user')
end

#user_available?Boolean

Returns:

  • (Boolean)


84
85
86
87
# File 'lib/do/systemd.rb', line 84

def user_available?
  shell_system([@systemctl_bin, '--user', 'is-system-running'],
               out: File::NULL, err: File::NULL)
end