# HG changeset patch # User wenzelm # Date 1576338986 -3600 # Node ID 5a2033fc8f3d1ae3d8247270b5bb5461c1067839 # Parent 2e873da296ae1d9cceb2ec29fd41a8ac27b0e24b avoid odd (harmless) problem with Mercurial 4.5.3 provided by Ubuntu 18.04 on first push: "couldn't write revision branch cache names"; diff -r 2e873da296ae -r 5a2033fc8f3d src/Doc/System/Phabricator.thy --- a/src/Doc/System/Phabricator.thy Thu Dec 12 16:12:17 2019 +0100 +++ b/src/Doc/System/Phabricator.thy Sat Dec 14 16:56:26 2019 +0100 @@ -86,7 +86,7 @@ The initial setup works as follows (with full Linux package upgrade): - @{verbatim [display] \ isabelle phabricator_setup -U\} + @{verbatim [display] \ isabelle phabricator_setup -U -M:\} After installing many packages, cloning the Phabricator distribution, initializing the MySQL database and Apache, the tool prints an URL for @@ -353,6 +353,7 @@ @{verbatim [display] \Usage: isabelle phabricator_setup [OPTIONS] Options are: + -M SOURCE install Mercurial from source: local PATH, or URL, or ":" -R DIR repository directory (default: "/var/www/phabricator-NAME/repo") -U full update of system packages before installation -n NAME Phabricator installation name (default: "vcs") @@ -382,6 +383,12 @@ Option \<^verbatim>\-U\ ensures a full update of system packages, before installing further packages required by Phabricator. This might require to reboot. + Option \<^verbatim>\-M:\ installs a standard Mercurial release from source: this works + better than the package provided by Ubuntu 18.04. Alternatively, an explicit + file path or URL the source archive (\<^verbatim>\.tar.gz\) may be here. This option is + recommended for production use, but it requires to \<^emph>\uninstall\ existing + Mercurial packages provided by the operating system. + Option \<^verbatim>\-n\ provides an alternative installation name. The default name \<^verbatim>\vcs\ means ``version control system''. The name appears in the URL for SSH access, and thus has some relevance to end-users. The initial server URL diff -r 2e873da296ae -r 5a2033fc8f3d src/Pure/System/linux.scala --- a/src/Pure/System/linux.scala Thu Dec 12 16:12:17 2019 +0100 +++ b/src/Pure/System/linux.scala Sat Dec 14 16:56:26 2019 +0100 @@ -70,6 +70,9 @@ def package_install(packages: List[String], progress: Progress = No_Progress): Unit = progress.bash("apt-get install -y -- " + Bash.strings(packages), echo = true).check + def package_installed(name: String): Boolean = + Isabelle_System.bash("dpkg-query -s " + Bash.string(name)).ok + /* users */ diff -r 2e873da296ae -r 5a2033fc8f3d src/Pure/Tools/phabricator.scala --- a/src/Pure/Tools/phabricator.scala Thu Dec 12 16:12:17 2019 +0100 +++ b/src/Pure/Tools/phabricator.scala Sat Dec 14 16:56:26 2019 +0100 @@ -27,7 +27,9 @@ "git", "mysql-server", "apache2", "libapache2-mod-php", "php", "php-mysql", "php-gd", "php-curl", "php-apcu", "php-cli", "php-json", "php-mbstring", // more packages - "php-zip", "python-pygments", "ssh", "subversion", "mercurial") + "php-zip", "python-pygments", "ssh", "subversion", + // mercurial build packages + "make", "gcc", "python", "python-dev", "python-docutils", "python-pygments", "python-openssl") /* global system resources */ @@ -60,6 +62,8 @@ val alternative_system_port = 222 val default_server_port = 2222 + val standard_mercurial_source = "https://www.mercurial-scm.org/release/mercurial-5.2.1.tar.gz" + /** global configuration **/ @@ -185,11 +189,38 @@ command } + def mercurial_setup(mercurial_source: String, progress: Progress = No_Progress) + { + progress.echo("\nBuilding Mercurial from source: " + quote(mercurial_source)) + Isabelle_System.with_tmp_dir("mercurial")(tmp_dir => + { + val archive = + if (Url.is_wellformed(mercurial_source)) { + val archive = tmp_dir + Path.basic("mercurial.tar.gz") + Bytes.write(archive, Url.read_bytes(Url(mercurial_source))) + archive + } + else Path.explode(mercurial_source) + + Isabelle_System.gnutar("-xzf " + File.bash_path(archive), dir = tmp_dir).check + + File.read_dir(tmp_dir).filter(name => (tmp_dir + Path.basic(name)).is_dir) match { + case List(dir) => + val build_dir = tmp_dir + Path.basic(dir) + progress.bash("make all && make install", cwd = build_dir.file, echo = true).check + case dirs => + error("Bad archive " + archive + + (if (dirs.isEmpty) "" else "\nmultiple directory entries " + commas_quote(dirs))) + } + }) + } + def phabricator_setup( name: String = default_name, root: String = "", repo: String = "", package_update: Boolean = false, + mercurial_source: String = "", progress: Progress = No_Progress) { /* system environment */ @@ -207,6 +238,15 @@ Linux.check_reboot_required() + if (mercurial_source.nonEmpty) { + for { name <- List("mercurial", "mercurial-common") if Linux.package_installed(name) } { + error("Cannot install Mercurial from source:" + + "package package " + quote(name) + " already installed") + } + mercurial_setup(mercurial_source, progress = progress) + } + + /* users */ if (name.contains((c: Char) => !(Symbol.is_ascii_letter(c) || Symbol.is_ascii_digit(c))) || @@ -271,8 +311,8 @@ val sudoers_file = Path.explode("/etc/sudoers.d") + Path.basic(isabelle_phabricator_name(name = name)) File.write(sudoers_file, - www_user + " ALL=(" + daemon_user + ") SETENV: NOPASSWD: /usr/bin/git, /usr/bin/hg, /usr/bin/ssh, /usr/bin/id\n" + - name + " ALL=(" + daemon_user + ") SETENV: NOPASSWD: /usr/bin/git, /usr/bin/git-upload-pack, /usr/bin/git-receive-pack, /usr/bin/hg, /usr/bin/svnserve, /usr/bin/ssh, /usr/bin/id\n") + www_user + " ALL=(" + daemon_user + ") SETENV: NOPASSWD: /usr/bin/git, /usr/local/bin/hg, /usr/bin/hg, /usr/bin/ssh, /usr/bin/id\n" + + name + " ALL=(" + daemon_user + ") SETENV: NOPASSWD: /usr/bin/git, /usr/bin/git-upload-pack, /usr/bin/git-receive-pack, /usr/local/bin/hg, /usr/bin/hg, /usr/bin/svnserve, /usr/bin/ssh, /usr/bin/id\n") Isabelle_System.chmod("440", sudoers_file) @@ -443,6 +483,7 @@ val isabelle_tool2 = Isabelle_Tool("phabricator_setup", "setup Phabricator server on Ubuntu Linux", args => { + var mercurial_source = "" var repo = "" var package_update = false var name = default_name @@ -453,6 +494,8 @@ 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 Phabricator installation name (default: """ + quote(default_name) + """) @@ -463,6 +506,7 @@ 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), @@ -477,7 +521,7 @@ if (!release.is_ubuntu_18_04) error("Bad Linux version: Ubuntu 18.04 LTS required") phabricator_setup(name = name, root = root, repo = repo, - package_update = package_update, progress = progress) + package_update = package_update, mercurial_source = mercurial_source, progress = progress) })