val isabelle_tool1 =
Isabelle_Tool("phabricator", "invoke command-line tool within Phorge home directory",
Scala_Project.here,
{ args => var list = false var name = default_name
val getopts = Getopts("""
Usage: isabelle phabricator [OPTIONS] COMMAND [ARGS...]
Options are:
-l list available Phorge installations
-n NAME Phorge installation name (default: """ + quote(default_name) + """)
Invoke a command-line tool within the home directory of the named
Phorge installation. """, "l" -> (_ => list = true), "n:" -> (arg => name = arg))
val more_args = getopts(args) if (more_args.isEmpty && !list) getopts.usage()
val progress = new Console_Progress
if (list) { for (config <- read_config()) {
progress.echo("phabricator " + quote(config.name) + " root " + config.root)
}
} else { val config = get_config(name) val result = progress.bash(Bash.strings(more_args), cwd = config.home, echo = true) if (!result.ok) error(result.print_return_code)
}
})
/** setup **/
def user_setup(name: String, description: String, ssh_setup: Boolean = false): Unit = { if (!Linux.user_exists(name)) {
Linux.user_add(name, description = description, system = true, ssh_setup = ssh_setup)
} elseif (Linux.user_description(name) != description) {
error("User " + quote(name) + " already exists --" + " for Phorge it should have the description:\n " + quote(description))
}
}
val root_path = if (root.nonEmpty) Path.explode(root) else default_root(name) val repo_path = if (repo.nonEmpty) Path.explode(repo) else default_repo(name)
val configs = read_config()
for (config <- configs if config.name == name) {
error("Duplicate Phorge installation " + quote(name) + " in " + config.root)
}
if (!Isabelle_System.bash("mkdir -p " + File.bash_path(root_path)).ok) {
error("Failed to create root directory " + root_path)
}
def mysql_conf(R: Regex, which: String): String = { val conf = Path.explode("/etc/mysql/debian.cnf")
split_lines(File.read(conf)).collectFirst({ case R(a) => a }) match { case Some(res) => res case None => error("Cannot determine " + which + " from " + conf)
}
}
val mysql_root_user = mysql_conf("""^user\s*=\s*(\S*)\s*$""".r, "superuser name") val mysql_root_password = mysql_conf("""^password\s*=\s*(\S*)\s*$""".r, "superuser password")
val mysql_name = phabricator_name(name = name).replace("-", "_") val mysql_user_string = SQL.string(mysql_name) + "@'localhost'" val mysql_password = Linux.generate_password()
Isabelle_System.bash("mysql --user=" + Bash.string(mysql_root_user) + " --password=" + Bash.string(mysql_root_password) + " --execute=" +
Bash.string( """DROP USER IF EXISTS """ + mysql_user_string + "; " + """CREATE USER """ + mysql_user_string + """ IDENTIFIED BY """ + SQL.string(mysql_password) + """ PASSWORD EXPIRE NEVER; """ + """GRANT ALL ON `""" + (mysql_name + "_%").replace("_", "\\_") + """`.* TO """ + mysql_user_string + "; " + """GRANT PROCESS ON *.* TO """ + mysql_user_string + ";")).check
config.execute("config set mysql.user " + Bash.string(mysql_name))
config.execute("config set mysql.pass " + Bash.string(mysql_password))
config.execute("config set phabricator.cache-namespace " + Bash.string(mysql_name))
config.execute("config set storage.default-namespace " + Bash.string(mysql_name))
config.execute("config set storage.mysql-engine.max-size 8388608")
val isabelle_tool2 =
Isabelle_Tool("phabricator_setup", "setup Phorge server on Ubuntu Linux",
Scala_Project.here,
{ args => var mercurial_source = "" var repo = "" var package_update = false var name = default_name var options = Options.init() var root = "" var webserver = default_webserver
val getopts = Getopts("""
Usage: isabelle phabricator_setup [OPTIONS]
Options are:
-M SOURCE install Mercurial from source: local PATH, or URL, or ":"for """ + standard_mercurial_source + """
-R DIR repository directory (default: """ + default_repo("NAME") + """)
-U full update of system packages before installation
-n NAME Phorge installation name (default: """ + quote(default_name) + """)
-o OPTION override Isabelle system OPTION (via NAME=VAL or NAME)
-r DIR installation root directory (default: """ + default_root("NAME") + """)
-w NAME webserver name (""" +
all_webservers.map(w => quote(w.user_name)).mkString (" or ") + ", default: " + quote(default_webserver.user_name) + """)
Install Phorge as Linux service, based on webserver + PHP + MySQL.
The installation name (default: """ + quote(default_name) + """) is mapped to a regular
Unix user; this is relevant for public SSH access. """, "M:" -> (arg => mercurial_source = (if (arg == ":") standard_mercurial_source else arg)), "R:" -> (arg => repo = arg), "U" -> (_ => package_update = true), "n:" -> (arg => name = arg), "o:" -> (arg => options = options + arg), "r:" -> (arg => root = arg), "w:" -> (arg => webserver = get_webserver(arg)))
val more_args = getopts(args) if (more_args.nonEmpty) getopts.usage()
val config = get_config(name) val default_config_file = config.root + default_mailers
val mail_config = config_file getOrElse default_config_file
def setup_mail: Unit = {
progress.echo("Using mail configuration from " + mail_config)
config.execute("config set cluster.mailers --stdin < " + File.bash_path(mail_config))
if (test_user.nonEmpty) {
progress.echo("Sending test mail to " + quote(test_user))
progress.bash(cwd = config.home, echo = true,
script = """echo "Test from Phorge ($(date))" | bin/mail send-test --subject "Test" --to """ +
Bash.string(test_user)).check
}
}
if (config_file.isEmpty) { if (!default_config_file.is_file) {
File.write(default_config_file, mailers_template)
Isabelle_System.chmod("600", default_config_file)
} if (File.read(default_config_file) == mailers_template) {
progress.echo("Please invoke the tool again, after providing details in\n " +
default_config_file.implode + "\n")
} else setup_mail
} else setup_mail
}
/* Isabelle tool wrapper */
val isabelle_tool3 =
Isabelle_Tool("phabricator_setup_mail", "setup mail for one Phorge installation",
Scala_Project.here,
{ args => var test_user = "" var name = default_name var config_file: Option[Path] = None
val getopts = Getopts("""
Usage: isabelle phabricator_setup_mail [OPTIONS]
Options are:
-T USER send test mail to Phorge user
-f FILE config file (default: """ + default_mailers + """ within Phorge root)
-n NAME Phorge installation name (default: """ + quote(default_name) + """)
Provide mail configuration for existing Phorge installation. """, "T:" -> (arg => test_user = arg), "f:" -> (arg => config_file = Some(Path.explode(arg))), "n:" -> (arg => name = arg))
val more_args = getopts(args) if (more_args.nonEmpty) getopts.usage()
def conf_ssh_port(port: Int): String = if (port == default_system_port) "#Port " + default_system_port else"Port " + port
def read_ssh_port(conf: Path): Int = { val lines = split_lines(File.read(conf)) val ports =
lines.flatMap({ case Port(Value.Int(p)) => Some(p) case No_Port() => Some(default_system_port) case _ => None
})
ports match { case List(port) => port case Nil => error("Missing Port specification in " + conf) case _ => error("Multiple Port specifications in " + conf)
}
}
def write_ssh_port(conf: Path, port: Int): Boolean = { val old_port = read_ssh_port(conf) if (old_port == port) false else { val lines = split_lines(File.read(conf)) val lines1 = lines.map({ case Any_Port() => conf_ssh_port(port) case line => line })
File.write(conf, cat_lines(lines1)) true
}
}
/* phabricator_setup_ssh */
def phabricator_setup_ssh(
server_port: Int = default_server_port,
system_port: Int = default_system_port,
progress: Progress = new Progress
): Unit = {
Linux.check_system_root()
val configs = read_config()
if (server_port == system_port) {
error("Port for Phorge sshd coincides with system port: " + system_port)
}
val sshd_conf_system = Path.explode("/etc/ssh/sshd_config") val sshd_conf_server = sshd_conf_system.ext(isabelle_phabricator_name())
val ssh_name = isabelle_phabricator_name(name = "ssh")
Linux.service_shutdown(ssh_name)
val old_system_port = read_ssh_port(sshd_conf_system) if (old_system_port != system_port) {
progress.echo("Reconfigurig system ssh service")
Linux.service_shutdown("ssh")
write_ssh_port(sshd_conf_system, system_port)
Linux.service_start("ssh")
}
for (config <- configs) {
progress.echo("phabricator " + quote(config.name) + " port " + server_port)
config.execute("config set diffusion.ssh-port " + Bash.string(server_port.toString)) if (server_port == default_system_port) config.execute("config delete diffusion.ssh-port")
}
}
/* Isabelle tool wrapper */
val isabelle_tool4 =
Isabelle_Tool("phabricator_setup_ssh", "setup ssh service for all Phorge installations",
Scala_Project.here,
{ args => var server_port = default_server_port var system_port = default_system_port
val getopts = Getopts("""
Usage: isabelle phabricator_setup_ssh [OPTIONS]
Options are:
-p PORT sshd port for Phorge servers (default: """ + default_server_port + """)
-q PORT sshd port for the operating system (default: """ + default_system_port + """)
Configure ssh service for all Phorge installations: a separate sshd
is run in addition to the one of the operating system, and ports need to
be distinct.
A particular Phorge installation is addressed by using its
name as the ssh user; the actual Phorge user is determined via
stored ssh keys. """, "p:" -> (arg => server_port = Value.Int.parse(arg)), "q:" -> (arg => system_port = Value.Int.parse(arg)))
val more_args = getopts(args) if (more_args.nonEmpty) getopts.usage()
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung ist noch experimentell.