Merge pull request #12460 from SMillerDev/feature/service/interval_systemd
service: add timer support for systemd
This commit is contained in:
commit
e482a9f03d
@ -1005,6 +1005,12 @@ class Formula
|
|||||||
opt_prefix/"#{service_name}.service"
|
opt_prefix/"#{service_name}.service"
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# The generated systemd {.timer} file path.
|
||||||
|
sig { returns(Pathname) }
|
||||||
|
def systemd_timer_path
|
||||||
|
opt_prefix/"#{service_name}.timer"
|
||||||
|
end
|
||||||
|
|
||||||
# The service specification of the software.
|
# The service specification of the software.
|
||||||
def service
|
def service
|
||||||
return unless service?
|
return unless service?
|
||||||
|
@ -1043,6 +1043,12 @@ class FormulaInstaller
|
|||||||
service_path = formula.systemd_service_path
|
service_path = formula.systemd_service_path
|
||||||
service_path.atomic_write(formula.service.to_systemd_unit)
|
service_path.atomic_write(formula.service.to_systemd_unit)
|
||||||
service_path.chmod 0644
|
service_path.chmod 0644
|
||||||
|
|
||||||
|
if formula.service.timed?
|
||||||
|
timer_path = formula.systemd_timer_path
|
||||||
|
timer_path.atomic_write(formula.service.to_systemd_timer)
|
||||||
|
timer_path.chmod 0644
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
service = if formula.service?
|
service = if formula.service?
|
||||||
|
@ -203,6 +203,8 @@ module Homebrew
|
|||||||
@run.map(&:to_s)
|
@run.map(&:to_s)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# Returns the `String` command to run manually instead of the service.
|
||||||
|
# @return [String]
|
||||||
sig { returns(String) }
|
sig { returns(String) }
|
||||||
def manual_command
|
def manual_command
|
||||||
instance_eval(&@service_block)
|
instance_eval(&@service_block)
|
||||||
@ -213,6 +215,14 @@ module Homebrew
|
|||||||
out.join(" ")
|
out.join(" ")
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# Returns a `Boolean` describing if a service is timed.
|
||||||
|
# @return [Boolean]
|
||||||
|
sig { returns(T::Boolean) }
|
||||||
|
def timed?
|
||||||
|
instance_eval(&@service_block)
|
||||||
|
@run_type == RUN_TYPE_CRON || @run_type == RUN_TYPE_INTERVAL
|
||||||
|
end
|
||||||
|
|
||||||
# Returns a `String` plist.
|
# Returns a `String` plist.
|
||||||
# @return [String]
|
# @return [String]
|
||||||
sig { returns(String) }
|
sig { returns(String) }
|
||||||
@ -267,5 +277,28 @@ module Homebrew
|
|||||||
|
|
||||||
unit + options.join("\n")
|
unit + options.join("\n")
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# Returns a `String` systemd unit timer.
|
||||||
|
# @return [String]
|
||||||
|
sig { returns(String) }
|
||||||
|
def to_systemd_timer
|
||||||
|
timer = <<~EOS
|
||||||
|
[Unit]
|
||||||
|
Description=Homebrew generated timer for #{@formula.name}
|
||||||
|
|
||||||
|
[Install]
|
||||||
|
WantedBy=timers.target
|
||||||
|
|
||||||
|
[Timer]
|
||||||
|
Unit=#{@formula.service_name}
|
||||||
|
EOS
|
||||||
|
|
||||||
|
instance_eval(&@service_block)
|
||||||
|
options = []
|
||||||
|
options << "Persistent=true=" if @run_type == RUN_TYPE_CRON
|
||||||
|
options << "OnUnitActiveSec=#{@interval}" if @run_type == RUN_TYPE_INTERVAL
|
||||||
|
|
||||||
|
timer + options.join("\n")
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -245,10 +245,11 @@ describe FormulaInstaller do
|
|||||||
|
|
||||||
expect(formula).to receive(:plist).and_return(nil)
|
expect(formula).to receive(:plist).and_return(nil)
|
||||||
expect(formula).to receive(:service?).exactly(3).and_return(true)
|
expect(formula).to receive(:service?).exactly(3).and_return(true)
|
||||||
expect(formula).to receive(:service).twice.and_return(service)
|
expect(formula).to receive(:service).exactly(3).and_return(service)
|
||||||
expect(formula).to receive(:plist_path).and_call_original
|
expect(formula).to receive(:plist_path).and_call_original
|
||||||
expect(formula).to receive(:systemd_service_path).and_call_original
|
expect(formula).to receive(:systemd_service_path).and_call_original
|
||||||
|
|
||||||
|
expect(service).to receive(:timed?).and_return(false)
|
||||||
expect(service).to receive(:to_plist).and_return("plist")
|
expect(service).to receive(:to_plist).and_return("plist")
|
||||||
expect(service).to receive(:to_systemd_unit).and_return("unit")
|
expect(service).to receive(:to_systemd_unit).and_return("unit")
|
||||||
|
|
||||||
@ -261,6 +262,36 @@ describe FormulaInstaller do
|
|||||||
expect(service_path).to exist
|
expect(service_path).to exist
|
||||||
end
|
end
|
||||||
|
|
||||||
|
it "works if timed service is set" do
|
||||||
|
formula = Testball.new
|
||||||
|
plist_path = formula.plist_path
|
||||||
|
service_path = formula.systemd_service_path
|
||||||
|
timer_path = formula.systemd_timer_path
|
||||||
|
service = Homebrew::Service.new(formula)
|
||||||
|
formula.opt_prefix.mkpath
|
||||||
|
|
||||||
|
expect(formula).to receive(:plist).and_return(nil)
|
||||||
|
expect(formula).to receive(:service?).exactly(3).and_return(true)
|
||||||
|
expect(formula).to receive(:service).exactly(4).and_return(service)
|
||||||
|
expect(formula).to receive(:plist_path).and_call_original
|
||||||
|
expect(formula).to receive(:systemd_service_path).and_call_original
|
||||||
|
expect(formula).to receive(:systemd_timer_path).and_call_original
|
||||||
|
|
||||||
|
expect(service).to receive(:to_plist).and_return("plist")
|
||||||
|
expect(service).to receive(:timed?).and_return(true)
|
||||||
|
expect(service).to receive(:to_systemd_unit).and_return("unit")
|
||||||
|
expect(service).to receive(:to_systemd_timer).and_return("timer")
|
||||||
|
|
||||||
|
installer = described_class.new(formula)
|
||||||
|
expect {
|
||||||
|
installer.install_service
|
||||||
|
}.not_to output(/Error: Failed to install service files/).to_stderr
|
||||||
|
|
||||||
|
expect(plist_path).to exist
|
||||||
|
expect(service_path).to exist
|
||||||
|
expect(timer_path).to exist
|
||||||
|
end
|
||||||
|
|
||||||
it "returns without definition" do
|
it "returns without definition" do
|
||||||
formula = Testball.new
|
formula = Testball.new
|
||||||
path = formula.plist_path
|
path = formula.plist_path
|
||||||
|
@ -758,6 +758,7 @@ describe Formula do
|
|||||||
expect(f.service_name).to eq("homebrew.formula_name")
|
expect(f.service_name).to eq("homebrew.formula_name")
|
||||||
expect(f.plist_path).to eq(HOMEBREW_PREFIX/"opt/formula_name/homebrew.mxcl.formula_name.plist")
|
expect(f.plist_path).to eq(HOMEBREW_PREFIX/"opt/formula_name/homebrew.mxcl.formula_name.plist")
|
||||||
expect(f.systemd_service_path).to eq(HOMEBREW_PREFIX/"opt/formula_name/homebrew.formula_name.service")
|
expect(f.systemd_service_path).to eq(HOMEBREW_PREFIX/"opt/formula_name/homebrew.formula_name.service")
|
||||||
|
expect(f.systemd_timer_path).to eq(HOMEBREW_PREFIX/"opt/formula_name/homebrew.formula_name.timer")
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -272,6 +272,70 @@ describe Homebrew::Service do
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
describe "#to_systemd_timer" do
|
||||||
|
it "returns valid timer" do
|
||||||
|
f.class.service do
|
||||||
|
run [opt_bin/"beanstalkd", "test"]
|
||||||
|
run_type :interval
|
||||||
|
interval 5
|
||||||
|
end
|
||||||
|
|
||||||
|
unit = f.service.to_systemd_timer
|
||||||
|
unit_expect = <<~EOS
|
||||||
|
[Unit]
|
||||||
|
Description=Homebrew generated timer for formula_name
|
||||||
|
|
||||||
|
[Install]
|
||||||
|
WantedBy=timers.target
|
||||||
|
|
||||||
|
[Timer]
|
||||||
|
Unit=homebrew.formula_name
|
||||||
|
OnUnitActiveSec=5
|
||||||
|
EOS
|
||||||
|
expect(unit).to eq(unit_expect.strip)
|
||||||
|
end
|
||||||
|
|
||||||
|
it "returns valid partial timer" do
|
||||||
|
f.class.service do
|
||||||
|
run opt_bin/"beanstalkd"
|
||||||
|
run_type :immediate
|
||||||
|
end
|
||||||
|
|
||||||
|
unit = f.service.to_systemd_timer
|
||||||
|
unit_expect = <<~EOS
|
||||||
|
[Unit]
|
||||||
|
Description=Homebrew generated timer for formula_name
|
||||||
|
|
||||||
|
[Install]
|
||||||
|
WantedBy=timers.target
|
||||||
|
|
||||||
|
[Timer]
|
||||||
|
Unit=homebrew.formula_name
|
||||||
|
EOS
|
||||||
|
expect(unit).to eq(unit_expect)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
describe "#timed?" do
|
||||||
|
it "returns false for immediate" do
|
||||||
|
f.class.service do
|
||||||
|
run [opt_bin/"beanstalkd", "test"]
|
||||||
|
run_type :immediate
|
||||||
|
end
|
||||||
|
|
||||||
|
expect(f.service.timed?).to eq(false)
|
||||||
|
end
|
||||||
|
|
||||||
|
it "returns true for interval" do
|
||||||
|
f.class.service do
|
||||||
|
run [opt_bin/"beanstalkd", "test"]
|
||||||
|
run_type :interval
|
||||||
|
end
|
||||||
|
|
||||||
|
expect(f.service.timed?).to eq(true)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
describe "#command" do
|
describe "#command" do
|
||||||
it "returns @run data" do
|
it "returns @run data" do
|
||||||
f.class.service do
|
f.class.service do
|
||||||
|
Loading…
x
Reference in New Issue
Block a user