117 lines
2.7 KiB
Ruby
117 lines
2.7 KiB
Ruby
module L4dServer
|
|
class SystemdManager
|
|
SYSTEMD_USER_DIR = File.expand_path("~/.config/systemd/user").freeze
|
|
|
|
def self.start(server)
|
|
new(server).start
|
|
end
|
|
|
|
def self.stop(server)
|
|
new(server).stop
|
|
end
|
|
|
|
def self.restart(server)
|
|
new(server).restart
|
|
end
|
|
|
|
def self.status(server)
|
|
new(server).status
|
|
end
|
|
|
|
def self.cleanup(server)
|
|
new(server).cleanup
|
|
end
|
|
|
|
def initialize(server)
|
|
@server = server
|
|
end
|
|
|
|
def start
|
|
execute("systemctl --user start #{unit_name}")
|
|
end
|
|
|
|
def stop
|
|
execute("systemctl --user stop #{unit_name}")
|
|
end
|
|
|
|
def restart
|
|
execute("systemctl --user restart #{unit_name}")
|
|
end
|
|
|
|
def status
|
|
output = `systemctl --user is-active #{unit_name} 2>&1`
|
|
output.strip
|
|
rescue StandardError => e
|
|
Rails.logger.error("Failed to get status: #{e.message}")
|
|
"unknown"
|
|
end
|
|
|
|
def cleanup
|
|
begin
|
|
stop
|
|
execute("systemctl --user disable #{unit_name}")
|
|
execute("systemctl --user daemon-reload")
|
|
File.delete(unit_file_path) if File.exist?(unit_file_path)
|
|
rescue StandardError => e
|
|
Rails.logger.error("Failed to cleanup systemd unit: #{e.message}")
|
|
end
|
|
end
|
|
|
|
def create_unit_file
|
|
FileUtils.mkdir_p(SYSTEMD_USER_DIR) unless Dir.exist?(SYSTEMD_USER_DIR)
|
|
File.write(unit_file_path, render_unit)
|
|
@server.update(unit_file_path: unit_file_path)
|
|
execute("systemctl --user daemon-reload")
|
|
end
|
|
|
|
def enable_and_start
|
|
execute("systemctl --user enable #{unit_name}")
|
|
start
|
|
end
|
|
|
|
private
|
|
|
|
def unit_name
|
|
"left4dead2-#{@server.id}.service"
|
|
end
|
|
|
|
def unit_file_path
|
|
File.join(SYSTEMD_USER_DIR, unit_name)
|
|
end
|
|
|
|
def render_unit
|
|
template = @server.server_template
|
|
|
|
# startup_params is now a text field, not an association
|
|
startup_args = template.startup_params.to_s.strip
|
|
|
|
<<~UNIT
|
|
[Unit]
|
|
Description=L4D2 Server #{@server.name}
|
|
After=network-online.target
|
|
Wants=network-online.target
|
|
|
|
[Service]
|
|
Type=simple
|
|
User=steam
|
|
ExecStart=#{L4dServer::Config.bin_path}/start-server #{@server.id}
|
|
ExecStop=#{L4dServer::Config.bin_path}/stop-server #{@server.id}
|
|
Restart=on-failure
|
|
RestartSec=10
|
|
Nice=-10
|
|
|
|
[Install]
|
|
WantedBy=default.target
|
|
UNIT
|
|
end
|
|
|
|
def execute(command)
|
|
output = `#{command} 2>&1`
|
|
raise "Command failed: #{command}\n#{output}" unless $?.success?
|
|
output
|
|
rescue StandardError => e
|
|
Rails.logger.error("Systemd command failed: #{e.message}")
|
|
raise
|
|
end
|
|
end
|
|
end
|