src/Pure/Tools/phabricator.scala
changeset 71280 5a2033fc8f3d
parent 71277 74cabc06cf2d
child 71281 5b3a813853bb
equal deleted inserted replaced
71279:2e873da296ae 71280:5a2033fc8f3d
    25     List(
    25     List(
    26       // https://secure.phabricator.com/source/phabricator/browse/master/scripts/install/install_ubuntu.sh 15e6e2adea61
    26       // https://secure.phabricator.com/source/phabricator/browse/master/scripts/install/install_ubuntu.sh 15e6e2adea61
    27       "git", "mysql-server", "apache2", "libapache2-mod-php", "php", "php-mysql",
    27       "git", "mysql-server", "apache2", "libapache2-mod-php", "php", "php-mysql",
    28       "php-gd", "php-curl", "php-apcu", "php-cli", "php-json", "php-mbstring",
    28       "php-gd", "php-curl", "php-apcu", "php-cli", "php-json", "php-mbstring",
    29       // more packages
    29       // more packages
    30       "php-zip", "python-pygments", "ssh", "subversion", "mercurial")
    30       "php-zip", "python-pygments", "ssh", "subversion",
       
    31       // mercurial build packages
       
    32       "make", "gcc", "python", "python-dev", "python-docutils", "python-pygments", "python-openssl")
    31 
    33 
    32 
    34 
    33   /* global system resources */
    35   /* global system resources */
    34 
    36 
    35   val www_user = "www-data"
    37   val www_user = "www-data"
    57   val default_mailers: Path = Path.explode("mailers.json")
    59   val default_mailers: Path = Path.explode("mailers.json")
    58 
    60 
    59   val default_system_port = 22
    61   val default_system_port = 22
    60   val alternative_system_port = 222
    62   val alternative_system_port = 222
    61   val default_server_port = 2222
    63   val default_server_port = 2222
       
    64 
       
    65   val standard_mercurial_source = "https://www.mercurial-scm.org/release/mercurial-5.2.1.tar.gz"
    62 
    66 
    63 
    67 
    64 
    68 
    65   /** global configuration **/
    69   /** global configuration **/
    66 
    70 
   183     Isabelle_System.chmod("755", command)
   187     Isabelle_System.chmod("755", command)
   184     Isabelle_System.chown("root:root", command)
   188     Isabelle_System.chown("root:root", command)
   185     command
   189     command
   186   }
   190   }
   187 
   191 
       
   192   def mercurial_setup(mercurial_source: String, progress: Progress = No_Progress)
       
   193   {
       
   194     progress.echo("\nBuilding Mercurial from source: " + quote(mercurial_source))
       
   195     Isabelle_System.with_tmp_dir("mercurial")(tmp_dir =>
       
   196     {
       
   197       val archive =
       
   198         if (Url.is_wellformed(mercurial_source)) {
       
   199           val archive = tmp_dir + Path.basic("mercurial.tar.gz")
       
   200           Bytes.write(archive, Url.read_bytes(Url(mercurial_source)))
       
   201           archive
       
   202         }
       
   203         else Path.explode(mercurial_source)
       
   204 
       
   205       Isabelle_System.gnutar("-xzf " + File.bash_path(archive), dir = tmp_dir).check
       
   206 
       
   207       File.read_dir(tmp_dir).filter(name => (tmp_dir + Path.basic(name)).is_dir) match {
       
   208         case List(dir) =>
       
   209           val build_dir = tmp_dir + Path.basic(dir)
       
   210           progress.bash("make all && make install", cwd = build_dir.file, echo = true).check
       
   211         case dirs =>
       
   212           error("Bad archive " + archive +
       
   213             (if (dirs.isEmpty) "" else "\nmultiple directory entries " + commas_quote(dirs)))
       
   214       }
       
   215     })
       
   216   }
       
   217 
   188   def phabricator_setup(
   218   def phabricator_setup(
   189     name: String = default_name,
   219     name: String = default_name,
   190     root: String = "",
   220     root: String = "",
   191     repo: String = "",
   221     repo: String = "",
   192     package_update: Boolean = false,
   222     package_update: Boolean = false,
       
   223     mercurial_source: String = "",
   193     progress: Progress = No_Progress)
   224     progress: Progress = No_Progress)
   194   {
   225   {
   195     /* system environment */
   226     /* system environment */
   196 
   227 
   197     Linux.check_system_root()
   228     Linux.check_system_root()
   203       Linux.check_reboot_required()
   234       Linux.check_reboot_required()
   204     }
   235     }
   205 
   236 
   206     Linux.package_install(packages, progress = progress)
   237     Linux.package_install(packages, progress = progress)
   207     Linux.check_reboot_required()
   238     Linux.check_reboot_required()
       
   239 
       
   240 
       
   241     if (mercurial_source.nonEmpty) {
       
   242       for { name <- List("mercurial", "mercurial-common") if Linux.package_installed(name) } {
       
   243         error("Cannot install Mercurial from source:" +
       
   244           "package package " + quote(name) + " already installed")
       
   245       }
       
   246       mercurial_setup(mercurial_source, progress = progress)
       
   247     }
   208 
   248 
   209 
   249 
   210     /* users */
   250     /* users */
   211 
   251 
   212     if (name.contains((c: Char) => !(Symbol.is_ascii_letter(c) || Symbol.is_ascii_digit(c))) ||
   252     if (name.contains((c: Char) => !(Symbol.is_ascii_letter(c) || Symbol.is_ascii_digit(c))) ||
   269 
   309 
   270 
   310 
   271     val sudoers_file =
   311     val sudoers_file =
   272       Path.explode("/etc/sudoers.d") + Path.basic(isabelle_phabricator_name(name = name))
   312       Path.explode("/etc/sudoers.d") + Path.basic(isabelle_phabricator_name(name = name))
   273     File.write(sudoers_file,
   313     File.write(sudoers_file,
   274       www_user + " ALL=(" + daemon_user + ") SETENV: NOPASSWD: /usr/bin/git, /usr/bin/hg, /usr/bin/ssh, /usr/bin/id\n" +
   314       www_user + " ALL=(" + daemon_user + ") SETENV: NOPASSWD: /usr/bin/git, /usr/local/bin/hg, /usr/bin/hg, /usr/bin/ssh, /usr/bin/id\n" +
   275       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")
   315       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")
   276 
   316 
   277     Isabelle_System.chmod("440", sudoers_file)
   317     Isabelle_System.chmod("440", sudoers_file)
   278 
   318 
   279     config.execute("config set diffusion.ssh-user " + Bash.string(config.name))
   319     config.execute("config set diffusion.ssh-user " + Bash.string(config.name))
   280 
   320 
   441   /* Isabelle tool wrapper */
   481   /* Isabelle tool wrapper */
   442 
   482 
   443   val isabelle_tool2 =
   483   val isabelle_tool2 =
   444     Isabelle_Tool("phabricator_setup", "setup Phabricator server on Ubuntu Linux", args =>
   484     Isabelle_Tool("phabricator_setup", "setup Phabricator server on Ubuntu Linux", args =>
   445     {
   485     {
       
   486       var mercurial_source = ""
   446       var repo = ""
   487       var repo = ""
   447       var package_update = false
   488       var package_update = false
   448       var name = default_name
   489       var name = default_name
   449       var root = ""
   490       var root = ""
   450 
   491 
   451       val getopts =
   492       val getopts =
   452         Getopts("""
   493         Getopts("""
   453 Usage: isabelle phabricator_setup [OPTIONS]
   494 Usage: isabelle phabricator_setup [OPTIONS]
   454 
   495 
   455   Options are:
   496   Options are:
       
   497     -M SOURCE    install Mercurial from source: local PATH, or URL, or ":" for
       
   498                  """ + standard_mercurial_source + """
   456     -R DIR       repository directory (default: """ + default_repo("NAME") + """)
   499     -R DIR       repository directory (default: """ + default_repo("NAME") + """)
   457     -U           full update of system packages before installation
   500     -U           full update of system packages before installation
   458     -n NAME      Phabricator installation name (default: """ + quote(default_name) + """)
   501     -n NAME      Phabricator installation name (default: """ + quote(default_name) + """)
   459     -r DIR       installation root directory (default: """ + default_root("NAME") + """)
   502     -r DIR       installation root directory (default: """ + default_root("NAME") + """)
   460 
   503 
   461   Install Phabricator as LAMP application (Linux, Apache, MySQL, PHP).
   504   Install Phabricator as LAMP application (Linux, Apache, MySQL, PHP).
   462 
   505 
   463   The installation name (default: """ + quote(default_name) + """) is mapped to a regular
   506   The installation name (default: """ + quote(default_name) + """) is mapped to a regular
   464   Unix user; this is relevant for public SSH access.
   507   Unix user; this is relevant for public SSH access.
   465 """,
   508 """,
       
   509           "M:" -> (arg => mercurial_source = (if (arg == ":") standard_mercurial_source else arg)),
   466           "R:" -> (arg => repo = arg),
   510           "R:" -> (arg => repo = arg),
   467           "U" -> (_ => package_update = true),
   511           "U" -> (_ => package_update = true),
   468           "n:" -> (arg => name = arg),
   512           "n:" -> (arg => name = arg),
   469           "r:" -> (arg => root = arg))
   513           "r:" -> (arg => root = arg))
   470 
   514 
   475 
   519 
   476       val release = Linux.Release()
   520       val release = Linux.Release()
   477       if (!release.is_ubuntu_18_04) error("Bad Linux version: Ubuntu 18.04 LTS required")
   521       if (!release.is_ubuntu_18_04) error("Bad Linux version: Ubuntu 18.04 LTS required")
   478 
   522 
   479       phabricator_setup(name = name, root = root, repo = repo,
   523       phabricator_setup(name = name, root = root, repo = repo,
   480         package_update = package_update, progress = progress)
   524         package_update = package_update, mercurial_source = mercurial_source, progress = progress)
   481     })
   525     })
   482 
   526 
   483 
   527 
   484 
   528 
   485   /** setup mail **/
   529   /** setup mail **/