8a1dc0de92
1. Move Mix tasks into a `pleroma` namespace, to avoid collisions with dependent packages. 2. Rename and condense tasks into two `pleroma.user` and `pleroma.gen.instance` tasks for consistency with Hex and Phoenix. 3. Add additional functionality to the tasks to make them more user-friendly. Arguments with sensible defaults were demoted to flags and in the interactive `generate_config` (renamed to `pleroma.gen.instance`), flags were added to allow non-interactive use, though interactive use remains the primary interface. That task also now prompts the user for database parameters. 4. Documentation has been added to both tasks such that `mix help` now shows useful information. 5. Finally, use of IO.puts in tasks has been replaced with Mix.shell() equivalents to make the behavior more consistent with Mix tasks in other packages, and such that variables like MIX_QUIET are respected. The only exception is in `mix pleroma.user reset_password`, wherein the URL must always be printed regardless of the value of MIX_QUIET since that's its entire purpose.
161 lines
5.1 KiB
Elixir
161 lines
5.1 KiB
Elixir
defmodule Mix.Tasks.Pleroma.Gen.Instance do
|
|
use Mix.Task
|
|
|
|
@shortdoc "Generates the configuration for a new instance"
|
|
@moduledoc """
|
|
Generates the configuration for a new instance.
|
|
|
|
If any options are left unspecified, you will be prompted interactively. This
|
|
means the simplest invocation would be
|
|
|
|
mix pleroma.gen.instance
|
|
|
|
## 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
|
|
- `--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
|
|
"""
|
|
|
|
def run(rest) do
|
|
{options, [], []} =
|
|
OptionParser.parse(
|
|
rest,
|
|
strict: [
|
|
force: :boolean,
|
|
output: :string,
|
|
output_psql: :string,
|
|
domain: :string,
|
|
instance_name: :string,
|
|
admin_email: :string,
|
|
dbhost: :string,
|
|
dbname: :string,
|
|
dbuser: :string,
|
|
dbpass: :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)
|
|
|
|
unless not proceed? do
|
|
domain =
|
|
Keyword.get(options, :domain) ||
|
|
Mix.shell().prompt("What domain will your instance use? (e.g. pleroma.soykaf.com)")
|
|
|> String.trim()
|
|
|
|
name =
|
|
Keyword.get(options, :name) ||
|
|
Mix.shell().prompt("What is the name of your instance? (e.g. Pleroma/Soykaf)")
|
|
|> String.trim()
|
|
|
|
email =
|
|
Keyword.get(options, :admin_email) ||
|
|
Mix.shell().prompt("What is your admin email address?")
|
|
|> String.trim()
|
|
|
|
dbhost =
|
|
Keyword.get(options, :dbhost) ||
|
|
case Mix.shell().prompt("What is the hostname of your database? [localhost]") do
|
|
"\n" -> "localhost"
|
|
dbhost -> dbhost |> String.trim()
|
|
end
|
|
|
|
dbname =
|
|
Keyword.get(options, :dbname) ||
|
|
case Mix.shell().prompt("What is the name of your database? [pleroma_dev]") do
|
|
"\n" -> "pleroma_dev"
|
|
dbname -> dbname |> String.trim()
|
|
end
|
|
|
|
dbuser =
|
|
Keyword.get(options, :dbuser) ||
|
|
case Mix.shell().prompt("What is the user used to connect to your database? [pleroma]") do
|
|
"\n" -> "pleroma"
|
|
dbuser -> dbuser |> String.trim()
|
|
end
|
|
|
|
dbpass =
|
|
Keyword.get(options, :dbpass) ||
|
|
case Mix.shell().prompt(
|
|
"What is the password used to connect to your database? [autogenerated]"
|
|
) do
|
|
"\n" -> :crypto.strong_rand_bytes(64) |> Base.encode64() |> binary_part(0, 64)
|
|
dbpass -> dbpass |> String.trim()
|
|
end
|
|
|
|
secret = :crypto.strong_rand_bytes(64) |> Base.encode64() |> binary_part(0, 64)
|
|
|
|
result_config =
|
|
EEx.eval_file(
|
|
"sample_config.eex" |> Path.expand(__DIR__),
|
|
domain: domain,
|
|
email: email,
|
|
name: name,
|
|
dbhost: dbhost,
|
|
dbname: dbname,
|
|
dbuser: dbuser,
|
|
dbpass: dbpass,
|
|
version: Pleroma.Mixfile.project() |> Keyword.get(:version),
|
|
secret: secret
|
|
)
|
|
|
|
result_psql =
|
|
EEx.eval_file(
|
|
"sample_psql.eex" |> Path.expand(__DIR__),
|
|
dbname: dbname,
|
|
dbuser: dbuser,
|
|
dbpass: dbpass
|
|
)
|
|
|
|
Mix.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)
|
|
Mix.shell().info("Writing #{psql_path}.")
|
|
File.write(psql_path, result_psql)
|
|
|
|
Mix.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
|
|
Mix.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 escape_sh_path(path) do
|
|
~S(') <> String.replace(path, ~S('), ~S(\')) <> ~S(')
|
|
end
|
|
end
|