class PublishToWeb

Constants

SLD
VERSION

Attributes

bind_host[R]
config[R]
directory_host[R]
forward_port[R]
logger[R]
proxy_host[R]
proxy_port[R]
proxy_user[R]

Public Class Methods

create_logger() click to toggle source
# File lib/publish_to_web.rb, line 21
def self.create_logger
  Logger.new(STDOUT).tap do |logger|
    logger.level = Logger::INFO
    logger.formatter = -> (severity, datetime, progname, msg) do
      color = {
        "WARN"  => :yellow,
        "ERROR" => :red,
        "FATAL" => :red
      }[severity] || :white
      Rainbow("[#{datetime}][#{severity.ljust(5)}] #{msg}\n").color(color)
    end
  end
end
new( forward_port: 80, bind_host: "127.0.0.1", proxy_host: "proxy.protonet.info", proxy_user: "localtunnel", proxy_port: 22666, directory_host: "https://directory.protonet.info", config: Config.new, logger: self.class.create_logger ) click to toggle source
# File lib/publish_to_web.rb, line 38
def initialize(
    forward_port: 80,
    bind_host: "127.0.0.1",
    proxy_host: "proxy.protonet.info",
    proxy_user: "localtunnel",
    proxy_port: 22666,
    directory_host: "https://directory.protonet.info",
    config: Config.new,
    logger: self.class.create_logger
  )

  @forward_port   = forward_port
  @bind_host      = bind_host
  @proxy_host     = proxy_host
  @proxy_user     = proxy_user
  @proxy_port     = proxy_port
  @directory_host = directory_host
  @config         = config
  @logger         = logger
end

Public Instance Methods

check_local_endpoint() click to toggle source
# File lib/publish_to_web.rb, line 59
def check_local_endpoint
  logger.info "Checking if local backend is available at #{bind_host}:#{forward_port}"
  TCPSocket.new(bind_host, forward_port).close
  logger.info "  ✔ Local backend is available!"

rescue Errno::ECONNREFUSED
  logger.warn "Local backend is not available (yet?) - waiting for it to become available"
  sleep 5
  check_local_endpoint
end
prepare_directory(fail_gracefully = true) click to toggle source
# File lib/publish_to_web.rb, line 71
def prepare_directory(fail_gracefully = true)
  config.success = config.error = nil

  if node_name = config.node_name
    if /^#{ Regexp.escape node_name }(#{ SLD })?$/ !~ directory.node_name
      directory.set_node_name node_name
    end
  end
  directory.set_version
  directory.public_key

  logger.info "Updating SMTP configuration"
  directory.smtp_config.tap do |smtp|
    config.smtp_host   = smtp["host"]
    config.smtp_sender = smtp["sender"]
    config.smtp_user   = smtp["user"]
    config.smtp_pass   = smtp["password"]
  end

  logger.info "Updating limits configuration"
  if limits = directory.limits
    config.account_limit = limits["accounts"]
  end

  directory.report_usage

  config.success = 'directory_configured'

rescue PublishToWeb::Directory::HttpResponseError => err
  logger.warn "#{err.class}: #{err}"
  logger.warn "Failed to interact with directory, will try again in a bit"

  # Write out that we have an issue since the directory might refuse
  # our license, our chosen node name might be in conflict and so on
  config.error = "directory_failure.#{err.response.status.to_i}"

  raise unless fail_gracefully
end
start_tunnel(blocking: true) click to toggle source
# File lib/publish_to_web.rb, line 115
def start_tunnel(blocking: true)
  unless blocking
    @thread = Thread.new do
      begin
        start_tunnel blocking: true
        logger.warn "Tunnel closed... :/"
      end while tunnel.running? and sleep(5)
    end
    @thread.abort_on_exception = true
    return
  end

  prepare_directory false
  check_local_endpoint

  logger.info "Starting tunnel to #{proxy_host} as #{directory.node_name}"
  tunnel.start { config.success = "connection_established" }

rescue Net::SSH::AuthenticationFailed => err

  logger.warn "#{err.class}: #{err}"
  logger.warn "Probably the SSH key is not deployed on the proxy server yet, retrying in a bit"

  sleep 30
  retry

rescue PublishToWeb::Directory::HttpResponseError
  # already handled by #prepare_directory, we just need to wait and retry...

  sleep 30
  retry

rescue => error

  logger.error error.message
  logger.error error.backtrace.join("\n")

end
stop_tunnel(*join_args) click to toggle source
# File lib/publish_to_web.rb, line 110
def stop_tunnel(*join_args)
  tunnel.stop
  @thread.join *join_args if @thread
end

Private Instance Methods

directory() click to toggle source
# File lib/publish_to_web.rb, line 156
def directory
  @directory ||= Directory.new host: directory_host, logger: logger, config: config
end
tunnel() click to toggle source
# File lib/publish_to_web.rb, line 160
def tunnel
  @tunnel ||= Tunnel.new proxy_host: proxy_host,
    proxy_user:   proxy_user, 
    proxy_port:   proxy_port,
    identity:     directory.private_key,
    bind_host:    bind_host, 
    remote_port:  directory.remote_port,
    forward_port: forward_port,
    logger:       self.class.create_logger
end