mirror of
https://github.com/l5yth/potato-mesh.git
synced 2026-03-28 17:42:48 +01:00
197 lines
5.9 KiB
Ruby
197 lines
5.9 KiB
Ruby
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
# you may not use this file except in compliance with the License.
|
|
# You may obtain a copy of the License at
|
|
#
|
|
# http://www.apache.org/licenses/LICENSE-2.0
|
|
#
|
|
# Unless required by applicable law or agreed to in writing, software
|
|
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
# See the License for the specific language governing permissions and
|
|
# limitations under the License.
|
|
|
|
# frozen_string_literal: true
|
|
|
|
require "sinatra/base"
|
|
require "json"
|
|
require "sqlite3"
|
|
require "fileutils"
|
|
require "logger"
|
|
require "rack/utils"
|
|
require "open3"
|
|
require "resolv"
|
|
require "socket"
|
|
require "time"
|
|
require "openssl"
|
|
require "base64"
|
|
require "prometheus/client"
|
|
require "prometheus/client/formats/text"
|
|
require "prometheus/middleware/collector"
|
|
require "prometheus/middleware/exporter"
|
|
require "net/http"
|
|
require "uri"
|
|
require "ipaddr"
|
|
require "set"
|
|
require "digest"
|
|
|
|
require_relative "config"
|
|
require_relative "sanitizer"
|
|
require_relative "meta"
|
|
require_relative "logging"
|
|
require_relative "application/helpers"
|
|
require_relative "application/errors"
|
|
require_relative "application/database"
|
|
require_relative "application/networking"
|
|
require_relative "application/identity"
|
|
require_relative "application/federation"
|
|
require_relative "application/prometheus"
|
|
require_relative "application/queries"
|
|
require_relative "application/data_processing"
|
|
require_relative "application/filesystem"
|
|
require_relative "application/instances"
|
|
require_relative "application/routes/api"
|
|
require_relative "application/routes/ingest"
|
|
require_relative "application/routes/root"
|
|
|
|
module PotatoMesh
|
|
class Application < Sinatra::Base
|
|
extend App::Helpers
|
|
extend App::Database
|
|
extend App::Networking
|
|
extend App::Identity
|
|
extend App::Federation
|
|
extend App::Instances
|
|
extend App::Prometheus
|
|
extend App::Queries
|
|
extend App::DataProcessing
|
|
extend App::Filesystem
|
|
|
|
helpers App::Helpers
|
|
include App::Database
|
|
include App::Networking
|
|
include App::Identity
|
|
include App::Federation
|
|
include App::Instances
|
|
include App::Prometheus
|
|
include App::Queries
|
|
include App::DataProcessing
|
|
include App::Filesystem
|
|
|
|
register App::Routes::Api
|
|
register App::Routes::Ingest
|
|
register App::Routes::Root
|
|
|
|
DEFAULT_PORT = 41_447
|
|
DEFAULT_BIND_ADDRESS = "0.0.0.0"
|
|
|
|
APP_VERSION = determine_app_version
|
|
INSTANCE_PRIVATE_KEY, INSTANCE_KEY_GENERATED = load_or_generate_instance_private_key
|
|
INSTANCE_PUBLIC_KEY_PEM = INSTANCE_PRIVATE_KEY.public_key.export
|
|
SELF_INSTANCE_ID = Digest::SHA256.hexdigest(INSTANCE_PUBLIC_KEY_PEM)
|
|
INSTANCE_DOMAIN, INSTANCE_DOMAIN_SOURCE = determine_instance_domain
|
|
|
|
# Adjust the runtime logger severity to match the DEBUG flag.
|
|
#
|
|
# @return [void]
|
|
def self.apply_logger_level!
|
|
logger = settings.logger
|
|
return unless logger
|
|
|
|
logger.level = PotatoMesh::Config.debug? ? Logger::DEBUG : Logger::WARN
|
|
end
|
|
|
|
# Determine the port the application should listen on by honouring the
|
|
# conventional +PORT+ environment variable used by hosting platforms. Any
|
|
# non-numeric or out-of-range values fall back to the provided default to
|
|
# keep the application bootable in misconfigured environments.
|
|
#
|
|
# @param default_port [Integer] fallback port when +ENV['PORT']+ is absent or invalid.
|
|
# @return [Integer] port number for the HTTP server.
|
|
def self.resolve_port(default_port: DEFAULT_PORT)
|
|
raw_port = ENV["PORT"]
|
|
return default_port if raw_port.nil?
|
|
|
|
trimmed = raw_port.to_s.strip
|
|
return default_port if trimmed.empty?
|
|
|
|
begin
|
|
port = Integer(trimmed, 10)
|
|
rescue ArgumentError
|
|
return default_port
|
|
end
|
|
|
|
return default_port unless port.positive?
|
|
return default_port unless PotatoMesh::Sanitizer.valid_port?(trimmed)
|
|
|
|
port
|
|
end
|
|
|
|
configure do
|
|
set :public_folder, File.expand_path("../../public", __dir__)
|
|
set :views, File.expand_path("../../views", __dir__)
|
|
set :federation_thread, nil
|
|
set :port, resolve_port
|
|
set :bind, DEFAULT_BIND_ADDRESS
|
|
|
|
app_logger = PotatoMesh::Logging.build_logger($stdout)
|
|
set :logger, app_logger
|
|
use Rack::CommonLogger, app_logger
|
|
use Rack::Deflater
|
|
use ::Prometheus::Middleware::Collector
|
|
use ::Prometheus::Middleware::Exporter
|
|
|
|
apply_logger_level!
|
|
|
|
perform_initial_filesystem_setup!
|
|
cleanup_legacy_well_known_artifacts
|
|
init_db unless db_schema_present?
|
|
ensure_schema_upgrades
|
|
|
|
log_instance_domain_resolution
|
|
log_instance_public_key
|
|
refresh_well_known_document_if_stale
|
|
ensure_self_instance_record!
|
|
update_all_prometheus_metrics_from_nodes
|
|
|
|
if federation_announcements_active?
|
|
start_initial_federation_announcement!
|
|
start_federation_announcer!
|
|
elsif federation_enabled?
|
|
debug_log(
|
|
"Federation announcements disabled",
|
|
context: "federation",
|
|
reason: "test environment",
|
|
)
|
|
else
|
|
debug_log(
|
|
"Federation announcements disabled",
|
|
context: "federation",
|
|
reason: "configuration",
|
|
)
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
if defined?(Sinatra::Application) && Sinatra::Application != PotatoMesh::Application
|
|
Sinatra.send(:remove_const, :Application)
|
|
end
|
|
Sinatra::Application = PotatoMesh::Application unless defined?(Sinatra::Application)
|
|
|
|
APP_VERSION = PotatoMesh::Application::APP_VERSION unless defined?(APP_VERSION)
|
|
SELF_INSTANCE_ID = PotatoMesh::Application::SELF_INSTANCE_ID unless defined?(SELF_INSTANCE_ID)
|
|
|
|
[
|
|
PotatoMesh::App::Helpers,
|
|
PotatoMesh::App::Database,
|
|
PotatoMesh::App::Networking,
|
|
PotatoMesh::App::Identity,
|
|
PotatoMesh::App::Federation,
|
|
PotatoMesh::App::Instances,
|
|
PotatoMesh::App::Prometheus,
|
|
PotatoMesh::App::Queries,
|
|
PotatoMesh::App::DataProcessing,
|
|
].each do |mod|
|
|
Object.include(mod) unless Object < mod
|
|
end
|