8c7a382027
instead of aliasing This seems to be the convention for functions that can be reused between different mix tasks in all Elixir projects I've seen and it gets rid on an error message when someone runs mix pleroma.common Also in this commit by accident: - Move benchmark task under a proper namespace - Insert a space after the prompt
222 lines
6.7 KiB
Elixir
222 lines
6.7 KiB
Elixir
# Pleroma: A lightweight social networking server
|
|
# Copyright © 2017-2018 Pleroma Authors <https://pleroma.social/>
|
|
# SPDX-License-Identifier: AGPL-3.0-only
|
|
|
|
defmodule Mix.Tasks.Pleroma.Instance do
|
|
use Mix.Task
|
|
import Mix.Pleroma
|
|
|
|
@shortdoc "Manages Pleroma instance"
|
|
@moduledoc """
|
|
Manages Pleroma instance.
|
|
|
|
## Generate a new instance config.
|
|
|
|
mix pleroma.instance gen [OPTION...]
|
|
|
|
If any options are left unspecified, you will be prompted interactively
|
|
|
|
## Options
|
|
|
|
- `-f`, `--force` - overwrite any output files
|
|
- `-o PATH`, `--output PATH` - the output file for the generated configuration
|
|
- `--output-psql PATH` - the output file for the generated PostgreSQL setup
|
|
- `--domain DOMAIN` - the domain of your instance
|
|
- `--instance-name INSTANCE_NAME` - the name of your instance
|
|
- `--admin-email ADMIN_EMAIL` - the email address of the instance admin
|
|
- `--notify-email NOTIFY_EMAIL` - email address for notifications
|
|
- `--dbhost HOSTNAME` - the hostname of the PostgreSQL database to use
|
|
- `--dbname DBNAME` - the name of the database to use
|
|
- `--dbuser DBUSER` - the user (aka role) to use for the database connection
|
|
- `--dbpass DBPASS` - the password to use for the database connection
|
|
- `--indexable Y/N` - Allow/disallow indexing site by search engines
|
|
- `--db-configurable Y/N` - Allow/disallow configuring instance from admin part
|
|
"""
|
|
|
|
def run(["gen" | rest]) do
|
|
{options, [], []} =
|
|
OptionParser.parse(
|
|
rest,
|
|
strict: [
|
|
force: :boolean,
|
|
output: :string,
|
|
output_psql: :string,
|
|
domain: :string,
|
|
instance_name: :string,
|
|
admin_email: :string,
|
|
notify_email: :string,
|
|
dbhost: :string,
|
|
dbname: :string,
|
|
dbuser: :string,
|
|
dbpass: :string,
|
|
indexable: :string,
|
|
db_configurable: :string
|
|
],
|
|
aliases: [
|
|
o: :output,
|
|
f: :force
|
|
]
|
|
)
|
|
|
|
paths =
|
|
[config_path, psql_path] = [
|
|
Keyword.get(options, :output, "config/generated_config.exs"),
|
|
Keyword.get(options, :output_psql, "config/setup_db.psql")
|
|
]
|
|
|
|
will_overwrite = Enum.filter(paths, &File.exists?/1)
|
|
proceed? = Enum.empty?(will_overwrite) or Keyword.get(options, :force, false)
|
|
|
|
if proceed? do
|
|
[domain, port | _] =
|
|
String.split(
|
|
get_option(
|
|
options,
|
|
:domain,
|
|
"What domain will your instance use? (e.g pleroma.soykaf.com)"
|
|
),
|
|
":"
|
|
) ++ [443]
|
|
|
|
name =
|
|
get_option(
|
|
options,
|
|
:instance_name,
|
|
"What is the name of your instance? (e.g. Pleroma/Soykaf)"
|
|
)
|
|
|
|
email = get_option(options, :admin_email, "What is your admin email address?")
|
|
|
|
notify_email =
|
|
get_option(
|
|
options,
|
|
:notify_email,
|
|
"What email address do you want to use for sending email notifications?",
|
|
email
|
|
)
|
|
|
|
indexable =
|
|
get_option(
|
|
options,
|
|
:indexable,
|
|
"Do you want search engines to index your site? (y/n)",
|
|
"y"
|
|
) === "y"
|
|
|
|
db_configurable? =
|
|
get_option(
|
|
options,
|
|
:db_configurable,
|
|
"Do you want to be able to configure instance from admin part? (y/n)",
|
|
"y"
|
|
) === "y"
|
|
|
|
dbhost = get_option(options, :dbhost, "What is the hostname of your database?", "localhost")
|
|
|
|
dbname = get_option(options, :dbname, "What is the name of your database?", "pleroma_dev")
|
|
|
|
dbuser =
|
|
get_option(
|
|
options,
|
|
:dbuser,
|
|
"What is the user used to connect to your database?",
|
|
"pleroma"
|
|
)
|
|
|
|
dbpass =
|
|
get_option(
|
|
options,
|
|
:dbpass,
|
|
"What is the password used to connect to your database?",
|
|
:crypto.strong_rand_bytes(64) |> Base.encode64() |> binary_part(0, 64),
|
|
"autogenerated"
|
|
)
|
|
|
|
secret = :crypto.strong_rand_bytes(64) |> Base.encode64() |> binary_part(0, 64)
|
|
signing_salt = :crypto.strong_rand_bytes(8) |> Base.encode64() |> binary_part(0, 8)
|
|
{web_push_public_key, web_push_private_key} = :crypto.generate_key(:ecdh, :prime256v1)
|
|
|
|
result_config =
|
|
EEx.eval_file(
|
|
"sample_config.eex" |> Path.expand(__DIR__),
|
|
domain: domain,
|
|
port: port,
|
|
email: email,
|
|
notify_email: notify_email,
|
|
name: name,
|
|
dbhost: dbhost,
|
|
dbname: dbname,
|
|
dbuser: dbuser,
|
|
dbpass: dbpass,
|
|
version: Pleroma.Mixfile.project() |> Keyword.get(:version),
|
|
secret: secret,
|
|
signing_salt: signing_salt,
|
|
web_push_public_key: Base.url_encode64(web_push_public_key, padding: false),
|
|
web_push_private_key: Base.url_encode64(web_push_private_key, padding: false),
|
|
db_configurable?: db_configurable?
|
|
)
|
|
|
|
result_psql =
|
|
EEx.eval_file(
|
|
"sample_psql.eex" |> Path.expand(__DIR__),
|
|
dbname: dbname,
|
|
dbuser: dbuser,
|
|
dbpass: dbpass
|
|
)
|
|
|
|
shell_info(
|
|
"Writing config to #{config_path}. You should rename it to config/prod.secret.exs or config/dev.secret.exs."
|
|
)
|
|
|
|
File.write(config_path, result_config)
|
|
shell_info("Writing #{psql_path}.")
|
|
File.write(psql_path, result_psql)
|
|
|
|
write_robots_txt(indexable)
|
|
|
|
shell_info(
|
|
"\n" <>
|
|
"""
|
|
To get started:
|
|
1. Verify the contents of the generated files.
|
|
2. Run `sudo -u postgres psql -f #{escape_sh_path(psql_path)}`.
|
|
""" <>
|
|
if config_path in ["config/dev.secret.exs", "config/prod.secret.exs"] do
|
|
""
|
|
else
|
|
"3. Run `mv #{escape_sh_path(config_path)} 'config/prod.secret.exs'`."
|
|
end
|
|
)
|
|
else
|
|
shell_error(
|
|
"The task would have overwritten the following files:\n" <>
|
|
(Enum.map(paths, &"- #{&1}\n") |> Enum.join("")) <>
|
|
"Rerun with `--force` to overwrite them."
|
|
)
|
|
end
|
|
end
|
|
|
|
defp write_robots_txt(indexable) do
|
|
robots_txt =
|
|
EEx.eval_file(
|
|
Path.expand("robots_txt.eex", __DIR__),
|
|
indexable: indexable
|
|
)
|
|
|
|
static_dir = Pleroma.Config.get([:instance, :static_dir], "instance/static/")
|
|
|
|
unless File.exists?(static_dir) do
|
|
File.mkdir_p!(static_dir)
|
|
end
|
|
|
|
robots_txt_path = Path.join(static_dir, "robots.txt")
|
|
|
|
if File.exists?(robots_txt_path) do
|
|
File.cp!(robots_txt_path, "#{robots_txt_path}.bak")
|
|
shell_info("Backing up existing robots.txt to #{robots_txt_path}.bak")
|
|
end
|
|
|
|
File.write(robots_txt_path, robots_txt)
|
|
shell_info("Writing #{robots_txt_path}.")
|
|
end
|
|
end
|