Module: Browserctl::Commands::Daemon

Extended by:
CliOutput
Defined in:
lib/browserctl/commands/daemon.rb

Constant Summary collapse

USAGE =
"Usage: browserctl daemon <ping|status|start|stop|list> [args]"

Constants included from CliOutput

CliOutput::AUTH_REQUIRED_EXIT_CODE

Class Method Summary collapse

Methods included from CliOutput

exit_code_for, print_result, structured_error_line

Class Method Details

.run(client, args) ⇒ Object



15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
# File 'lib/browserctl/commands/daemon.rb', line 15

def self.run(client, args)
  sub = args.shift or abort USAGE
  case sub
  when "ping"
    begin
      print_result(client.ping)
    rescue Browserctl::DaemonUnavailableError => e
      payload = { ok: false, daemon: "offline", error: e.message }
      OutputFormat.current.emit(payload)
      exit 1
    end
  when "status" then run_status(client)
  when "start"  then run_start(args)
  when "stop"   then print_result(client.shutdown)
  when "list"   then run_list
  else abort "unknown daemon subcommand '#{sub}'\n#{USAGE}"
  end
end

.run_listObject



67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
# File 'lib/browserctl/commands/daemon.rb', line 67

def self.run_list
  sockets = Dir[File.join(Browserctl::BROWSERCTL_DIR, "*.sock")]
  rows = sockets.map do |sock_path|
    daemon_name = File.basename(sock_path, ".sock")
    display_name = daemon_name == "browserd" ? "default" : daemon_name
    socket_name = daemon_name == "browserd" ? nil : daemon_name
    client = Browserctl::Client.new(Browserctl.socket_path(socket_name))
    status = client.ping
    next unless status&.dig(:ok)

    { name: display_name, pid: status[:pid], pages: (client.page_list[:pages] || []).length }
  rescue Browserctl::DaemonUnavailableError, RuntimeError
    nil
  end.compact
  OutputFormat.current.emit({ daemons: rows })
end

.run_start(args) ⇒ Object



54
55
56
57
58
59
60
61
62
63
64
65
# File 'lib/browserctl/commands/daemon.rb', line 54

def self.run_start(args)
  opts = Optimist.options(args) do
    opt :headed, "Run with visible browser", default: false
    opt :name,   "Daemon name", type: :string
  end
  flags = []
  flags << "--headed" if opts[:headed]
  flags += ["--name", opts[:name]] if opts[:name]
  pid = Process.spawn("browserd", *flags, out: File::NULL, err: File::NULL)
  Process.detach(pid)
  OutputFormat.current.emit({ ok: true, pid: pid }) { "browserd started (pid #{pid})" }
end

.run_status(client) ⇒ Object



34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
# File 'lib/browserctl/commands/daemon.rb', line 34

def self.run_status(client)
  ping = client.ping
  pages = client.page_list[:pages] || []
  page_info = pages.map do |name|
    url_res = client.url(name)
    { name: name, url: url_res[:url] || url_res[:error] }
  end
  payload = {
    daemon: "online",
    pid: ping[:pid],
    protocol_version: ping[:protocol_version],
    pages: page_info
  }
  OutputFormat.current.emit(payload, JSON.pretty_generate(payload))
rescue Browserctl::DaemonUnavailableError => e
  payload = { daemon: "offline", error: e.message }
  OutputFormat.current.emit(payload, JSON.pretty_generate(payload))
  exit 1
end