rufus-daemon 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 +7 -0
- data/.gitignore +18 -0
- data/Gemfile +12 -0
- data/Gemfile.lock +55 -0
- data/LICENSE.txt +21 -0
- data/README.md +75 -0
- data/Rakefile +18 -0
- data/bin/console +8 -0
- data/bin/setup +5 -0
- data/exe/rufus +122 -0
- data/lib/rufus/daemon.rb +78 -0
- data/rufus-daemon.gemspec +36 -0
- metadata +58 -0
checksums.yaml
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
---
|
|
2
|
+
SHA256:
|
|
3
|
+
metadata.gz: e223784d24bf2446f29d91e3828094d1146d629ccb5cf09fde6056e48a2f5d80
|
|
4
|
+
data.tar.gz: 154fb35fad31697e6e7f3aa4a4efc90cec18c82c6df7d1b77319f3b5a6b8433a
|
|
5
|
+
SHA512:
|
|
6
|
+
metadata.gz: 479f339eeae9f8c460d1cbbc5887bab1031314c745b87d76d8036dd73a244f2e501724f06f377e75e519bbf8adccc405eff728811e8bcc6a9f2a94aed62a9205
|
|
7
|
+
data.tar.gz: f7f153e94c0f41ebac64f686d78585602322415022559116ac91f62045c41cf731d96abde9136159b2d6c489b47bde46945411e39581b0d51ce8554e11d83b34
|
data/.gitignore
ADDED
data/Gemfile
ADDED
data/Gemfile.lock
ADDED
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
PATH
|
|
2
|
+
remote: .
|
|
3
|
+
specs:
|
|
4
|
+
mirrorfile (0.1.0)
|
|
5
|
+
|
|
6
|
+
GEM
|
|
7
|
+
remote: https://rubygems.org/
|
|
8
|
+
specs:
|
|
9
|
+
ast (2.4.3)
|
|
10
|
+
json (2.18.0)
|
|
11
|
+
language_server-protocol (3.17.0.5)
|
|
12
|
+
lint_roller (1.1.0)
|
|
13
|
+
minitest (5.27.0)
|
|
14
|
+
parallel (1.27.0)
|
|
15
|
+
parser (3.3.10.0)
|
|
16
|
+
ast (~> 2.4.1)
|
|
17
|
+
racc
|
|
18
|
+
prism (1.7.0)
|
|
19
|
+
racc (1.8.1)
|
|
20
|
+
rainbow (3.1.1)
|
|
21
|
+
rake (13.3.1)
|
|
22
|
+
regexp_parser (2.11.3)
|
|
23
|
+
rubocop (1.82.1)
|
|
24
|
+
json (~> 2.3)
|
|
25
|
+
language_server-protocol (~> 3.17.0.2)
|
|
26
|
+
lint_roller (~> 1.1.0)
|
|
27
|
+
parallel (~> 1.10)
|
|
28
|
+
parser (>= 3.3.0.2)
|
|
29
|
+
rainbow (>= 2.2.2, < 4.0)
|
|
30
|
+
regexp_parser (>= 2.9.3, < 3.0)
|
|
31
|
+
rubocop-ast (>= 1.48.0, < 2.0)
|
|
32
|
+
ruby-progressbar (~> 1.7)
|
|
33
|
+
unicode-display_width (>= 2.4.0, < 4.0)
|
|
34
|
+
rubocop-ast (1.49.0)
|
|
35
|
+
parser (>= 3.3.7.2)
|
|
36
|
+
prism (~> 1.7)
|
|
37
|
+
ruby-progressbar (1.13.0)
|
|
38
|
+
unicode-display_width (3.2.0)
|
|
39
|
+
unicode-emoji (~> 4.1)
|
|
40
|
+
unicode-emoji (4.2.0)
|
|
41
|
+
yard (0.9.38)
|
|
42
|
+
|
|
43
|
+
PLATFORMS
|
|
44
|
+
ruby
|
|
45
|
+
x86_64-linux
|
|
46
|
+
|
|
47
|
+
DEPENDENCIES
|
|
48
|
+
minitest (~> 5.0)
|
|
49
|
+
mirrorfile!
|
|
50
|
+
rake (~> 13.0)
|
|
51
|
+
rubocop (~> 1.21)
|
|
52
|
+
yard (~> 0.9)
|
|
53
|
+
|
|
54
|
+
BUNDLED WITH
|
|
55
|
+
2.7.2
|
data/LICENSE.txt
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
The MIT License (MIT)
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2024 Your Name
|
|
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
|
|
13
|
+
all 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
|
|
21
|
+
THE SOFTWARE.
|
data/README.md
ADDED
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
# rufus-daemon
|
|
2
|
+
|
|
3
|
+
Run a rufus-scheduler daemon in the background, with access to the instance over DRb unix socket.
|
|
4
|
+
Lovingly built to prevent hanging processes.
|
|
5
|
+
|
|
6
|
+
## Why?
|
|
7
|
+
1. Get status updates on your jobs
|
|
8
|
+
2. Build a job querying service
|
|
9
|
+
3. Allow other processes to dynamically schedule jobs
|
|
10
|
+
4. Organise schedule files in ~/.rufus
|
|
11
|
+
5. ???
|
|
12
|
+
6. Profit
|
|
13
|
+
|
|
14
|
+
## Install
|
|
15
|
+
```ruby
|
|
16
|
+
gem install rufus-daemon
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
## Usage
|
|
20
|
+
|
|
21
|
+
### Running the command line
|
|
22
|
+
```bash
|
|
23
|
+
$ rufus --help
|
|
24
|
+
Usage: rufus [options]
|
|
25
|
+
|
|
26
|
+
Example: rufus --start
|
|
27
|
+
|
|
28
|
+
Options:
|
|
29
|
+
--start
|
|
30
|
+
--restart
|
|
31
|
+
--stop
|
|
32
|
+
--status
|
|
33
|
+
--list
|
|
34
|
+
|
|
35
|
+
Help options:
|
|
36
|
+
--help
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
### Access the rufus instance over DRb socket
|
|
40
|
+
```ruby
|
|
41
|
+
require 'rufus/daemon'
|
|
42
|
+
|
|
43
|
+
Rufus::Daemon.attach.then do |service|
|
|
44
|
+
puts service.rufus # the rufus-scheduler instance
|
|
45
|
+
|
|
46
|
+
# .jobs is a helper that deserializes the jobs before sending
|
|
47
|
+
# over DRb socket. Otherwise you get a marshalling error.
|
|
48
|
+
service.jobs.each do |job|
|
|
49
|
+
puts job
|
|
50
|
+
end
|
|
51
|
+
end
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
###
|
|
55
|
+
The daemon will load both a `~/rufus.rb` file, and all files inside `~/.rufus` with the glob `~/.rufus/**/*.rb`.
|
|
56
|
+
Here's what your files can look like.
|
|
57
|
+
```
|
|
58
|
+
every '10s' do
|
|
59
|
+
# call something
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
cron '0 9 * * *' do
|
|
63
|
+
# call something
|
|
64
|
+
end
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
|
|
68
|
+
|
|
69
|
+
## Contributing
|
|
70
|
+
|
|
71
|
+
Bug reports and pull requests are welcome on GitHub.
|
|
72
|
+
|
|
73
|
+
## License
|
|
74
|
+
|
|
75
|
+
The gem is available as open source under the terms of the [MIT License](LICENSE.txt).
|
data/Rakefile
ADDED
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
#require "bundler/gem_tasks"
|
|
4
|
+
#require "rake/testtask"
|
|
5
|
+
#require "yard"
|
|
6
|
+
#
|
|
7
|
+
#Rake::TestTask.new(:test) do |t|
|
|
8
|
+
# t.libs << "test"
|
|
9
|
+
# t.libs << "lib"
|
|
10
|
+
# t.test_files = FileList["test/**/*_test.rb"]
|
|
11
|
+
#end
|
|
12
|
+
#
|
|
13
|
+
#YARD::Rake::YardocTask.new do |t|
|
|
14
|
+
# t.files = ["lib/**/*.rb"]
|
|
15
|
+
# t.options = ["--markup", "markdown"]
|
|
16
|
+
#end
|
|
17
|
+
#
|
|
18
|
+
#task default: :test
|
data/bin/console
ADDED
data/bin/setup
ADDED
data/exe/rufus
ADDED
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
#!/usr/bin/env ruby
|
|
2
|
+
|
|
3
|
+
require 'optparse'
|
|
4
|
+
require_relative '../lib/rufus/daemon'
|
|
5
|
+
|
|
6
|
+
#def install
|
|
7
|
+
# # install systemd service
|
|
8
|
+
# #
|
|
9
|
+
# File.write 'filename', <<~SERVICE
|
|
10
|
+
# what ever goes in a service file
|
|
11
|
+
# SERVICE
|
|
12
|
+
#end
|
|
13
|
+
|
|
14
|
+
SCHEDULE_FILE = File.expand_path("~/rufus.rb")
|
|
15
|
+
SCHEDULE_DIR = File.expand_path("~/.rufus")
|
|
16
|
+
|
|
17
|
+
# Your schedule file can look like this:
|
|
18
|
+
#
|
|
19
|
+
# every '10s' do
|
|
20
|
+
# puts "hello"
|
|
21
|
+
# end
|
|
22
|
+
#
|
|
23
|
+
# cron '0 9 * * *' do
|
|
24
|
+
# puts "morning"
|
|
25
|
+
# end
|
|
26
|
+
|
|
27
|
+
def start
|
|
28
|
+
Rufus::Daemon.start
|
|
29
|
+
sleep 1
|
|
30
|
+
|
|
31
|
+
if File.exist?(SCHEDULE_FILE)
|
|
32
|
+
Rufus::Daemon.attach.then do |daemon|
|
|
33
|
+
if daemon.jobs.empty?
|
|
34
|
+
daemon.load_schedule(SCHEDULE_FILE)
|
|
35
|
+
end
|
|
36
|
+
end
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
if Dir.exist?(SCHEDULE_DIR)
|
|
40
|
+
Rufus::Daemon.attach.then do |daemon|
|
|
41
|
+
if daemon.jobs.empty?
|
|
42
|
+
Dir.glob("#{SCHEDULE_DIR}/**/*.rb").each do |file|
|
|
43
|
+
daemon.load_schedule(file)
|
|
44
|
+
end
|
|
45
|
+
end
|
|
46
|
+
end
|
|
47
|
+
end
|
|
48
|
+
rescue DRb::DRbConnError
|
|
49
|
+
puts "Failed to connect after start"
|
|
50
|
+
puts "Therefore, couldn't load schedule"
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
def stop
|
|
54
|
+
Rufus::Daemon.stop
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
def restart
|
|
58
|
+
stop
|
|
59
|
+
sleep 1
|
|
60
|
+
start
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
def status
|
|
64
|
+
Rufus::Daemon.attach.rufus.then do |rufus|
|
|
65
|
+
puts "Total jobs: #{rufus.jobs.count}"
|
|
66
|
+
end
|
|
67
|
+
rescue DRb::DRbConnError => e
|
|
68
|
+
puts "Not started"
|
|
69
|
+
puts e
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
def list
|
|
73
|
+
Rufus::Daemon.attach.then do |rufus|
|
|
74
|
+
if rufus.jobs.any?
|
|
75
|
+
rufus.jobs.each do |job|
|
|
76
|
+
puts job
|
|
77
|
+
end
|
|
78
|
+
else
|
|
79
|
+
puts "No jobs"
|
|
80
|
+
end
|
|
81
|
+
end
|
|
82
|
+
rescue DRb::DRbConnError => e
|
|
83
|
+
puts "Not started"
|
|
84
|
+
puts e
|
|
85
|
+
end
|
|
86
|
+
|
|
87
|
+
OptionParser.new.instance_exec do
|
|
88
|
+
banner = 'Usage: rufus [options]'
|
|
89
|
+
|
|
90
|
+
separator ''
|
|
91
|
+
separator 'Example: rufus --start'
|
|
92
|
+
|
|
93
|
+
separator ''
|
|
94
|
+
separator 'Options:'
|
|
95
|
+
|
|
96
|
+
on('--install') { install; exit }
|
|
97
|
+
on('--start') { start; exit }
|
|
98
|
+
on('--restart') { restart; exit }
|
|
99
|
+
on('--stop') { stop; exit }
|
|
100
|
+
on('--status') { status; exit }
|
|
101
|
+
on('--list') { list; exit }
|
|
102
|
+
|
|
103
|
+
separator ''
|
|
104
|
+
separator 'Help options:'
|
|
105
|
+
|
|
106
|
+
on('--help') { puts self; exit }
|
|
107
|
+
|
|
108
|
+
if ARGV.empty?
|
|
109
|
+
puts self
|
|
110
|
+
else
|
|
111
|
+
case ARGV.first.to_sym
|
|
112
|
+
when :start then start
|
|
113
|
+
when :restart then restart
|
|
114
|
+
when :stop then stop
|
|
115
|
+
when :status then status
|
|
116
|
+
when :list then list
|
|
117
|
+
when :help then puts self
|
|
118
|
+
else
|
|
119
|
+
parse!
|
|
120
|
+
end
|
|
121
|
+
end
|
|
122
|
+
end
|
data/lib/rufus/daemon.rb
ADDED
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'drb/drb'
|
|
4
|
+
require 'fileutils'
|
|
5
|
+
require 'rufus-scheduler'
|
|
6
|
+
|
|
7
|
+
module Rufus
|
|
8
|
+
class Daemon
|
|
9
|
+
VERSION = "1.0.0"
|
|
10
|
+
|
|
11
|
+
SOCKET_DIR = "/tmp/drb-sockets"
|
|
12
|
+
SOCKET_FILE = SOCKET_DIR + "/rufus.sock"
|
|
13
|
+
SOCKET_URI = "drbunix://#{SOCKET_FILE}"
|
|
14
|
+
|
|
15
|
+
attr_reader :rufus
|
|
16
|
+
|
|
17
|
+
def initialize
|
|
18
|
+
@rufus = Rufus::Scheduler.new
|
|
19
|
+
@drb = DRb.start_service(SOCKET_URI, self)
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
def uri = @drb.uri
|
|
23
|
+
|
|
24
|
+
def load_schedule(path)
|
|
25
|
+
@rufus.instance_eval(File.read(path))
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
def stop
|
|
29
|
+
@rufus.shutdown
|
|
30
|
+
ensure
|
|
31
|
+
DRb.stop_service
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
def jobs
|
|
35
|
+
@rufus.jobs.map do |job|
|
|
36
|
+
{
|
|
37
|
+
id: job.id,
|
|
38
|
+
scheduled_at: job.scheduled_at.to_s,
|
|
39
|
+
next_time: (job.next_time.to_s if job.respond_to?(:next_time)),
|
|
40
|
+
last_time: (job.last_time.to_s if job.respond_to?(:last_time)),
|
|
41
|
+
tags: job.tags,
|
|
42
|
+
original: job.original
|
|
43
|
+
}.compact
|
|
44
|
+
end
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
def self.attach
|
|
48
|
+
DRbObject.new_with_uri(SOCKET_URI)
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
def self.stop
|
|
52
|
+
attach.stop
|
|
53
|
+
puts "Rufus stopped"
|
|
54
|
+
rescue DRb::DRbConnError
|
|
55
|
+
puts "Already Stopped"
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
def self.start
|
|
59
|
+
FileUtils.mkdir_p(SOCKET_DIR)
|
|
60
|
+
|
|
61
|
+
fork do
|
|
62
|
+
Process.setsid
|
|
63
|
+
|
|
64
|
+
fork do
|
|
65
|
+
daemon = new
|
|
66
|
+
puts "Rufus started - #{daemon.uri}"
|
|
67
|
+
DRb.thread.join
|
|
68
|
+
rescue Errno::EADDRINUSE
|
|
69
|
+
puts "Already started"
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
exit # closes the process after DRb ends
|
|
73
|
+
end
|
|
74
|
+
|
|
75
|
+
Process.wait # no idea what this does
|
|
76
|
+
end
|
|
77
|
+
end
|
|
78
|
+
end
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require_relative "lib/rufus/daemon"
|
|
4
|
+
|
|
5
|
+
Gem::Specification.new do |spec|
|
|
6
|
+
spec.name = "rufus-daemon"
|
|
7
|
+
spec.version = Rufus::Daemon::VERSION
|
|
8
|
+
spec.authors = ["Nathan Kidd"]
|
|
9
|
+
spec.email = ["nathankidd@hey.com"]
|
|
10
|
+
|
|
11
|
+
spec.summary = "Run rufus-scheduler in the background"
|
|
12
|
+
|
|
13
|
+
spec.description = <<~DESC
|
|
14
|
+
Run rufus-scheduler in the background with a DRb unix socket.
|
|
15
|
+
You can save schedule files in the ~/.rufus directory or as ~/rufus.rb
|
|
16
|
+
DESC
|
|
17
|
+
|
|
18
|
+
spec.homepage = "https://github.com/n-at-han-k/rufus-daemon"
|
|
19
|
+
spec.license = "MIT"
|
|
20
|
+
spec.required_ruby_version = ">= 3.2.0"
|
|
21
|
+
|
|
22
|
+
spec.metadata["homepage_uri"] = spec.homepage
|
|
23
|
+
spec.metadata["source_code_uri"] = spec.homepage
|
|
24
|
+
spec.metadata["documentation_uri"] = spec.homepage
|
|
25
|
+
spec.metadata["rubygems_mfa_required"] = "true"
|
|
26
|
+
|
|
27
|
+
spec.files = `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features|data)/}) }
|
|
28
|
+
spec.bindir = "exe"
|
|
29
|
+
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
|
30
|
+
spec.require_paths = ["lib"]
|
|
31
|
+
|
|
32
|
+
#spec.add_development_dependency "minitest", "~> 5.0"
|
|
33
|
+
#spec.add_development_dependency "rake", "~> 13.0"
|
|
34
|
+
#spec.add_development_dependency "rubocop", "~> 1.21"
|
|
35
|
+
#spec.add_development_dependency "yard", "~> 0.9"
|
|
36
|
+
end
|
metadata
ADDED
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
|
2
|
+
name: rufus-daemon
|
|
3
|
+
version: !ruby/object:Gem::Version
|
|
4
|
+
version: 1.0.0
|
|
5
|
+
platform: ruby
|
|
6
|
+
authors:
|
|
7
|
+
- Nathan Kidd
|
|
8
|
+
bindir: exe
|
|
9
|
+
cert_chain: []
|
|
10
|
+
date: 1980-01-02 00:00:00.000000000 Z
|
|
11
|
+
dependencies: []
|
|
12
|
+
description: |
|
|
13
|
+
Run rufus-scheduler in the background with a DRb unix socket.
|
|
14
|
+
You can save schedule files in the ~/.rufus directory or as ~/rufus.rb
|
|
15
|
+
email:
|
|
16
|
+
- nathankidd@hey.com
|
|
17
|
+
executables:
|
|
18
|
+
- rufus
|
|
19
|
+
extensions: []
|
|
20
|
+
extra_rdoc_files: []
|
|
21
|
+
files:
|
|
22
|
+
- ".gitignore"
|
|
23
|
+
- Gemfile
|
|
24
|
+
- Gemfile.lock
|
|
25
|
+
- LICENSE.txt
|
|
26
|
+
- README.md
|
|
27
|
+
- Rakefile
|
|
28
|
+
- bin/console
|
|
29
|
+
- bin/setup
|
|
30
|
+
- exe/rufus
|
|
31
|
+
- lib/rufus/daemon.rb
|
|
32
|
+
- rufus-daemon.gemspec
|
|
33
|
+
homepage: https://github.com/n-at-han-k/rufus-daemon
|
|
34
|
+
licenses:
|
|
35
|
+
- MIT
|
|
36
|
+
metadata:
|
|
37
|
+
homepage_uri: https://github.com/n-at-han-k/rufus-daemon
|
|
38
|
+
source_code_uri: https://github.com/n-at-han-k/rufus-daemon
|
|
39
|
+
documentation_uri: https://github.com/n-at-han-k/rufus-daemon
|
|
40
|
+
rubygems_mfa_required: 'true'
|
|
41
|
+
rdoc_options: []
|
|
42
|
+
require_paths:
|
|
43
|
+
- lib
|
|
44
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
|
45
|
+
requirements:
|
|
46
|
+
- - ">="
|
|
47
|
+
- !ruby/object:Gem::Version
|
|
48
|
+
version: 3.2.0
|
|
49
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
50
|
+
requirements:
|
|
51
|
+
- - ">="
|
|
52
|
+
- !ruby/object:Gem::Version
|
|
53
|
+
version: '0'
|
|
54
|
+
requirements: []
|
|
55
|
+
rubygems_version: 3.6.7
|
|
56
|
+
specification_version: 4
|
|
57
|
+
summary: Run rufus-scheduler in the background
|
|
58
|
+
test_files: []
|