未验证 提交 4cb8afee 编辑于 作者: Sean Molenaar's avatar Sean Molenaar
浏览文件

service: add timer support for systemd

上级 2c6b979f
......@@ -1005,6 +1005,12 @@ class Formula
opt_prefix/"#{service_name}.service"
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.
def service
return unless service?
......
......@@ -1043,6 +1043,12 @@ class FormulaInstaller
service_path = formula.systemd_service_path
service_path.atomic_write(formula.service.to_systemd_unit)
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
service = if formula.service?
......
......@@ -203,6 +203,8 @@ module Homebrew
@run.map(&:to_s)
end
# Returns the `String` command to run manually instead of the service.
# @return [String]
sig { returns(String) }
def manual_command
instance_eval(&@service_block)
......@@ -213,6 +215,14 @@ module Homebrew
out.join(" ")
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.
# @return [String]
sig { returns(String) }
......@@ -267,5 +277,28 @@ module Homebrew
unit + options.join("\n")
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
......@@ -245,10 +245,11 @@ describe FormulaInstaller do
expect(formula).to receive(:plist).and_return(nil)
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(: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_systemd_unit).and_return("unit")
......@@ -261,6 +262,36 @@ describe FormulaInstaller do
expect(service_path).to exist
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
formula = Testball.new
path = formula.plist_path
......
......@@ -758,6 +758,7 @@ describe Formula do
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.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
......
......@@ -272,6 +272,70 @@ describe Homebrew::Service do
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
it "returns @run data" do
f.class.service do
......
支持 Markdown
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册