De-Montyfy Puppet-phabricator

This patch takes what monty did, and cleans it up. Notable changes
include:

- Configuration has been extracted into a common config resource.
- Installation components have been split into individual concerns,
  to allow some custom setups.
- Directories are now all under /opt/phabricator
- Database user has been given wildcard permissions on database
  phabricator%, to allow the database migration script to run.

Change-Id: I41d808f68aa8587df797b8107dba043b7cccb1a6
This commit is contained in:
Michael Krotscheck 2016-04-26 17:20:38 -05:00
parent 0978a15076
commit ff81b7e5af
No known key found for this signature in database
GPG Key ID: 20E618D878DE38AB
10 changed files with 386 additions and 5249 deletions

File diff suppressed because one or more lines are too long

55
manifests/certificates.pp Normal file
View File

@ -0,0 +1,55 @@
# 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::certificates
#
# Sets up SSL certificates for the module.
#
class phabricator::certificates (
# SSL Certificates.
$ssl_cert_file = $phabricator::config::ssl_cert_file,
$ssl_cert_file_contents = $phabricator::config::ssl_cert_file_contents,
$ssl_chain_file = $phabricator::config::ssl_chain_file,
$ssl_chain_file_contents = $phabricator::config::ssl_chain_file_contents,
$ssl_key_file = $phabricator::config::ssl_key_file,
$ssl_key_file_contents = $phabricator::config::ssl_key_file_contents,
) {
if $ssl_cert_file_contents != undef {
file { $ssl_cert_file:
owner => 'root',
group => 'root',
mode => '0640',
content => $ssl_cert_file_contents,
}
}
if $ssl_key_file_contents != undef {
file { $ssl_key_file:
owner => 'root',
group => 'ssl-cert',
mode => '0640',
content => $ssl_key_file_contents,
}
}
if $ssl_chain_file_contents != undef {
file { $ssl_chain_file:
owner => 'root',
group => 'root',
mode => '0640',
content => $ssl_chain_file_contents,
}
}
}

44
manifests/config.pp Normal file
View File

@ -0,0 +1,44 @@
# 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
#
class phabricator::config (
# 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"
}

42
manifests/httpd.pp Normal file
View File

@ -0,0 +1,42 @@
# 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::httpd
#
# Set up the virtual host for phabricator.
#
class phabricator::httpd (
$ssl_cert_file = $phabricator::config::ssl_cert_file,
$ssl_chain_file = $phabricator::config::ssl_chain_file,
$ssl_key_file = $phabricator::config::ssl_key_file,
$httpd_vhost = $phabricator::config::httpd_vhost,
$httpd_admin_email = $phabricator::config::httpd_admin_email,
$httpd_docroot = $phabricator::config::httpd_docroot,
) {
include ::httpd
include ::httpd::ssl
include ::httpd::php
httpd_mod { 'rewrite':
ensure => present,
}
::httpd::vhost { $httpd_vhost:
port => 443,
docroot => $httpd_docroot,
priority => '50',
template => 'phabricator/vhost.erb',
ssl => true,
}
}

View File

@ -1,174 +1,86 @@
# 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',
# 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::config':
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],
}
}

130
manifests/install.pp Normal file
View File

@ -0,0 +1,130 @@
# 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::config::phabricator_dir,
$mysql_database = $phabricator::config::mysql_database,
$mysql_host = $phabricator::config::mysql_host,
$mysql_port = $phabricator::config::mysql_port,
$mysql_user = $phabricator::config::mysql_user,
$mysql_user_password = $phabricator::config::mysql_user_password,
$httpd_vhost = $phabricator::config::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
}
}
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'],
}
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'],
}
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'],
]
}
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"],
]
}
exec { 'Ensure daemons are running':
command => "${phabricator_dir}/phabricator/bin/phd restart",
unless => "${phabricator_dir}/phabricator/bin/phd status",
subscribe => Vcsrepo["${phabricator_dir}/libphutil"],
require => [
Exec['load-initial-db'],
File['local.json'],
]
}
}

View File

@ -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::config::mysql_host,
$mysql_port = $phabricator::config::mysql_port,
$mysql_user = $phabricator::config::mysql_user,
$mysql_user_password = $phabricator::config::mysql_user_password,
$mysql_root_password = $phabricator::config::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}",
}
}

View File

@ -1,12 +1,15 @@
{
"mysql.pass": "<%= @mysql_user_password %>",
"mysql.user": "<%= @mysql_user %>",
"mysql.host": "<%= @mysql_host %>",
"mysql.port": "<%= @mysql_port %>",
"config.ignore-issues": {
"daemons.need-restarting": true,
"security.security.alternate-file-domain": true
},
"pygments.enabled": true,
"repository.default-local-path": "/var/lib/git",
"repository.default-local-path": "/opt/phabricator/repo",
"phabricator.serious-business": true,
"phabricator.base-uri": "https://<%= @vhost_name %>",
"phabricator.base-uri": "https://<%= @httpd_vhost %>/",
"phabricator.uninstalled-applications": {
"PhabricatorDifferentialApplication": true,
"PhabricatorPhrictionApplication": true,

View File

@ -1,6 +1,6 @@
<VirtualHost *:80>
ServerAdmin noc@openstack.org
ServerName <%= scope.lookupvar("phabricator::vhost_name") %>
ServerAdmin <%= @httpd_admin_email %>
ServerName <%= @httpd_vhost %>
DocumentRoot /var/www
<Directory />
@ -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 @@
</VirtualHost>
<VirtualHost *:443>
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 %>
<Directory />
Options FollowSymLinks
AllowOverride None
</Directory>
<Directory <%= @docroot %>>
<Directory <%= @httpd_docroot %>>
Options Indexes FollowSymLinks MultiViews
AllowOverride None
Order allow,deny

View File

@ -1,17 +0,0 @@
# I started from git clone https://github.com/emonty/phabricator-tools.git
sudo puppet apply phabricator-tools/vagrant/puppet/phabricator/manifests/default.pp --modulepath phabricator-tools/vagrant/puppet
sudo cp ~/local.json /phabricator/instances/dev/phabricator/conf/local/local.json
sudo /phabricator/instances/dev/phabricator/bin/phd start
Then run:
REPAIR TABLE phabricator_search.search_documentfield;
sudo mkdir /var/lib/git
apt-get install exim4 python-pygments
# I did not do: https://secure.phabricator.com/book/phabricator/article/configuring_file_domain/