Merge "Askbot module refactor"

This commit is contained in:
Jenkins 2015-06-16 17:19:35 +00:00 committed by Gerrit Code Review
commit 3bbc6184ec
23 changed files with 837 additions and 460 deletions

View File

@ -28,24 +28,21 @@ needs to run.
## ::askbot
A module that installs a standalone Askbot application with dependencies based
on configuration settings.
class { 'askbot':
db_provider => 'mysql',
askbot_version => '0.7.50',
redis_enabled => false,
}
## ::askbot::site
This module installs an Askbot site, synchronize and install the database
on configuration settings. This class synchronize and install the database
schema, configure the askbot-celeryd daemon required for scheduled tasks, and
finally apply a proper log rotation.
askbot::site { 'ask.example.com':
The source of deployement is a git repository defined in askbot_repo and
askbot_revision parameters.
class { 'askbot':
dist_root => '/srv/dist',
site_root => '/srv/askbot-site',
askbot_revision => 'master',
askbot_repo => 'https://github.com/ASKBOT/askbot-devel.git',
www_user => 'www-data',
www_group => 'www-data',
slot_name => 'slot0',
site_name => undef,
# custom theme
custom_theme_enabled => false,
custom_theme_name => undef,
@ -83,6 +80,7 @@ A helper module to compile the Sass style sheets for a custom theme. As
OpenStack Askbot theme contains pure Sass files in the repository, for a
production deployment those files must be compiled into css.
askbot::compass { 'slot0':
}
askbot::theme::compass { 'os':
require => Vcsrepo['/srv/askbot-site/themes'],
before => Exec['askbot-static-generate'],
}

138
examples/site.pp Normal file
View File

@ -0,0 +1,138 @@
node 'default' {
# Database configuration
$db_provider = 'pgsql'
$db_name = 'askbotdb'
$db_user = 'askbot'
$db_password = 'mys3cr3tpassw0rd'
# Redis configuration
$redis_enabled = true
$redis_port = 6378
$redis_max_memory = '256m'
$redis_bind = '127.0.0.1'
$redis_password = 's3cr3t'
$site_name = 'askbot-dev.local'
$solr_version = '4.7.2'
case $db_provider {
'mysql': {
class { 'mysql::server':
}
mysql::db { 'askbotdb':
user => 'askbot',
password => 's3cr3t',
host => 'localhost',
grant => ['all'],
before => Class['askbot'],
}
}
'pgsql': {
class { 'postgresql::server': }
postgresql::server::db { $db_name:
user => $db_user,
password => postgresql_password($db_user, $db_password),
before => Class['askbot'],
}
}
default: {
fail("Database provider ${db_provider} is not supported.")
}
}
# redis (custom module written by tipit)
class { 'redis':
redis_port => $redis_port,
redis_max_memory => $redis_max_memory,
redis_bind => $redis_bind,
redis_password => $redis_password,
version => '2.8.4',
before => Class['askbot'],
}
# solr search engine
class { 'solr':
mirror => 'http://apache.mesi.com.ar/lucene/solr',
version => $solr_version,
cores => [ 'core-default', 'core-en', 'core-zh' ],
}
file { '/usr/share/solr/core-en/conf/schema.xml':
ensure => present,
content => template('openstack_project/askbot/schema.en.xml.erb'),
replace => true,
owner => 'jetty',
group => 'jetty',
mode => '0644',
require => File['/usr/share/solr/core-zh/conf'],
}
file { '/usr/share/solr/core-zh/conf/schema.xml':
ensure => present,
content => template('openstack_project/askbot/schema.cn.xml.erb'),
replace => true,
owner => 'jetty',
group => 'jetty',
mode => '0644',
require => File['/usr/share/solr/core-en/conf'],
}
# deploy smartcn Chinese analyzer from solr contrib/analysys-extras
file { "/usr/share/solr/WEB-INF/lib/lucene-analyzers-smartcn-${solr_version}.jar":
ensure => present,
replace => 'no',
source => "/tmp/solr-${solr_version}/contrib/analysis-extras/lucene-libs/lucene-analyzers-smartcn-${solr_version}.jar",
owner => 'root',
group => 'root',
mode => '0644',
require => Exec['copy-solr'],
}
class { 'askbot':
db_provider => $db_provider,
db_name => $db_name,
db_user => $db_user,
db_password => $db_password,
redis_enabled => $redis_enabled,
redis_port => $redis_port,
redis_max_memory => $redis_max_memory,
redis_bind => $redis_bind,
redis_password => $redis_password,
custom_theme_enabled => false,
custom_theme_name => 'os',
site_name => $site_name,
askbot_debug => true,
solr_enabled => true,
# ssl setup
site_ssl_enabled => true,
site_ssl_cert_file => '/etc/ssl/certs/ssl-cert-snakeoil.pem',
site_ssl_key_file => '/etc/ssl/private/ssl-cert-snakeoil.key',
}
# custom theme
vcsrepo { '/srv/askbot-site/themes':
ensure => latest,
provider => git,
revision => 'feature/development',
source => 'https://git.openstack.org/openstack-infra/askbot-theme',
require => [
File['/srv/askbot-site'], Package['git']
],
before => Exec['askbot-syncdb'],
notify => [
Exec['theme-bundle-install-os'],
Exec['theme-bundle-compile-os'],
Exec['askbot-static-generate'],
],
}
askbot::theme::compass { 'os':
require => Vcsrepo['/srv/askbot-site/themes'],
before => Exec['askbot-static-generate'],
}
}

View File

@ -68,7 +68,7 @@
<tokenizer class="solr.StandardTokenizerFactory"/>
<filter class="solr.StopFilterFactory"
ignoreCase="true"
words="stopwords_en.txt"
words="stopwords.txt"
enablePositionIncrements="true"
/>
<filter class="solr.LowerCaseFilterFactory"/>
@ -84,7 +84,7 @@
<filter class="solr.SynonymFilterFactory" synonyms="synonyms.txt" ignoreCase="true" expand="true"/>
<filter class="solr.StopFilterFactory"
ignoreCase="true"
words="stopwords_en.txt"
words="stopwords.txt"
enablePositionIncrements="true"
/>
<filter class="solr.LowerCaseFilterFactory"/>
@ -131,6 +131,9 @@
</types>
<fields>
<field name="_version_" type="long" indexed="true" stored="true"/>
<field name="_root_" type="string" indexed="true" stored="false"/>
<!-- general -->
<field name="id" type="string" indexed="true" stored="true" multiValued="false" required="true"/>
<field name="django_ct" type="string" indexed="true" stored="true" multiValued="false"/>
@ -160,9 +163,6 @@
<field name="title" type="text_en" indexed="true" stored="true" multiValued="false" />
<!-- required by solr 4 -->
<field name="_version_" type="long" indexed="true" stored="true"/>
</fields>
<!-- field to use to determine and enforce document uniqueness. -->
@ -173,4 +173,4 @@
<!-- SolrQueryParser configuration: defaultOperator="AND|OR" -->
<solrQueryParser defaultOperator="AND"/>
</schema>
</schema>

View File

@ -46,18 +46,14 @@
<fieldType name="text_general" class="solr.TextField" positionIncrementGap="100">
<analyzer type="index">
<tokenizer class="solr.StandardTokenizerFactory"/>
<filter class="solr.LowerCaseFilterFactory"/>
<filter class="solr.StopFilterFactory" ignoreCase="true" words="stopwords.txt" enablePositionIncrements="true" />
</analyzer>
<analyzer type="query">
<tokenizer class="solr.StandardTokenizerFactory"/>
<filter class="solr.LowerCaseFilterFactory"/>
<filter class="solr.StopFilterFactory" ignoreCase="true" words="stopwords.txt" enablePositionIncrements="true" />
</analyzer>
</fieldType>
@ -66,7 +62,7 @@
<tokenizer class="solr.StandardTokenizerFactory"/>
<filter class="solr.StopFilterFactory"
ignoreCase="true"
words="stopwords_en.txt"
words="stopwords.txt"
enablePositionIncrements="true"
/>
<filter class="solr.LowerCaseFilterFactory"/>
@ -82,7 +78,7 @@
<filter class="solr.SynonymFilterFactory" synonyms="synonyms.txt" ignoreCase="true" expand="true"/>
<filter class="solr.StopFilterFactory"
ignoreCase="true"
words="stopwords_en.txt"
words="stopwords.txt"
enablePositionIncrements="true"
/>
<filter class="solr.LowerCaseFilterFactory"/>
@ -129,6 +125,9 @@
</types>
<fields>
<field name="_version_" type="long" indexed="true" stored="true"/>
<field name="_root_" type="string" indexed="true" stored="false"/>
<!-- general -->
<field name="id" type="string" indexed="true" stored="true" multiValued="false" required="true"/>
<field name="django_ct" type="string" indexed="true" stored="true" multiValued="false"/>
@ -158,9 +157,6 @@
<field name="title" type="text_en" indexed="true" stored="true" multiValued="false" />
<!-- required by solr 4 -->
<field name="_version_" type="long" indexed="true" stored="true"/>
</fields>
<!-- field to use to determine and enforce document uniqueness. -->
@ -171,4 +167,4 @@
<!-- SolrQueryParser configuration: defaultOperator="AND|OR" -->
<solrQueryParser defaultOperator="AND"/>
</schema>
</schema>

107
manifests/config.pp Normal file
View File

@ -0,0 +1,107 @@
# == Class: askbot::config
# This class sets up askbot install
#
# == Parameters
#
# == Actions
class askbot::config (
$db_password,
$redis_password,
$site_root = '/srv/askbot-site',
$dist_root = '/srv/dist',
$www_group = 'www-data',
$db_provider = 'www-data',
$db_name = 'askbotdb',
$db_user = 'askbot',
$db_host = 'localhost',
$askbot_debug = false,
$redis_enabled = false,
$redis_prefix = 'askbot',
$redis_port = 6378,
$redis_max_memory = '256m',
$redis_bind = '127.0.0.1',
$site_ssl_enabled = false,
$site_ssl_cert_file_contents = '',
$site_ssl_key_file_contents = '',
$site_ssl_chain_file_contents = '',
$site_ssl_cert_file = '/etc/ssl/certs/ssl-cert-snakeoil.pem',
$site_ssl_key_file = '/etc/ssl/private/ssl-cert-snakeoil.key',
$site_ssl_chain_file = '',
$site_name = 'askbot',
$custom_theme_enabled = false,
$custom_theme_name = '',
$solr_enabled = false,
$smtp_port = 25,
$smtp_host = 'localhost',
) {
file { $site_root:
ensure => directory,
owner => 'root',
group => 'root',
mode => '0755',
}
file { "${site_root}/upfiles":
ensure => directory,
owner => 'root',
group => $www_group,
mode => '0775',
require => File[$site_root],
}
if $site_ssl_enabled {
class { 'askbot::site::ssl':
site_ssl_cert_file_contents => $site_ssl_cert_file_contents,
site_ssl_key_file_contents => $site_ssl_key_file_contents,
site_ssl_chain_file_contents => $site_ssl_chain_file_contents,
site_ssl_cert_file => $site_ssl_cert_file,
site_ssl_key_file => $site_ssl_key_file,
site_ssl_chain_file => $site_ssl_chain_file,
}
}
class { 'askbot::site::http':
site_root => $site_root,
site_name => $site_name,
}
class { 'askbot::site::celeryd':
site_root => $site_root,
}
class { 'askbot::site::config':
site_root => $site_root,
dist_root => $dist_root,
db_provider => $db_provider,
db_name => $db_name,
db_user => $db_user,
db_password => $db_password,
db_host => $db_host,
askbot_debug => $askbot_debug,
smtp_port => $smtp_host,
smtp_host => $smtp_port,
redis_enabled => $redis_enabled,
redis_prefix => $redis_prefix,
redis_port => $redis_port,
redis_max_memory => $redis_max_memory,
redis_bind => $redis_bind,
redis_password => $redis_password,
custom_theme_enabled => $custom_theme_enabled,
custom_theme_name => $custom_theme_name,
solr_enabled => $solr_enabled,
}
class { 'askbot::site::static':
site_root => $site_root,
}
class { 'askbot::site::log':
site_root => $site_root,
www_group => $www_group,
}
class { 'askbot::site::cron':
site_root => $site_root,
}
}

View File

@ -1,71 +1,144 @@
# Class: askbot
# == Class: askbot
# This class sets up an askbot site
#
# This class installs Askbot and main dependencies, like
# postgresql or mysql driver, and other django libraries.
# (django-redis-cache, django-haystack, pysolr, stopforumspam)
# == Parameters
# - $www_group: group name for web writeable directories like upfiles and log
# - $www_user: user name for web process
# - $askbot_debug: set to true to enable askbot debug mode
# - $dist_root: root directory of distribution releases
# - $site_root: root directory of site config and assets
# - $site_name: fqdn of askbot site
#
# Parameters:
# - $db_provider: database provider (mysql | pgsql)
# - $askbot_version: pip package version of askbot
# - $redis_enabled: set to true if askbot using redis for cache
# Source repository:
# - askbot_repo: git repository of askbot source files
# - askbot_revision: branch of askbot repo used for deployment
#
# Actions:
# - Install Askbot
# - Install Askbot dependencies
# Custom askbot theme settings:
# - $custom_theme_enabled: set to true to enable custom themes, default: false
# - $custom_theme_name: name of custom theme set to default
#
# Redis configuration:
# - $redis_enabled: set to true to use redis as cache backend
# - $redis_prefix: redis key prefix (required for multi-site setups)
# - $redis_port: port of redis service
# - $redis_max_memory: memory allocation for redis
# - $redis_bind: bind address of redis service
# - $redis_password: password required for redis connection
#
# SSL Settings:
# - $site_ssl_enabled: set to true for SSL based vhost
# - $site_ssl_cert_file_contents: x509 certificate in pem format
# - $site_ssl_key_file_contents: the key of site certificate in pem format
# - $site_ssl_chain_file_contents: the issuer certs of site cert (optional)
# - $site_ssl_cert_file: file name of site certificate
# - $site_ssl_key_file: file name of the site certificate's key file
# - $site_ssl_chain_file: file name of the issuer certificates
#
# Email configuration:
# - $smtp_host: hostname of smtp service used for email sending
# - $smtp_port: port of smtp service
#
# Database provider and connection details:
# - $db_provider: database provider (mysql or pgsql)
# - $db_name: database name
# - $db_user: user name required for db connection
# - $db_password: password required for db connection
# - $db_host: database host
#
# Solr support:
# - solr_enabled: set true to use solr as a search indexing engine
#
# == Actions
#
class askbot (
$db_provider = 'mysql',
$askbot_version = '0.7.50',
$redis_enabled = false,
$db_password,
$redis_password,
$dist_root = '/srv/dist',
$site_root = '/srv/askbot-site',
$askbot_revision = 'master',
$askbot_repo = 'https://github.com/ASKBOT/askbot-devel.git',
$www_group = 'www-data',
$www_user = 'www-data',
$db_provider = 'mysql',
$db_name = 'askbotdb',
$db_user = 'askbot',
$db_host = 'localhost',
$askbot_debug = false,
$redis_enabled = false,
$redis_prefix = 'askbot',
$redis_port = 6378,
$redis_max_memory = '256m',
$redis_bind = '127.0.0.1',
$site_ssl_enabled = false,
$site_ssl_cert_file_contents = '',
$site_ssl_key_file_contents = '',
$site_ssl_chain_file_contents = '',
$site_ssl_cert_file = '/etc/ssl/certs/ssl-cert-snakeoil.pem',
$site_ssl_key_file = '/etc/ssl/private/ssl-cert-snakeoil.key',
$site_ssl_chain_file = '',
$site_name = 'askbot',
$custom_theme_enabled = false,
$custom_theme_name = '',
$solr_enabled = false,
$smtp_port = '25',
$smtp_host = 'localhost'
) {
include apache::mod::wsgi
case $db_provider {
'mysql': {
$package_deps = [ 'python-pip', 'python-dev', 'python-mysqldb' ]
}
'pgsql': {
$package_deps = [ 'python-pip', 'python-dev', 'python-psycopg2' ]
}
default: {
fail("Unsupported database provider: ${db_provider}")
class { 'askbot::install':
db_provider => $db_provider,
dist_root => $dist_root,
askbot_repo => $askbot_repo,
askbot_revision => $askbot_revision,
redis_enabled => $redis_enabled,
solr_enabled => $solr_enabled,
}
if !defined(File[$dist_root]) {
file { $dist_root:
ensure => directory,
owner => 'root',
group => 'root',
mode => '0755',
}
}
package { $package_deps:
ensure => present,
vcsrepo { "${dist_root}/askbot":
ensure => latest,
provider => git,
revision => $askbot_revision,
source => $askbot_repo,
require => [ File[$dist_root], Package['git'] ],
}
if $redis_enabled {
package { 'django-redis-cache':
ensure => present,
provider => 'pip',
before => Package['askbot'],
}
class { 'askbot::config':
site_root => $site_root,
dist_root => $dist_root,
www_group => $www_group,
db_provider => $db_provider,
db_name => $db_name,
db_user => $db_user,
db_password => $db_password,
db_host => $db_host,
askbot_debug => $askbot_debug,
redis_enabled => $redis_enabled,
redis_prefix => $redis_prefix,
redis_port => $redis_port,
redis_max_memory => $redis_max_memory,
redis_bind => $redis_bind,
redis_password => $redis_password,
site_ssl_enabled => $site_ssl_enabled,
site_ssl_cert_file_contents => $site_ssl_cert_file_contents,
site_ssl_key_file_contents => $site_ssl_key_file_contents,
site_ssl_chain_file_contents => $site_ssl_chain_file_contents,
site_ssl_cert_file => $site_ssl_cert_file,
site_ssl_key_file => $site_ssl_key_file,
site_ssl_chain_file => $site_ssl_chain_file,
site_name => $site_name,
custom_theme_enabled => $custom_theme_enabled,
custom_theme_name => $custom_theme_name,
solr_enabled => $solr_enabled,
smtp_port => $smtp_port,
smtp_host => $smtp_host,
require => [ Vcsrepo["${dist_root}/askbot"], Class['askbot::install'] ],
}
package { [ 'django-haystack', 'pysolr' ]:
ensure => present,
provider => 'pip',
before => Package['askbot'],
}
package { 'stopforumspam':
ensure => present,
provider => 'pip',
before => Package['askbot'],
}
package { 'askbot':
ensure => $askbot_version,
provider => 'pip',
require => Package[$package_deps],
}
file { '/srv/askbot-sites':
ensure => directory,
owner => 'root',
group => 'root',
mode => '0755',
}
}
}

87
manifests/install.pp Normal file
View File

@ -0,0 +1,87 @@
# == Class: askbot::install
# This class installs the required packages for askbot
class askbot::install (
$db_provider = 'mysql',
$dist_root = '/srv/dist',
$askbot_repo = 'https://github.com/ASKBOT/askbot-devel.git',
$askbot_revision = 'master',
$redis_enabled = false,
$solr_enabled = false,
) {
if !defined(Package['git']) {
package { 'git':
ensure => present,
}
}
if !defined(Package['python-pip']) {
package { 'python-pip':
ensure => present,
}
}
if !defined(Package['python-dev']) {
package { 'python-dev':
ensure => present,
}
}
case $db_provider {
'mysql': {
$db_provider_package = 'python-mysqldb'
}
'pgsql': {
$db_provider_package = 'python-psycopg2'
}
default: {
fail("Unsupported database provider: ${db_provider}")
}
}
if ! defined(Package[$db_provider_package]) {
package { $db_provider_package:
ensure => present,
}
}
if $redis_enabled {
package { 'django-redis-cache':
ensure => present,
provider => 'pip',
}
}
include apache::mod::wsgi
if $solr_enabled {
package { [ 'django-haystack', 'pysolr' ]:
ensure => present,
provider => 'pip',
}
}
package { 'stopforumspam':
ensure => present,
provider => 'pip',
before => Exec['askbot-install'],
}
exec { 'pip-requirements-install':
path => [ '/bin', '/sbin' , '/usr/bin', '/usr/sbin', '/usr/local/bin' ],
command => "pip install -q -r ${dist_root}/askbot/askbot_requirements.txt",
cwd => "${dist_root}/askbot",
logoutput => on_failure,
subscribe => Vcsrepo["${dist_root}/askbot"],
refreshonly => true,
}
exec { 'askbot-install':
path => [ '/bin', '/sbin' , '/usr/bin', '/usr/sbin', '/usr/local/bin' ],
cwd => "${dist_root}/askbot",
command => 'python setup.py -q install',
logoutput => on_failure,
subscribe => Vcsrepo["${dist_root}/askbot"],
refreshonly => true,
}
}

View File

@ -1,335 +0,0 @@
# Class: askbot::site
#
# This class installs an Askbot site.
#
# Parameters:
# - $slot_name: slot name under /srv/askbot-sites
# (Notice: don't use ask as a slot name)
# - $www_group: group name for web writeable directories like upfiles and log
# - $www_user: user name for web process
# - $askbot_debug: set to true to enable askbot debug mode
#
# Custom askbot theme settings:
# - $custom_theme_enabled: set to true to enable custom themes, default: false
# - $custom_theme_name: name of custom theme set to default
#
# Redis configuration:
# - $redis_enabled: set to true to use redis as cache backend
# - $redis_prefix: redis key prefix (required for multi-site setups)
# - $redis_port: port of redis service
# - $redis_max_memory: memory allocation for redis
# - $redis_bind: bind address of redis service
# - $redis_password: password required for redis connection
#
# SSL Settings:
# - $site_ssl_enabled: set to true for SSL based vhost
# - $site_ssl_cert_file_contents: x509 certificate in pem format
# - $site_ssl_key_file_contents: the key of site certificate in pem format
# - $site_ssl_chain_file_contents: the issuer certs of site cert (optional)
# - $site_ssl_cert_file: file name of site certificate
# - $site_ssl_key_file: file name of the site certificate's key file
# - $site_ssl_chain_file: file name of the issuer certificates
#
# Email configuration:
# - $smtp_host: hostname of smtp service used for email sending
# - $smtp_port: port of smtp service
#
# Database provider and connection details:
# - $db_provider: database provider (mysql or pgsql)
# - $db_name: database name
# - $db_user: user name required for db connection
# - $db_password: password required for db connection
# - $db_host: database host
#
# Actions:
# - Install an Askbot site
# - Sync and migrate database schema
# - Install askbot-celeryd daemon
# - Setup log rotatation for application logs
#
define askbot::site (
$www_user = 'www-data',
$www_group = 'www-data',
$slot_name = 'slot0',
$custom_theme_enabled = false,
$custom_theme_name = undef,
$askbot_debug = false,
$redis_enabled = false,
$redis_prefix = 'askbot',
$redis_port = undef,
$redis_max_memory = undef,
$redis_bind = undef,
$redis_password = undef,
$site_ssl_enabled = false,
$site_ssl_cert_file_contents = undef,
$site_ssl_key_file_contents = undef,
$site_ssl_chain_file_contents = undef,
$site_ssl_cert_file = '',
$site_ssl_key_file = '',
$site_ssl_chain_file = '',
$smtp_host = 'localhost',
$smtp_port = '25',
$db_provider = 'mysql',
$db_name = undef,
$db_user = undef,
$db_password = undef,
$db_host = 'localhost',
) {
# ensure askbot base class is included
if ! defined(Class['askbot']) {
fail('You must include the askbot base class before using any askbot defined resources')
}
case $db_provider {
'mysql': {
$db_engine = 'django.db.backends.mysql'
}
'pgsql': {
$db_engine = 'django.db.backends.postgresql_psycopg2'
}
default: {
fail("Unsupported database provider: ${db_provider}")
}
}
$askbot_site_root = "/srv/askbot-sites/${slot_name}"
# ssl certificates
if $site_ssl_enabled == true {
include apache::ssl
# site x509 certificate
if $site_ssl_cert_file_contents != '' {
file { $site_ssl_cert_file:
owner => 'root',
group => 'root',
mode => '0640',
content => $site_ssl_cert_file_contents,
before => Apache::Vhost[$name],
}
}
# site ssl key
if $site_ssl_key_file_contents != '' {
file { $site_ssl_key_file:
owner => 'root',
group => 'root',
mode => '0640',
content => $site_ssl_key_file_contents,
before => Apache::Vhost[$name],
}
}
# site ca certificates file
if $site_ssl_chain_file_contents != '' {
file { $site_ssl_chain_file:
owner => 'root',
group => 'root',
mode => '0640',
content => $site_ssl_chain_file_contents,
before => Apache::Vhost[$name],
}
}
}
# site directory layout
if ! defined(File[$askbot_site_root]) {
file { $askbot_site_root:
ensure => directory,
owner => 'root',
group => 'root',
mode => '0755',
}
}
file { "${askbot_site_root}/log":
ensure => directory,
owner => 'root',
group => $www_group,
mode => '0775',
require => File[$askbot_site_root],
}
# if not exists, create empty log file with
# www-data group write access
file { "${askbot_site_root}/log/askbot.log":
ensure => present,
replace => 'no',
owner => 'root',
group => $www_group,
mode => '0664',
require => File["${askbot_site_root}/log"],
}
file { "${askbot_site_root}/upfiles":
ensure => directory,
owner => 'root',
group => $www_group,
mode => '0775',
require => File[$askbot_site_root],
}
file { "${askbot_site_root}/static":
ensure => directory,
owner => 'root',
group => 'root',
mode => '0755',
require => File[$askbot_site_root],
}
file { "${askbot_site_root}/config":
ensure => directory,
owner => 'root',
group => 'root',
mode => '0755',
require => File[$askbot_site_root],
}
file { "${askbot_site_root}/cron":
ensure => directory,
owner => 'root',
group => 'root',
mode => '0755',
require => File[$askbot_site_root],
}
# askbot setup_templates
# copy template files from askbot's setup_templates into site config
$setup_templates = [ '__init__.py', 'manage.py', 'urls.py', 'django.wsgi']
askbot::template_file { $setup_templates:
template_path => '/usr/local/lib/python2.7/dist-packages/askbot/setup_templates',
dest_dir => "${askbot_site_root}/config",
require => File["${askbot_site_root}/config"],
}
# askbot settings
file { "${askbot_site_root}/config/settings.py":
ensure => present,
owner => 'root',
group => 'root',
mode => '0644',
content => template('askbot/settings.py.erb'),
require => File["${askbot_site_root}/config"],
}
# cron jobs
file { "${askbot_site_root}/cron/send_email_alerts.sh":
ensure => present,
owner => 'root',
group => 'root',
mode => '0644',
content => template('askbot/cron/send_email_alerts.sh.erb'),
require => File["${askbot_site_root}/cron"],
}
file { "${askbot_site_root}/cron/clean_session.sh":
ensure => present,
owner => 'root',
group => 'root',
mode => '0644',
content => template('askbot/cron/clean_session.sh.erb'),
require => File["${askbot_site_root}/cron"],
}
# 0 3 * * *
cron { "${slot_name}-send-email-alerts":
name => "${slot_name}-send-mail-alerts.cron",
command => "/bin/bash ${askbot_site_root}/cron/send_email_alerts.sh",
user => root,
minute => '0',
hour => '3',
require => [
File["${askbot_site_root}/cron/send_email_alerts.sh"],
]
}
# 10 * * * *
cron { "${slot_name}-clean-session":
name => "${slot_name}-clean-session.cron",
command => "/bin/bash ${askbot_site_root}/cron/clean_session.sh",
user => root,
minute => '10',
require => [
File["${askbot_site_root}/cron/clean_session.sh"],
]
}
# post-configuration
Exec {
path => ['/bin', '/usr/bin', '/sbin', '/usr/sbin'],
logoutput => on_failure,
}
$post_config_dependency = [
File["${askbot_site_root}/static"],
File["${askbot_site_root}/log"],
Askbot::Template_file[ $setup_templates ],
File["${askbot_site_root}/config/settings.py"],
Package['askbot'],
]
exec { "askbot-static-generate-${slot_name}":
cwd => "${askbot_site_root}/config",
command => 'python manage.py collectstatic --noinput',
require => $post_config_dependency,
subscribe => File["${askbot_site_root}/config/settings.py"],
refreshonly => true,
}
exec { "askbot-syncdb-${slot_name}":
cwd => "${askbot_site_root}/config",
command => 'python manage.py syncdb --noinput',
require => $post_config_dependency,
subscribe => File["${askbot_site_root}/config/settings.py"],
refreshonly => true,
}
exec { "askbot-migrate-${slot_name}":
cwd => "${askbot_site_root}/config",
command => 'python manage.py migrate --noinput',
require => Exec["askbot-syncdb-${slot_name}"],
subscribe => File["${askbot_site_root}/config/settings.py"],
refreshonly => true,
notify => [ Service['httpd'], Service['askbot-celeryd'] ],
}
apache::vhost { $name:
port => 80,
priority => 10,
docroot => $askbot_site_root,
require => Exec["askbot-migrate-${slot_name}"],
template => 'askbot/askbot.vhost.erb',
}
file { '/etc/init/askbot-celeryd.conf':
ensure => present,
owner => 'root',
group => 'root',
mode => '0644',
content => template('askbot/celeryd.upstart.conf.erb'),
require => Exec["askbot-migrate-${slot_name}"],
}
service { 'askbot-celeryd':
ensure => running,
enable => true,
hasrestart => true,
require => File['/etc/init/askbot-celeryd.conf'],
}
include logrotate
logrotate::file { "askbot-${slot_name}.log":
log => "${askbot_site_root}/askbot.log",
options => [
'compress',
'copytruncate',
'missingok',
'rotate 7',
'daily',
'notifempty',
],
require => [ Service['httpd'], File["${askbot_site_root}/log/askbot.log"] ],
}
}

22
manifests/site/celeryd.pp Normal file
View File

@ -0,0 +1,22 @@
# == Class: askbot::site::celeryd
# This class describes the askbot celery daemon configuration
class askbot::site::celeryd (
$site_root,
) {
file { '/etc/init/askbot-celeryd.conf':
ensure => present,
owner => 'root',
group => 'root',
mode => '0644',
content => template('askbot/celeryd.upstart.conf.erb'),
require => Exec['askbot-migrate'],
}
service { 'askbot-celeryd':
ensure => running,
enable => true,
hasrestart => true,
require => File['/etc/init/askbot-celeryd.conf'],
subscribe => [ Exec['askbot-migrate'], File["${site_root}/config/settings.py"] ]
}
}

100
manifests/site/config.pp Normal file
View File

@ -0,0 +1,100 @@
# == Class: askbot::site::config
# This class configure and askbot site
class askbot::site::config (
$site_root,
$dist_root,
$db_provider,
$db_name,
$db_user,
$db_password,
$db_host,
$askbot_debug,
$smtp_host,
$smtp_port,
$redis_enabled,
$redis_prefix,
$redis_port,
$redis_max_memory,
$redis_bind,
$redis_password,
$custom_theme_enabled,
$custom_theme_name,
$solr_enabled,
) {
case $db_provider {
'mysql': {
$db_engine = 'django.db.backends.mysql'
}
'pgsql': {
$db_engine = 'django.db.backends.postgresql_psycopg2'
}
default: {
fail("Unsupported database provider: ${db_provider}")
}
}
file { "${site_root}/config":
ensure => directory,
owner => 'root',
group => 'root',
mode => '0755',
require => File[$site_root],
}
$setup_templates = [ '__init__.py', 'manage.py', 'urls.py', 'django.wsgi']
askbot::site::setup_template { $setup_templates:
template_path => "${dist_root}/askbot/askbot/setup_templates",
dest_dir => "${site_root}/config",
require => File["${site_root}/config"],
}
file { "${site_root}/config/settings.py":
ensure => present,
owner => 'root',
group => 'root',
mode => '0644',
content => template('askbot/settings.py.erb'),
require => File["${site_root}/config"],
}
# post-configuration
Exec {
path => ['/bin', '/usr/bin', '/sbin', '/usr/sbin'],
logoutput => on_failure,
}
$post_config_dependency = [
File["${site_root}/static"],
File["${site_root}/log"],
Askbot::Site::Setup_template[ $setup_templates ],
File["${site_root}/config/settings.py"],
Vcsrepo["${dist_root}/askbot"],
]
exec { 'askbot-static-generate':
cwd => "${site_root}/config",
command => 'python manage.py collectstatic --noinput',
require => $post_config_dependency,
subscribe => [Vcsrepo["${dist_root}/askbot"], File["${site_root}/config/settings.py"] ],
refreshonly => true,
}
exec { 'askbot-syncdb':
cwd => "${site_root}/config",
command => 'python manage.py syncdb --noinput',
require => $post_config_dependency,
subscribe => [Vcsrepo["${dist_root}/askbot"], File["${site_root}/config/settings.py"] ],
refreshonly => true,
}
# TODO: end of chain: notify httpd, celeryd
exec { 'askbot-migrate':
cwd => "${site_root}/config",
command => 'python manage.py migrate --noinput',
require => Exec['askbot-syncdb'],
subscribe => [Vcsrepo["${dist_root}/askbot"], File["${site_root}/config/settings.py"] ],
refreshonly => true,
}
}

54
manifests/site/cron.pp Normal file
View File

@ -0,0 +1,54 @@
# == Class: askbot::site::cron
# This class describes the askbot scheduled tasks
class askbot::site::cron (
$site_root,
) {
file { "${site_root}/cron":
ensure => directory,
owner => 'root',
group => 'root',
mode => '0755',
require => File[$site_root],
}
file { "${site_root}/cron/send_email_alerts.sh":
ensure => present,
owner => 'root',
group => 'root',
mode => '0644',
content => template('askbot/cron/send_email_alerts.sh.erb'),
require => File["${site_root}/cron"],
}
file { "${site_root}/cron/clean_session.sh":
ensure => present,
owner => 'root',
group => 'root',
mode => '0644',
content => template('askbot/cron/clean_session.sh.erb'),
require => File["${site_root}/cron"],
}
# 0 3 * * *
cron { 'askbot-send-email-alerts':
name => 'askbot-send-mail-alerts.cron',
command => "/bin/bash ${site_root}/cron/send_email_alerts.sh",
user => root,
minute => '0',
hour => '3',
require => [
File["${site_root}/cron/send_email_alerts.sh"],
]
}
# 10 * * * *
cron { 'askbot-clean-session':
name => 'askbot-clean-session.cron',
command => "/bin/bash ${site_root}/cron/clean_session.sh",
user => root,
minute => '10',
require => [
File["${site_root}/cron/clean_session.sh"],
]
}
}

14
manifests/site/http.pp Normal file
View File

@ -0,0 +1,14 @@
# == Class: askbot::site::http
# This class describes the http server configuration
class askbot::site::http (
$site_root,
$site_name,
$site_template = 'askbot/askbot.vhost.erb',
) {
apache::vhost { $site_name:
port => 80,
priority => 10,
docroot => $site_root,
template => $site_template,
}
}

38
manifests/site/log.pp Normal file
View File

@ -0,0 +1,38 @@
# == Class: askbot::site::log
# This class describes the askbot site log files
class askbot::site::log (
$site_root,
$www_group,
) {
file { "${site_root}/log":
ensure => directory,
owner => 'root',
group => $www_group,
mode => '0775',
require => File[$site_root],
}
file { "${site_root}/log/askbot.log":
ensure => present,
replace => 'no',
owner => 'root',
group => $www_group,
mode => '0664',
require => File["${site_root}/log"],
}
include logrotate
logrotate::file { 'askbot':
log => "${site_root}/log/askbot.log",
options => [
'compress',
'copytruncate',
'missingok',
'rotate 7',
'daily',
'notifempty',
],
require => File["${site_root}/log/askbot.log"],
}
}

View File

@ -1,4 +1,4 @@
# Define: askbot::template_file
# Define: askbot::helper::template_file
#
# Define a setup_templates file, cloned from a template
# directory.
@ -7,9 +7,9 @@
# - $template_path: root directory of setup_templates.
# - $dest_dir: destination directory of target files.
#
define askbot::template_file (
$template_path = undef,
$dest_dir = undef,
define askbot::site::setup_template (
$template_path,
$dest_dir,
) {
file { "${dest_dir}/${name}":
ensure => present,
@ -18,4 +18,4 @@ define askbot::template_file (
mode => '0644',
source => "${template_path}/${name}",
}
}
}

45
manifests/site/ssl.pp Normal file
View File

@ -0,0 +1,45 @@
# == Class: askbot::site::ssl
# This class describes the http server's SSL configuration
class askbot::site::ssl (
$site_ssl_cert_file_contents = '',
$site_ssl_key_file_contents = '',
$site_ssl_chain_file_contents = '',
$site_ssl_cert_file = '',
$site_ssl_key_file = '',
$site_ssl_chain_file = '',
) {
include apache::ssl
# site x509 certificate
if $site_ssl_cert_file_contents != '' {
file { $site_ssl_cert_file:
owner => 'root',
group => 'root',
mode => '0640',
content => $site_ssl_cert_file_contents,
before => Apache::Vhost[$name],
}
}
# site ssl key
if $site_ssl_key_file_contents != '' {
file { $site_ssl_key_file:
owner => 'root',
group => 'root',
mode => '0640',
content => $site_ssl_key_file_contents,
before => Apache::Vhost[$name],
}
}
# site ca certificates file
if $site_ssl_chain_file_contents != '' {
file { $site_ssl_chain_file:
owner => 'root',
group => 'root',
mode => '0640',
content => $site_ssl_chain_file_contents,
before => Apache::Vhost[$name],
}
}
}

13
manifests/site/static.pp Normal file
View File

@ -0,0 +1,13 @@
# == Class: askbot::site::static
# This class describes askbot site static files
class askbot::site::static (
$site_root,
) {
file { "${site_root}/static":
ensure => directory,
owner => 'root',
group => 'root',
mode => '0755',
require => File[$site_root],
}
}

View File

@ -1,4 +1,4 @@
# Define: askbot::site
# Define: askbot::theme::compass
#
# This class installs the Ruby based bundler command and compiles
# the Sass files of a custom theme. The theme must contain a
@ -8,26 +8,33 @@
# - Install Ruby / Compass
# - Compile Sass files into Css stylesheets
#
define askbot::compass(
define askbot::theme::compass(
) {
# add ruby, bundler packages if not defined somewhere else
if ! defined(Package['rubygems']) {
package { 'rubygems':
ensure => present,
if $::lsbdistcodename == 'precise' {
# add ruby, bundler packages if not defined somewhere else
if ! defined(Package['rubygems']) {
package { 'rubygems':
ensure => present,
}
}
}
if ! defined(Package['bundler']) {
if ! defined(Package['bundler']) {
package { 'bundler':
ensure => latest,
provider => gem,
require => Package['rubygems'],
}
}
} else {
# add bundler as a debian package
package { 'bundler':
ensure => latest,
provider => gem,
require => Package['rubygems'],
}
}
# install bundle requirements in Gemfiles, compile Sass
exec { "theme-bundle-install-${name}":
cwd => "/srv/askbot-sites/${name}/themes",
cwd => '/srv/askbot-site/themes',
path => ['/bin', '/usr/bin', '/sbin', '/usr/sbin', '/usr/local/bin'],
logoutput => on_failure,
command => 'bundle install',
@ -36,13 +43,13 @@ define askbot::compass(
}
exec { "theme-bundle-compile-${name}":
cwd => "/srv/askbot-sites/${name}/themes",
cwd => '/srv/askbot-site/themes',
path => ['/bin', '/usr/bin', '/sbin', '/usr/sbin', '/usr/local/bin'],
logoutput => on_failure,
command => 'bundle exec compass compile',
require => Exec["theme-bundle-install-${name}"],
refreshonly => true,
notify => Exec["askbot-static-generate-${name}"],
notify => Exec['askbot-static-generate'],
}
}
}

View File

@ -1,6 +1,6 @@
{
"name": "openstackinfra-askbot",
"version": "0.0.1",
"version": "0.0.2",
"author": "Openstack CI",
"summary": "Puppet module for askbot",
"license": "Apache 2.0",
@ -8,7 +8,12 @@
"project_page": "http://docs.openstack.org/infra/system-config/",
"issues_url": "https://storyboard.openstack.org/#!/project/767",
"operatingsystem_support": [
{ "operatingsystem": "Ubuntu", "operatingsystemrelease": ["12.04"] }
{ "operatingsystem": "Ubuntu",
"operatingsystemrelease": [
"12.04",
"14.04"
]
}
],
"requirements": [
{ "name": "pe", "version_requirement": ">= 3.2.0 < 3.4.0" },
@ -18,6 +23,7 @@
{ "name": "puppetlabs/stdlib", "version_requirement": ">= 3.2.0" },
{ "name": "puppetlabs/mysql", "version_requirement": "= 0.6.1" },
{ "name": "puppetlabs/apache", "version_requirement": "= 0.0.4" },
{ "name": "openstackinfra/redis", "version_requirement": "= 0.0.1" }
{ "name": "openstackinfra/redis", "version_requirement": "= 0.0.1" },
{ "name": "openstackinfra/vcsrepo", "version_requirement": "= 0.0.1" }
]
}

View File

@ -3,6 +3,8 @@
# Managed by Puppet
# ************************************
<% trusty_compatible = @lsbdistcodename == 'trusty' %>
WSGIRestrictStdout On
WSGIRestrictSignal Off
@ -31,6 +33,7 @@ NameVirtualHost <%= @vhost_name %>:443
<Directory <%= @docroot %>/static/>
Order deny,allow
Allow from all
<%if trusty_compatible %>Require all granted<%end%>
</Directory>
# uploaded files
@ -38,6 +41,7 @@ NameVirtualHost <%= @vhost_name %>:443
<Directory <%= @docroot %>/upfiles/>
Order deny,allow
Allow from all
<%if trusty_compatible %>Require all granted<%end%>
</Directory>
# wsgi daemon
@ -49,10 +53,11 @@ NameVirtualHost <%= @vhost_name %>:443
WSGIProcessGroup askbot
Order deny,allow
Allow from all
<%if trusty_compatible %>Require all granted<%end%>
</Location>
ErrorLog /var/log/apache2/<%= @name %>_error.log
LogLevel warn
CustomLog /var/log/apache2/<%= @name %>_access.log combined
ServerSignature Off
</VirtualHost>
</VirtualHost>

View File

@ -7,6 +7,6 @@ stop on runlevel [016]
kill timeout 30
respawn
script
chdir /srv/askbot-sites/<%= @slot_name %>/config
chdir /srv/askbot-site/config
exec su -s /bin/sh -c 'exec "$0" "$@"' www-data -- /usr/bin/python manage.py celeryd -c 5 --maxtasksperchild=1000 --time-limit=30
end script

View File

@ -1,3 +1,3 @@
#!/bin/bash
cd <%= @askbot_site_root %>/config
cd <%= @site_root %>/config
python manage.py clean_session

View File

@ -1,3 +1,3 @@
#!/bin/bash
cd <%= @askbot_site_root %>/config
cd <%= @site_root %>/config
python manage.py send_email_alerts

View File

@ -79,7 +79,7 @@ LANGUAGE_CODE = 'en'
# Absolute path to the directory that holds uploaded media
# Example: "/home/media/media.lawrence.com/"
#MEDIA_ROOT = os.path.join(os.path.dirname(__file__), 'askbot', 'upfiles')
MEDIA_ROOT = '/srv/askbot-sites/<%= @slot_name%>/upfiles'
MEDIA_ROOT = '/srv/askbot-sites/upfiles'
MEDIA_URL = '/upfiles/'
STATIC_URL = '/m/'#this must be different from MEDIA_URL
@ -151,7 +151,7 @@ DEFAULT_FILE_STORAGE = 'django.core.files.storage.FileSystemStorage'
#take a look here http://askbot.org/en/question/207/
<% if @custom_theme_enabled %>
ASKBOT_EXTRA_SKINS_DIR = '<%= @askbot_site_root %>/themes'
ASKBOT_EXTRA_SKINS_DIR = '<%= @site_root %>/themes'
<% end %>
TEMPLATE_CONTEXT_PROCESSORS = (
@ -161,6 +161,7 @@ TEMPLATE_CONTEXT_PROCESSORS = (
'askbot.user_messages.context_processors.user_messages',#must be before auth
'django.contrib.auth.context_processors.auth', #this is required for the admin app
'django.core.context_processors.csrf', #necessary for csrf protection
'askbot.deps.group_messaging.context.group_messaging_context',
)
@ -178,8 +179,10 @@ INSTALLED_APPS = (
'django.contrib.sitemaps',
'django.contrib.messages',
#'debug_toolbar',
<% if @solr_enabled %>
#Optional, to enable haystack search
'haystack',
<% end %>
'compressor',
'askbot',
'askbot.deps.django_authopenid',
@ -234,7 +237,7 @@ AUTHENTICATION_BACKENDS = (
#logging settings
LOG_FILENAME = 'askbot.log'
logging.basicConfig(
filename=os.path.join('<%= @askbot_site_root %>/log', LOG_FILENAME),
filename=os.path.join('<%= @site_root %>/log', LOG_FILENAME),
level=logging.CRITICAL,
format='%(pathname)s TIME: %(asctime)s MSG: %(filename)s:%(funcName)s:%(lineno)d %(message)s',
)
@ -268,10 +271,10 @@ CSRF_COOKIE_NAME = '_csrf'
#CSRF_COOKIE_DOMAIN = DOMAIN_NAME
STATIC_ROOT = os.path.join(PROJECT_ROOT, "static")
STATIC_ROOT = '<%= @askbot_site_root %>/static'
STATIC_ROOT = '<%= @site_root %>/static'
STATICFILES_DIRS = (
('default/media', os.path.join(ASKBOT_ROOT, 'media')),
<% if @custom_theme_enabled %>'<%= @askbot_site_root %>/themes',<% end %>
<% if @custom_theme_enabled %>'<%= @site_root %>/themes',<% end %>
)
STATICFILES_FINDERS = (
'django.contrib.staticfiles.finders.FileSystemFinder',
@ -294,7 +297,13 @@ ENABLE_HAYSTACK_SEARCH = False
# }
#}
<% if @solr_enabled %>
#HAYSTACK_SETTINGS
#
# Notice:
# the default and default_en url must match to avoid a bug
# in r0.7.53 that broke the working model of UI search and
# cli indexing.
ENABLE_HAYSTACK_SEARCH = True
HAYSTACK_ROUTERS = ['askbot.search.haystack.routers.LanguageRouter',]
@ -302,7 +311,7 @@ HAYSTACK_ROUTERS = ['askbot.search.haystack.routers.LanguageRouter',]
HAYSTACK_CONNECTIONS = {
'default': {
'ENGINE': 'haystack.backends.solr_backend.SolrEngine',
'URL': 'http://127.0.0.1:8983/solr'
'URL': 'http://127.0.0.1:8983/solr/core-en'
},
'default_en': {
'ENGINE': 'haystack.backends.solr_backend.SolrEngine',
@ -315,7 +324,7 @@ HAYSTACK_CONNECTIONS = {
}
HAYSTACK_SIGNAL_PROCESSOR = 'askbot.search.haystack.signals.AskbotRealtimeSignalProcessor'
<% end %>
TINYMCE_COMPRESSOR = True
@ -346,13 +355,14 @@ TINYMCE_DEFAULT_CONFIG = {
'height': '250'
}
<%if @custom_theme_name %>
LIVESETTINGS_OPTIONS = {
1: {
'DB': True,
'SETTINGS': {
'GENERAL_SKIN_SETTINGS': {
<% if @custom_theme_enabled %>
'ASKBOT_DEFAULT_SKIN': '<%= @custom_theme_name %>',
<%end%>
'SHOW_LOGO': True
},
'LOGIN_PROVIDERS': {
@ -378,7 +388,6 @@ LIVESETTINGS_OPTIONS = {
},
}
}
<%end%>
#delayed notifications, time in seconds, 15 mins by default
NOTIFICATION_DELAY_TIME = 60 * 15