From 00dd06afe4eaaab0e49620cc72ce38d398bde3fe Mon Sep 17 00:00:00 2001 From: Craige McWhirter Date: Fri, 15 Jul 2016 10:23:49 +1000 Subject: [PATCH] Patches Required to Deliver Pholio This set of patches delivers the changes required to install and configure an instance of Pholio for the UX team. Change-Id: I394da0070214af5ceadb3e236eca8a1b78562a72 Implements: Spec Pholio --- .gitignore | 1 + manifests/init.pp | 220 +++++++--------------- manifests/install.pp | 195 +++++++++++++++++++ manifests/mysql.pp | 60 +++--- manifests/vars.pp | 47 +++++ templates/set-auth_providerconfig.sql.erb | 19 ++ templates/vhost.erb | 26 ++- 7 files changed, 381 insertions(+), 187 deletions(-) create mode 100644 manifests/install.pp create mode 100644 manifests/vars.pp create mode 100644 templates/set-auth_providerconfig.sql.erb diff --git a/.gitignore b/.gitignore index dade81e..20e461c 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,3 @@ Gemfile.lock .bundled_gems/ +.vagrant diff --git a/manifests/init.pp b/manifests/init.pp index 2857582..b8a40ae 100644 --- a/manifests/init.pp +++ b/manifests/init.pp @@ -1,174 +1,90 @@ +# Copyright 2016 Hewlett Packard Enterprise Development Company, L.P. +# +# Licensed under the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. You may obtain +# a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. +# # == Class: phabricator # +# Set up a full, standalone instance of phabricator. +# class phabricator ( - $mysql_user_password, - $instance = 'dev', + # Database Configurations. $mysql_database = 'phabricator', $mysql_host = 'localhost', $mysql_port = 3306, $mysql_user = 'phabricator', - $phab_dir = '/phabricator', - $ssl_cert_file = "/etc/ssl/certs/${::fqdn}.pem", + $mysql_user_password, + $mysql_root_password, + + # Phabricator working directory + $phabricator_dir = '/opt/phabricator', + + # OpenID configuration + $auth_location = '/auth/login/RemoteUser:self/', + $authopenidsingleidp = 'https://openstackid.org/', + + # SSL Certificates. + $ssl_cert_file = undef, $ssl_cert_file_contents = undef, # If left empty puppet will not create file. $ssl_chain_file = undef, $ssl_chain_file_contents = undef, # If left empty puppet will not create file. - $ssl_key_file = "/etc/ssl/private/${::fqdn}.key", - $ssl_key_file_contents = undef, # If left empty puppet will not create file. - $vhost_name = $::fqdn, + $ssl_key_file = undef, + $ssl_key_file_contents = undef, # If left empty puppet will not create file. + + # Httpd config. + $httpd_vhost = $::fqdn, + $httpd_admin_email = 'noc@openstack.org', ) { - $instances_dir = "${phab_dir}/instances" - $instance_dir = "${instances_dir}/${instance}" + # Set up the shared configuration. + class { '::phabricator::vars': + mysql_database => $mysql_database, + mysql_host => $mysql_host, + mysql_port => $mysql_port, + mysql_user => $mysql_user, + mysql_user_password => $mysql_user_password, + mysql_root_password => $mysql_root_password, + phabricator_dir => $phabricator_dir, + ssl_cert_file => $ssl_cert_file, + ssl_cert_file_contents => $ssl_cert_file_contents, + ssl_chain_file => $ssl_chain_file, + ssl_chain_file_contents => $ssl_chain_file_contents, + ssl_key_file => $ssl_key_file, + ssl_key_file_contents => $ssl_key_file_contents, + httpd_vhost => $httpd_vhost, + httpd_admin_email => $httpd_admin_email, - $packages = [ - 'php5', - 'php5-mysql', - 'php5-gd', - 'php5-dev', - 'php5-curl', - 'php-apc', - 'php5-cli', - 'python-pygmentize' - ] - package { $packages: - ensure => installed, - } - - if !defined(Package['git']) { - package { 'git': - ensure => present - } - } - - file { $phab_dir: - ensure => directory, - } - file { $instances_dir: - ensure => directory, - } - file { $instance_dir: - ensure => directory, - } - - if $ssl_cert_file_contents != undef { - file { $ssl_cert_file: - owner => 'root', - group => 'root', - mode => '0640', - content => $ssl_cert_file_contents, - before => Httpd::Vhost[$vhost_name], - } - } - - if $ssl_key_file_contents != undef { - file { $ssl_key_file: - owner => 'root', - group => 'ssl-cert', - mode => '0640', - content => $ssl_key_file_contents, - before => Httpd::Vhost[$vhost_name], - } - } - - if $ssl_chain_file_contents != undef { - file { $ssl_chain_file: - owner => 'root', - group => 'root', - mode => '0640', - content => $ssl_chain_file_contents, - before => Httpd::Vhost[$vhost_name], - } - } - - vcsrepo { "${instance_dir}/phabricator": - ensure => latest, - provider => git, - source => 'https://github.com/phacility/phabricator.git', - require => [ - File[$instance_dir], - Package['git'], + before => [ + Class['Phabricator::Certificates'], + Class['Phabricator::Httpd'], + Class['Phabricator::Mysql'], + Class['Phabricator::Install'], ] } - vcsrepo { "${instance_dir}/arcanist": - ensure => latest, - provider => git, - source => 'https://github.com/phacility/arcanist.git', - require => [ - File[$instance_dir], - Package['git'], + include ::phabricator::certificates + include ::phabricator::mysql + + class { '::phabricator::httpd': + require => [ + Class['phabricator::install'], + Class['phabricator::mysql'], + Class['phabricator::certificates'] ] } - vcsrepo { "${instance_dir}/libphutil": - ensure => latest, - provider => git, - source => 'https://github.com/phacility/libphutil.git', - require => [ - File[$instance_dir], - Package['git'], + class { '::phabricator::install': + require => [ + Class['phabricator::mysql'], ] } - - file { 'initial.db': - ensure => present, - path => "${phab_dir}/initial.db", - source => 'puppet:///modules/phabricator/initial.db', - } - - file {'local.json': - ensure => present, - path => "${instance_dir}/phabricator/conf/local/local.json", - content => template('phabricator/local.json.erb'), - } - - file { '/etc/php5/mods-available/phabricator.ini': - ensure => present, - owner => 'root', - group => 'root', - content => "; configuration for phabricator\n; priority=20\npost_max_size = 32M", - - } - - file { '/etc/php5/apache2/conf.d/20-phabricator.ini': - ensure => 'link', - target => '/etc/php5/mods-available/phabricator.ini', - notify => Service['httpd'], - } - - exec { 'load-initial-db': - command => "/usr/bin/mysql < ${phab_dir}/initial.db && ${instance_dir}/phabricator/bin/storage upgrade --force", - unless => "${instance_dir}/phabricator/bin/storage status", - subscribe => File['initial.db'], - refreshonly => true, - require => [ - Vcsrepo["${instance_dir}/phabricator"], - File['initial.db'], - ] - } - - exec { 'update-database': - command => "${instance_dir}/phabricator/bin/storage upgrade --force", - refreshonly => true, - subscribe => Vcsrepo["${instance_dir}/phabricator"], - require => Vcsrepo["${instance_dir}/phabricator"], - } - - include ::httpd - include ::httpd::ssl - include ::httpd::php - - httpd_mod { 'rewrite': - ensure => present, - } - - ::httpd::vhost { $vhost_name: - port => 443, - docroot => "${instance_dir}/phabricator/webroot/", - priority => '50', - template => 'phabricator/vhost.erb', - ssl => true, - require => File[$instance_dir], - } - } diff --git a/manifests/install.pp b/manifests/install.pp new file mode 100644 index 0000000..a8e68be --- /dev/null +++ b/manifests/install.pp @@ -0,0 +1,195 @@ +# Copyright 2016 Hewlett Packard Enterprise Development Company, L.P. +# +# Licensed under the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. You may obtain +# a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. +# +# == Class: phabricator::install +# +# Installation of phabricator itself. +# +class phabricator::install ( + $phabricator_dir = $phabricator::vars::phabricator_dir, + $mysql_database = $phabricator::vars::mysql_database, + $mysql_host = $phabricator::vars::mysql_host, + $mysql_port = $phabricator::vars::mysql_port, + $mysql_user = $phabricator::vars::mysql_user, + $mysql_user_password = $phabricator::vars::mysql_user_password, + $httpd_vhost = $phabricator::vars::httpd_vhost, +) { + + # Dependencies + package { [ + 'php5', + 'php5-mysql', + 'php5-gd', + 'php5-dev', + 'php5-curl', + 'php-apc', + 'php5-cli', + 'php5-json', + 'sendmail', + 'python-pygments']: + ensure => present, + } + if !defined(Package['git']) { + package { 'git': + ensure => present + } + } + if !defined(Package['libapache2-mod-auth-openid']) { + package { 'libapache2-mod-auth-openid': + ensure => present + } + } + + # Set "post_max_size" in your PHP configuration to at least 32MB to support + # large file uploads. + ini_setting { 'Increase post_max_size in php.ini': + ensure => present, + path => '/etc/php5/apache2/php.ini', + section => 'PHP', + setting => 'post_max_size', + value => '32M', + notify => Service['httpd'], + } + + # In production, OPcache should be configured to never revalidate code. This + # will slightly improve performance. To do this, disable + # "opcache.validate_timestamps" in your PHP configuration. + ini_setting { 'Set opcache.validate_timestamps in php.ini': + ensure => present, + path => '/etc/php5/apache2/php.ini', + section => 'opcache', + setting => 'opcache.validate_timestamps', + value => '0', + notify => Service['httpd'], + } + + # PHP setting "always_populate_raw_post_data" should be set to "-1" to avoid + # deprecation warnings. + ini_setting { 'Disable PHP always_populate_raw_post_data on php.ini': + ensure => present, + path => '/etc/php5/apache2/php.ini', + section => 'PHP', + setting => 'always_populate_raw_post_data', + value => '-1', + notify => Service['httpd'], + } + + file { [$phabricator_dir, "${phabricator_dir}/repo"]: + ensure => directory, + } + + vcsrepo { "${phabricator_dir}/phabricator": + ensure => latest, + provider => git, + source => 'https://github.com/phacility/phabricator.git', + revision => 'stable', + require => [ + File[$phabricator_dir], + Package['git'], + ] + } + + vcsrepo { "${phabricator_dir}/arcanist": + ensure => latest, + provider => git, + source => 'https://github.com/phacility/arcanist.git', + revision => 'stable', + require => [ + File[$phabricator_dir], + Package['git'], + ] + } + + vcsrepo { "${phabricator_dir}/libphutil": + ensure => latest, + provider => git, + source => 'https://github.com/phacility/libphutil.git', + revision => 'stable', + require => [ + File[$phabricator_dir], + Package['git'], + ] + } + + vcsrepo { "${phabricator_dir}/libphremoteuser": + ensure => latest, + provider => git, + source => 'https://github.com/psigen/libphremoteuser.git', + revision => 'master', + require => [ + File[$phabricator_dir], + Package['git', 'libapache2-mod-auth-openid'], + ] + } + + exec { 'Letting Phabricator know about libphremoteuser...': + command => "${phabricator_dir}/phabricator/bin/config set load-libraries '[\"libphremoteuser/src\"]'", + subscribe => Vcsrepo["${phabricator_dir}/libphremoteuser"], + require => [ + Vcsrepo["${phabricator_dir}/arcanist"], + Vcsrepo["${phabricator_dir}/libphremoteuser"], + ] + } + + exec {'set-auth_providerconfig': + command => "/usr/bin/mysql -u ${mysql_user} -p${mysql_user_password} < ${phabricator_dir}/set-auth_providerconfig.sql", + subscribe => File['set-auth_providerconfig.sql'], + require => [ + Vcsrepo["${phabricator_dir}/phabricator"], + File['set-auth_providerconfig.sql'], + File[$phabricator_dir], + Service['Phabricator-daemons'] + ] + } + + file {'set-auth_providerconfig.sql': + ensure => present, + path => "${phabricator_dir}/set-auth_providerconfig.sql", + content => template('phabricator/set-auth_providerconfig.sql.erb'), + } + + file { 'local.json': + ensure => present, + path => "${phabricator_dir}/phabricator/conf/local/local.json", + content => template('phabricator/local.json.erb'), + require => Vcsrepo["${phabricator_dir}/phabricator"], + notify => Service['httpd'], + } + + exec { 'load-initial-db': + command => "${phabricator_dir}/phabricator/bin/storage upgrade --force", + unless => "${phabricator_dir}/phabricator/bin/storage status", + require => [ + Vcsrepo["${phabricator_dir}/phabricator"], + Vcsrepo["${phabricator_dir}/libphutil"], + Vcsrepo["${phabricator_dir}/arcanist"], + ] + } + + service { 'Phabricator-daemons': + ensure => running, + provider => base, + start => "${phabricator_dir}/phabricator/bin/phd start", + stop => "${phabricator_dir}/phabricator/bin/phd stop", + restart => "${phabricator_dir}/phabricator/bin/phd restart", + status => "${phabricator_dir}/phabricator/bin/phd status", + subscribe => Vcsrepo["${phabricator_dir}/libphutil"], + require => [ + File[$phabricator_dir], + Vcsrepo["${phabricator_dir}/phabricator"], + Vcsrepo["${phabricator_dir}/libphutil"], + Vcsrepo["${phabricator_dir}/arcanist"], + ] + } +} diff --git a/manifests/mysql.pp b/manifests/mysql.pp index f76128a..f5d3ab4 100644 --- a/manifests/mysql.pp +++ b/manifests/mysql.pp @@ -1,4 +1,4 @@ -# Copyright 2014 Hewlett-Packard Development Company, L.P. +# Copyright 2016 Hewlett Packard Enterprise Development Company, L.P. # # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain @@ -14,31 +14,41 @@ # # == Class: phabricator::mysql # +# Set up a mysql host for phabricator. +# class phabricator::mysql( - $mysql_root_password, - $mysql_bind_address = '127.0.0.1', - $mysql_port = '3306' - ) { + $mysql_host = $phabricator::vars::mysql_host, + $mysql_port = $phabricator::vars::mysql_port, + $mysql_user = $phabricator::vars::mysql_user, + $mysql_user_password = $phabricator::vars::mysql_user_password, + $mysql_root_password = $phabricator::vars::mysql_root_password, +) { - class { '::mysql::server': - config_hash => { - 'root_password' => $mysql_root_password, - 'default_engine' => 'InnoDB', - 'bind_address' => $mysql_bind_address, - 'port' => $mysql_port, - } - } - - mysql::server::config { 'phab_config': - settings => { - 'mysqld' => { - 'max_allowed_packet' => '32M', - 'sql_mode' => 'STRICT_ALL_TABLES', - 'ft_stopword_file' => '/phabricator/instances/dev/phabricator/resources/sql/stopwords.txt', - 'ft_min_word_len' => '3', - 'ft_boolean_syntax' => '\' |-><()~*:""&^\'', - 'innodb_buffer_pool_size' => '1600M', - } + class { '::mysql::server': + root_password => $mysql_root_password, + remove_default_accounts => true, + override_options => { + mysqld => { + max_allowed_packet => '32M', + sql_mode => 'STRICT_ALL_TABLES', + ft_stopword_file => '/opt/phabricator/phabricator/resources/sql/stopwords.txt', + ft_min_word_len => 3, + ft_boolean_syntax => '\' |-><()~*:""&^\'', + innodb_buffer_pool_size => '1600M', } - } + }, } + + mysql_user { "${mysql_user}@${mysql_host}": + provider => 'mysql', + password_hash => mysql_password($mysql_user_password), + } + + # Phabricator creates a mess of tables. This ensures that we don't have + # to create ACL's for all of them. + mysql_grant { "${mysql_user}@${mysql_host}/phabricator%.*": + privileges => ['ALL'], + table => 'phabricator%.*', + user => "${mysql_user}@${mysql_host}", + } +} diff --git a/manifests/vars.pp b/manifests/vars.pp new file mode 100644 index 0000000..d1fdf84 --- /dev/null +++ b/manifests/vars.pp @@ -0,0 +1,47 @@ +# Copyright 2016 Hewlett Packard Enterprise Development Company, L.P. +# +# Licensed under the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. You may obtain +# a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. +# +# == Class: phabricator::vars +# +# Variables, and their defaults, shared between all the submodules. This +# module is used as the source of all the shared default values. +# +class phabricator::vars ( + # Database Configurations. + $mysql_database = 'phabricator', + $mysql_host = 'localhost', + $mysql_port = 3306, + $mysql_user = 'phabricator', + $mysql_user_password, + $mysql_root_password, + + # Phabricator working directory + $phabricator_dir = '/opt/phabricator', + + # SSL Certificates. + $ssl_cert_file = undef, + $ssl_cert_file_contents = undef, # If left empty puppet will not create file. + $ssl_chain_file = undef, + $ssl_chain_file_contents = undef, # If left empty puppet will not create file. + $ssl_key_file = undef, + $ssl_key_file_contents = undef, # If left empty puppet will not create file. + + # Virtual host config. + $httpd_vhost = $::fqdn, + $httpd_admin_email = 'noc@openstack.org', +) { + + # Non-configurable-options (derived) + $httpd_docroot = "${phabricator_dir}/phabricator/webroot" +} diff --git a/templates/set-auth_providerconfig.sql.erb b/templates/set-auth_providerconfig.sql.erb new file mode 100644 index 0000000..0dce575 --- /dev/null +++ b/templates/set-auth_providerconfig.sql.erb @@ -0,0 +1,19 @@ +DELETE FROM phabricator_auth.auth_providerconfig; + +INSERT INTO phabricator_auth.auth_providerconfig + SELECT + 1 as id, + "PHID-AUTH-7nztvra7ehvmx2xnmjgc" as phid, + "PhabricatorAuthProviderRemoteUser" as providerClass, + "RemoteUser" as providerType, + "self" as providerDomain, + 1 as isEnabled, + 1 as shouldAllowLogin, + 1 as shouldAllowRegistration, + 1 as shouldAllowLink, + 1 as shouldAllowUnlink, + 1 as shouldTrustEmails, + "[]" as properties, + 1469712430 as dateCreated, + 1469712430 as dateModified, + 0 as shouldAutoLogin; diff --git a/templates/vhost.erb b/templates/vhost.erb index de27939..cc3e424 100644 --- a/templates/vhost.erb +++ b/templates/vhost.erb @@ -1,6 +1,6 @@ - ServerAdmin noc@openstack.org - ServerName <%= scope.lookupvar("phabricator::vhost_name") %> + ServerAdmin <%= @httpd_admin_email %> + ServerName <%= @httpd_vhost %> DocumentRoot /var/www @@ -16,7 +16,7 @@ RewriteEngine on RewriteCond %{SERVER_PORT} !^443$ - RewriteRule ^/(.*)$ https://<%= scope.lookupvar("phabricator::vhost_name") %>/$1 [L,R] + RewriteRule ^/(.*)$ https://<%= @httpd_vhost %>/$1 [L,R] ErrorLog /var/log/apache2/phabricator-error.log @@ -30,24 +30,24 @@ ServerAdmin noc@openstack.org - ServerName <%= scope.lookupvar("phabricator::vhost_name") %> + ServerName <%= @httpd_vhost %> SSLEngine on SSLProtocol All -SSLv2 -SSLv3 - SSLCertificateFile <%= scope.lookupvar("phabricator::ssl_cert_file") %> - SSLCertificateKeyFile <%= scope.lookupvar("phabricator::ssl_key_file") %> + SSLCertificateFile <%= @ssl_cert_file %> + SSLCertificateKeyFile <%= @ssl_key_file %> <%# scope.lookupvar returns nil for an undefined variable in puppet 4 -%> <%# scope.lookupvar returns :undef for an undefined variable in puppet 3 -%> - <% unless ['', nil, :undef].include?(scope.lookupvar("phabricator::ssl_chain_file")) %> - SSLCertificateChainFile <%= scope.lookupvar("phabricator::ssl_chain_file") %> + <% unless ['', nil, :undef].include?(scope.lookupvar("ssl_chain_file")) %> + SSLCertificateChainFile <%= @ssl_chain_file %> <% end %> - DocumentRoot <%= @docroot %> + DocumentRoot <%= @httpd_docroot %> Options FollowSymLinks AllowOverride None - > + > Options Indexes FollowSymLinks MultiViews AllowOverride None Order allow,deny @@ -55,6 +55,12 @@ Require all granted + > + AuthType OpenID + require valid-user + AuthOpenIDSingleIdP <%= @authopenidsingleidp %> + + RewriteEngine on RewriteRule ^/rsrc/(.*) - [L,QSA] RewriteRule ^/favicon.ico - [L,QSA]