From dbb23739b0173bf36222b8c3460a25e69ae8383d Mon Sep 17 00:00:00 2001 From: NickHackman Date: Fri, 4 Feb 2022 11:37:29 -0600 Subject: [PATCH 1/4] service(MacOS): launch only once --- Library/Homebrew/service.rb | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/Library/Homebrew/service.rb b/Library/Homebrew/service.rb index 205ac4085c039..1fba85547d8a6 100644 --- a/Library/Homebrew/service.rb +++ b/Library/Homebrew/service.rb @@ -112,6 +112,18 @@ def keep_alive(value = nil) end end + sig { params(value: T.nilable(T::Boolean)).returns(T.nilable(T::Boolean)) } + def launch_only_once(value = nil) + case T.unsafe(value) + when nil + @launch_only_once + when true, false + @launch_only_once = value + else + raise TypeError, "Service#launch_only_once expects a Boolean" + end + end + sig { params(value: T.nilable(Integer)).returns(T.nilable(Integer)) } def restart_delay(value = nil) case T.unsafe(value) @@ -291,6 +303,7 @@ def to_plist } base[:KeepAlive] = @keep_alive if @keep_alive == true + base[:LaunchOnlyOnce] = @launch_only_once if @launch_only_once == false base[:LegacyTimers] = @macos_legacy_timers if @macos_legacy_timers == true base[:TimeOut] = @restart_delay if @restart_delay.present? base[:ProcessType] = @process_type.to_s.capitalize if @process_type.present? From 9f4949c8c610ade26130e56292ac8a42940c1494 Mon Sep 17 00:00:00 2001 From: NickHackman Date: Fri, 4 Feb 2022 11:42:25 -0600 Subject: [PATCH 2/4] service: LaunchOnlyOnce plist test --- Library/Homebrew/service.rb | 2 +- Library/Homebrew/test/service_spec.rb | 3 +++ 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/Library/Homebrew/service.rb b/Library/Homebrew/service.rb index 1fba85547d8a6..5b4245cde5821 100644 --- a/Library/Homebrew/service.rb +++ b/Library/Homebrew/service.rb @@ -303,7 +303,7 @@ def to_plist } base[:KeepAlive] = @keep_alive if @keep_alive == true - base[:LaunchOnlyOnce] = @launch_only_once if @launch_only_once == false + base[:LaunchOnlyOnce] = @launch_only_once if @launch_only_once == true base[:LegacyTimers] = @macos_legacy_timers if @macos_legacy_timers == true base[:TimeOut] = @restart_delay if @restart_delay.present? base[:ProcessType] = @process_type.to_s.capitalize if @process_type.present? diff --git a/Library/Homebrew/test/service_spec.rb b/Library/Homebrew/test/service_spec.rb index da1c8ec20d40c..b1d10b74a2d74 100644 --- a/Library/Homebrew/test/service_spec.rb +++ b/Library/Homebrew/test/service_spec.rb @@ -102,6 +102,7 @@ root_dir var working_dir var keep_alive true + launch_only_once true process_type :interactive restart_delay 30 interval 5 @@ -127,6 +128,8 @@ \t \tLabel \thomebrew.mxcl.formula_name + \tLaunchOnlyOnce + \t \tLegacyTimers \t \tProcessType From 12bf07a6ba03c358a8f087ecbcb0a5c090e8d711 Mon Sep 17 00:00:00 2001 From: NickHackman Date: Fri, 11 Feb 2022 13:59:24 -0600 Subject: [PATCH 3/4] service: systemd launch_only_once Set the type of service to oneshot if launch_only_once is provided; otherwise, simple. --- Library/Homebrew/service.rb | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/Library/Homebrew/service.rb b/Library/Homebrew/service.rb index 5b4245cde5821..2a870048edc5d 100644 --- a/Library/Homebrew/service.rb +++ b/Library/Homebrew/service.rb @@ -334,11 +334,14 @@ def to_systemd_unit WantedBy=multi-user.target [Service] - Type=simple - ExecStart=#{command.join(" ")} EOS + # command needs to be first because it initializes all other values + cmd = command.join(" ") + options = [] + options << "Type=#{@launch_only_once == true ? "oneshot" : "simple"}" + options << "ExecStart=#{cmd}" options << "Restart=always" if @keep_alive == true options << "RestartSec=#{restart_delay}" if @restart_delay.present? options << "WorkingDirectory=#{@working_dir}" if @working_dir.present? From 53d37cc84cbb9dfa5315ce96542637595fe4ab01 Mon Sep 17 00:00:00 2001 From: NickHackman Date: Fri, 11 Feb 2022 14:48:05 -0600 Subject: [PATCH 4/4] service(systemd): launch_only_once test --- Library/Homebrew/test/service_spec.rb | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/Library/Homebrew/test/service_spec.rb b/Library/Homebrew/test/service_spec.rb index b1d10b74a2d74..72e587f07fd72 100644 --- a/Library/Homebrew/test/service_spec.rb +++ b/Library/Homebrew/test/service_spec.rb @@ -291,10 +291,11 @@ expect(unit).to eq(unit_expect.strip) end - it "returns valid partial unit" do + it "returns valid partial oneshot unit" do f.class.service do run opt_bin/"beanstalkd" run_type :immediate + launch_only_once true end unit = f.service.to_systemd_unit @@ -306,10 +307,10 @@ WantedBy=multi-user.target [Service] - Type=simple + Type=oneshot ExecStart=#{HOMEBREW_PREFIX}/opt/#{name}/bin/beanstalkd EOS - expect(unit).to eq(unit_expect) + expect(unit).to eq(unit_expect.strip) end end