Class: Machinery::Html

Inherits:
Object show all
Defined in:
lib/html.rb

Overview

Copyright © 2013-2016 SUSE LLC

This program is free software; you can redistribute it and/or modify it under the terms of version 3 of the GNU General Public License as published by the Free Software Foundation.

This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.

You should have received a copy of the GNU General Public License along with this program; if not, contact SUSE LLC.

To contact SUSE about this file by physical or electronic mail, you may find current contact information at www.suse.com

Class Method Summary collapse

Class Method Details

.remove_output_redirectionObject



106
107
108
109
# File 'lib/html.rb', line 106

def self.remove_output_redirection
  STDOUT.reopen @orig_stdout
  STDERR.reopen @orig_stderr
end

.run_server(system_description_store, opts, &block) ⇒ Object

Creates a new thread running a sinatra webserver which serves the local system descriptions The Thread object is returned so that the caller can ‘.join` it until it’s finished.



21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
# File 'lib/html.rb', line 21

def self.run_server(system_description_store, opts, &block)
  if opts[:public] && opts[:ip]
    raise RuntimeError.new("It's only possible to use either an IP address or the 'public' " \
      "flag bot not both.")
  end

  Thread.new do
    if opts[:public]
      opts[:ip] = "0.0.0.0"

      Machinery::Ui.warn <<-EOF.chomp
Warning:
The --public option makes the HTTP server listen on all configured IP addresses. Everyone who has access to one of those IP addresses can access all of your system descriptions stored in '~/.machinery'. Be careful if there is sensitive information (such as private keys) stored in one of your descriptions.
EOF
    elsif opts[:ip] == "0.0.0.0"
      Machinery::Ui.warn <<-EOF.chomp
Warning:
The server is listening on all configured IP addresses. Everyone who has access to one of those IP addresses can access all of your system descriptions stored in '~/.machinery'. Be careful if there is sensitive information (such as private keys) stored in one of your descriptions.
EOF
    elsif opts[:ip] && opts[:ip] != "localhost" && opts[:ip] != "127.0.0.1"
      Machinery::Ui.warn <<-EOF.chomp
Warning:
You specified an IP address other than '127.0.0.1', your server may be reachable from the network. Everyone who can access that network can access your system descriptions stored in '~/.machinery'. Be careful if there is sensitive information (such as private keys) stored in one of your descriptions.
EOF
    elsif !opts[:ip]
      opts[:ip] = "127.0.0.1"
    end

    Server.set :system_description_store, system_description_store
    Server.set :port, opts[:port] || Machinery::Config.new.http_server_port
    Server.set :bind, opts[:ip]
    Server.set :public_folder, File.join(Machinery::ROOT, "html")
    Server.set :static_cache_control, "no-cache"

    begin
      setup_output_redirection
      begin
        Server.run! do
          Thread.new { block.call }
        end
      rescue SocketError => e
        servefailed_error = <<-EOF.chomp
Cannot start server on #{opts[:ip]}:#{Server.settings.port}.
ERROR: #{e.message}
EOF
        raise Machinery::Errors::ServeFailed, servefailed_error
      rescue Errno::EADDRNOTAVAIL
        servefailed_error = <<-EOF.chomp
The IP-Address #{opts[:ip]} is not available. Please choose a different IP-Address.
EOF
        raise Machinery::Errors::ServeFailed, servefailed_error
      rescue Errno::EACCES => e
        servefailed_error = <<-EOF.chomp
You are not allowed to start the server on port #{Server.settings.port}. You need root privileges for ports between 2 and 1023!
ERROR: #{e.message}
EOF
        raise Machinery::Errors::ServeFailed, servefailed_error
      rescue Errno::EADDRINUSE, RuntimeError => e
        # If eventmachine is installed it will be used for handling the server. And eventmachine
        # raises RuntimeError instead of Errno::EADDRINUSE, so we have to handle these as well
        raise(e) if e.is_a?(RuntimeError) && !(e.to_s.index("port is in use"))

        servefailed_error = <<-EOF.chomp
Port #{Server.settings.port} is already in use.
You have to stop the already running server on port #{Server.settings.port} first or if you're serving a description with the `serve` command, you can also use the `--port` option.
        EOF
        raise Machinery::Errors::ServeFailed, servefailed_error
      end
      remove_output_redirection
    rescue => e
      remove_output_redirection
      # Re-raise exception in main thread
      Thread.main.raise e
    end
  end
end

.setup_output_redirectionObject



98
99
100
101
102
103
104
# File 'lib/html.rb', line 98

def self.setup_output_redirection
  @orig_stdout = STDOUT.clone
  @orig_stderr = STDERR.clone
  server_log = File.join(Machinery::DEFAULT_CONFIG_DIR, "webserver.log")
  STDOUT.reopen server_log, "w"
  STDERR.reopen server_log, "w"
end