103 lines
2.9 KiB
Ruby
Raw Normal View History

# typed: strict
# frozen_string_literal: true
require_relative "system/systemctl"
module Services
module System
extend FileUtils
# Path to launchctl binary.
sig { returns(T.nilable(Pathname)) }
def self.launchctl
@launchctl ||= T.let(which("launchctl"), T.nilable(Pathname))
end
# Is this a launchctl system
sig { returns(T::Boolean) }
def self.launchctl?
launchctl.present?
end
# Is this a systemd system
sig { returns(T::Boolean) }
def self.systemctl?
Systemctl.executable.present?
end
# Woohoo, we are root dude!
sig { returns(T::Boolean) }
def self.root?
Process.euid.zero?
end
# Current user running `[sudo] brew services`.
sig { returns(T.nilable(String)) }
def self.user
@user ||= T.let(ENV["USER"].presence || Utils.safe_popen_read("/usr/bin/whoami").chomp, T.nilable(String))
end
sig { params(pid: T.nilable(Integer)).returns(T.nilable(String)) }
def self.user_of_process(pid)
if pid.nil? || pid.zero?
user
else
Utils.safe_popen_read("ps", "-o", "user", "-p", pid.to_s).lines.second&.chomp
end
end
# Run at boot.
sig { returns(T.nilable(Pathname)) }
def self.boot_path
if launchctl?
Pathname.new("/Library/LaunchDaemons")
elsif systemctl?
Pathname.new("/usr/lib/systemd/system")
end
end
# Run at login.
sig { returns(T.nilable(Pathname)) }
def self.user_path
if launchctl?
Pathname.new("#{Dir.home}/Library/LaunchAgents")
elsif systemctl?
Pathname.new("#{Dir.home}/.config/systemd/user")
end
end
# If root, return `boot_path`, else return `user_path`.
sig { returns(T.nilable(Pathname)) }
def self.path
root? ? boot_path : user_path
end
sig { returns(String) }
def self.domain_target
if root?
"system"
elsif (ssh_tty = ENV.fetch("HOMEBREW_SSH_TTY", nil).present? && File.stat("/dev/console").uid != Process.uid) ||
(sudo_user = ENV.fetch("HOMEBREW_SUDO_USER", nil).present?) ||
(Process.uid != Process.euid)
if @output_warning.blank? && ENV.fetch("HOMEBREW_SERVICES_NO_DOMAIN_WARNING", nil).blank?
if ssh_tty
opoo "running over SSH without /dev/console ownership, using user/* instead of gui/* domain!"
elsif sudo_user
opoo "running through sudo, using user/* instead of gui/* domain!"
else
opoo "uid and euid do not match, using user/* instead of gui/* domain!"
end
unless Homebrew::EnvConfig.no_env_hints?
puts "Hide this warning by setting HOMEBREW_SERVICES_NO_DOMAIN_WARNING."
puts "Hide these hints with HOMEBREW_NO_ENV_HINTS (see `man brew`)."
end
@output_warning = T.let(true, T.nilable(TrueClass))
end
"user/#{Process.euid}"
else
"gui/#{Process.uid}"
end
end
end
end