Add mysql::globals and refactor mysql::server.

This work adds a new mysql::globals class which contains a hash used to
build my.cnf from.  It's used to share this data across multiple classes
so that the client and server can share this data.

End users can modify content in my.cnf by including mysql::globals and
passing in override_options as a hash that looks like:

override_options = { 'mysqld' => { 'max_connections' => '120' } }

This completely replaces the mess of parameters that existed in the main
mysql class before.

Completely refactor mysql::server and rework the API.  This changes
ordering, changes from execs{} to mysql_user for the root password,
removes some functionality (like the etc_root_password), and generally
makes some tough decisions about how mysql::server should be built.
This commit is contained in:
Ashley Penney 2013-09-13 13:04:42 -04:00
parent e3843ceb6f
commit e4d5671e7f
10 changed files with 169 additions and 430 deletions

View file

@ -1,51 +1,13 @@
# PRIVATE CLASS: See README.md for more details.
# See README.md for more details.
class mysql::globals (
$override_options = {}
) {
$default_options = {
'bind_address' => '127.0.0.1',
'binlog_do_db' => 'UNSET',
'character_set' => 'UNSET',
'default_engine' => 'UNSET',
'etc_root_password' => false,
'expire_logs_days' => '10',
'ft_max_word_len' => 'UNSET',
'ft_min_word_len' => 'UNSET',
'key_buffer' => '16M',
'log_bin' => 'UNSET',
'log_bin_trust_function_creators' => 'UNSET',
'long_query_time' => 'UNSET',
'manage_config_file' => true,
'max_allowed_packet' => '16M',
'max_binlog_size' => '100M',
'max_connections' => '151',
'max_heap_table_size' => 'UNSET',
'myisam_recover' => 'BACKUP',
'old_root_password' => '',
'port' => '3306',
'purge_conf_dir' => false,
'query_cache_limit' => '1M',
'query_cache_size' => '16M',
'replicate_ignore_table' => 'UNSET',
'replicate_wild_do_table' => 'UNSET',
'replicate_wild_ignore_table' => 'UNSET',
'restart' => true,
'root_password' => 'UNSET',
'server_id' => 'UNSET',
'sql_log_bin' => 'UNSET',
'ssl' => false,
'table_open_cache' => 'UNSET',
'thread_cache_size' => '8',
'thread_stack' => '256K',
'tmp_table_size' => 'UNSET',
}
# mysql::bindings
$java_package_ensure = 'present'
$perl_package_ensure = 'present'
$python_package_ensure = 'present'
$ruby_package_ensure = 'present'
$config_file = $mysql::params::config_file,
$manage_config_file = $mysql::params::manage_config_file,
$old_root_password = $mysql::params::old_root_password,
$override_options = {},
$purge_conf_dir = $mysql::params::purge_conf_dir,
$restart = $mysql::params::restart,
$root_group = $mysql::params::root_group,
) inherits mysql::params {
case $::operatingsystem {
'Ubuntu': {
@ -56,168 +18,53 @@ class mysql::globals (
}
}
case $::osfamily {
'RedHat': {
if $::operatingsystem == 'Fedora' and $::operatingsystemrelease >= 19 {
$client_package_name = 'mariadb'
$server_package_name = 'mariadb-server'
} else {
$client_package_name = 'mysql'
$server_package_name = 'mysql-server'
}
$distro_options = {
'basedir' => '/usr',
'config_file' => '/etc/my.cnf',
'datadir' => '/var/lib/mysql',
'log_error' => '/var/log/mysqld.log',
'pidfile' => '/var/run/mysqld/mysqld.pid',
'root_group' => 'root',
'service_name' => 'mysqld',
'socket' => '/var/lib/mysql/mysql.sock',
'ssl_ca' => '/etc/mysql/cacert.pem',
'ssl_cert' => '/etc/mysql/server-cert.pem',
'ssl_key' => '/etc/mysql/server-key.pem',
'tmpdir' => '/tmp',
}
# mysql::bindings
$java_package_name = 'mysql-connector-java'
$perl_package_name = 'perl-DBD-MySQL'
$php_package_name = 'php-mysql'
$python_package_name = 'MySQL-python'
$ruby_package_name = 'ruby-mysql'
$ruby_package_provider = 'gem'
}
'Suse': {
$client_package_name = $::operatingsystem ? {
/OpenSuSE/ => 'mysql-community-server-client',
/(SLES|SLED)/ => 'mysql-client',
}
$server_package_name = $::operatingsystem ? {
/OpenSuSE/ => 'mysql-community-server',
/(SLES|SLED)/ => 'mysql',
}
$distro_options = {
'basedir' => $basedir,
'config_file' => '/etc/my.cnf',
'datadir' => '/var/lib/mysql',
'log_error' => $::operatingsystem ? {
/OpenSuSE/ => '/var/log/mysql/mysqld.log',
/(SLES|SLED)/ => '/var/log/mysqld.log',
},
'pidfile' => $::operatingsystem ? {
/OpenSuSE/ => '/var/run/mysql/mysqld.pid',
/(SLES|SLED)/ => '/var/lib/mysql/mysqld.pid',
},
'root_group' => 'root',
'service_name' => 'mysql',
'socket' => $::operatingsystem ? {
/OpenSuSE/ => '/var/run/mysql/mysql.sock',
/(SLES|SLED)/ => '/var/lib/mysql/mysql.sock',
},
'ssl_ca' => '/etc/mysql/cacert.pem',
'ssl_cert' => '/etc/mysql/server-cert.pem',
'ssl_key' => '/etc/mysql/server-key.pem',
'tmpdir' => '/tmp',
}
# mysql::bindings
$java_package_name = 'mysql-connector-java'
$perl_package_name = 'perl-DBD-mysql'
$python_package_name = 'python-mysql'
$ruby_package_name = $::operatingsystem ? {
/OpenSuSE/ => 'rubygem-mysql',
/(SLES|SLED)/ => 'ruby-mysql',
}
}
'Debian': {
$client_package_name = 'mysql-client'
$server_package_name = 'mysql-server'
$distro_options = {
'basedir' => '/usr',
'config_file' => '/etc/mysql/my.cnf',
'datadir' => '/var/lib/mysql',
'log_error' => '/var/log/mysql/error.log',
'pidfile' => '/var/run/mysqld/mysqld.pid',
'root_group' => 'root',
'service_name' => 'mysql',
'socket' => '/var/run/mysqld/mysqld.sock',
'ssl_ca' => '/etc/mysql/cacert.pem',
'ssl_cert' => '/etc/mysql/server-cert.pem',
'ssl_key' => '/etc/mysql/server-key.pem',
'tmpdir' => '/tmp',
}
# mysql::bindings
$java_package_name = 'libmysql-java'
$perl_package_name = 'libdbd-mysql-perl'
$php_package_name = 'php5-mysql'
$python_package_name = 'python-mysqldb'
$ruby_package_name = 'libmysql-ruby'
}
'FreeBSD': {
$client_package_name = 'databases/mysql55-client'
$server_package_name = 'databases/mysql55-server'
$distro_options = {
'basedir' => '/usr/local',
'config_file' => '/var/db/mysql/my.cnf',
'datadir' => '/var/db/mysql',
'log_error' => "/var/db/mysql/${::hostname}.err",
'pidfile' => '/var/db/mysql/mysql.pid',
'root_group' => 'wheel',
'service_name' => 'mysql-server',
'socket' => '/tmp/mysql.sock',
'ssl_ca' => undef,
'ssl_cert' => undef,
'ssl_key' => undef,
'tmpdir' => '/tmp',
}
# mysql::bindings
$java_package_name = 'databases/mysql-connector-java'
$perl_package_name = 'p5-DBD-mysql'
$php_package_name = 'php5-mysql'
$python_package_name = 'databases/py-MySQLdb'
$ruby_package_name = 'ruby-mysql'
$ruby_package_provider = 'gem'
}
default: {
case $::operatingsystem {
'Amazon': {
$client_package_name = 'mysql'
$server_package_name = 'mysql-server'
$distro_options = {
'basedir' => '/usr',
'config_file' => '/etc/my.cnf',
'datadir' => '/var/lib/mysql',
'log_error' => '/var/log/mysqld.log',
'pidfile' => '/var/run/mysqld/mysqld.pid',
'root_group' => 'root',
'service_name' => 'mysqld',
'socket' => '/var/lib/mysql/mysql.sock',
'ssl_ca' => '/etc/mysql/cacert.pem',
'ssl_cert' => '/etc/mysql/server-cert.pem',
'ssl_key' => '/etc/mysql/server-key.pem',
'tmpdir' => '/tmp',
}
# mysql::bindings
$java_package_name = 'mysql-connector-java'
$perl_package_name = 'perl-DBD-MySQL'
$php_package_name = 'php-mysql'
$python_package_name = 'MySQL-python'
$ruby_package_name = 'ruby-mysql'
$ruby_package_provider = 'gem'
}
default: {
fail("Unsupported osfamily: ${::osfamily} operatingsystem: ${::operatingsystem}, module ${module_name} only support osfamily RedHat, Debian, and FreeBSD, or operatingsystem Amazon")
}
}
}
$default_options = {
'client' => {
'port' => '3306',
'socket' => $mysql::params::socket,
},
'mysqld_safe' => {
'nice' => '0',
'log_error' => $mysql::params::log_error,
'socket' => $mysql::params::socket,
},
'mysqld' => {
'basedir' => $mysql::params::basedir,
'bind_address' => '127.0.0.1',
'datadir' => $mysql::params::datadir,
'expire_logs_days' => '10',
'key_buffer' => '16M',
'log_error' => $mysql::params::log_error,
'max_allowed_packet' => '16M',
'max_binlog_size' => '100M',
'max_connections' => '151',
'myisam_recover' => 'BACKUP',
'pid_file' => $mysql::params::pidfile,
'port' => '3306',
'query_cache_limit' => '1M',
'query_cache_size' => '16M',
'skip-external-locking' => true,
'socket' => $mysql::params::socket,
'ssl' => false,
'ssl-ca' => $mysql::params::ssl_ca,
'ssl-cert' => $mysql::params::ssl_cert,
'ssl-key' => $mysql::params::ssl_key,
'thread_cache_size' => '8',
'thread_stack' => '256K',
'tmpdir' => $mysql::params::tmpdir,
'user' => 'mysql',
},
'mysqldump' => {
'max_allowed_packets' => '16M',
'quick' => true,
'quote-names' => true,
},
'isamchk' => {
'key_buffer' => '16M',
},
}
# Create a merged together set of options. Rightmost hashes win over left.
$options = merge($default_options, $distro_options, $override_options)
$options = merge($default_options, $override_options)
}

View file

@ -1,32 +1,34 @@
# Class: mysql::server
#
# manages the installation of the mysql server. manages the package, service,
# my.cnf
#
# Parameters:
# [*enabled*] - Defaults to true, boolean to set service ensure.
# [*manage_service*] - Boolean dictating if mysql::server should manage the service
# [*package_ensure*] - Ensure state for package. Can be specified as version.
# [*package_name*] - The name of package
# [*service_name*] - The name of service
# [*service_provider*] - What service provider to use.
#
# Actions:
#
# Requires:
#
# Sample Usage:
#
# Class: mysql::server: See README.md for documentation.
class mysql::server (
$enabled = true,
$manage_service = true,
$package_ensure = $mysql::globals::package_ensure,
$package_name = $mysql::globals::server_package_name,
$service_name = $mysql::globals::service_name,
$service_provider = $mysql::globals::service_provider
#Deprecated.
$enabled = undef,
$manage_service = undef,
#
$old_root_password = $mysql::params::old_root_password,
$package_ensure = $mysql::params::server_package_ensure,
$package_name = $mysql::params::server_package_name,
$remove_default_accounts = false,
$root_password = $mysql::params::root_password,
$service_enabled = $mysql::params::server_service_enabled,
$service_manage = $mysql::params::server_service_manage,
$service_name = $mysql::params::server_service_name,
$service_provider = $mysql::params::server_service_provider
) inherits mysql::globals {
# Deprecated parameters.
if $enabled {
crit('This parameter has been renamed to service_enabled.')
$real_service_enabled = $enabled
} else {
$real_service_enabled = $service_enabled
}
if $manage_service {
crit('This parameter has been renamed to service_manage.')
$real_service_manage = $manage_service
} else {
$real_service_manage = $service_manage
}
Class['mysql::server::root_password'] -> Mysql::Db <| |>
include '::mysql::server::install'
@ -34,9 +36,20 @@ class mysql::server (
include '::mysql::server::service'
include '::mysql::server::root_password'
if $remove_default_accounts {
class { '::mysql::server::account_security':
require => Anchor['mysql::server::end'],
}
}
anchor { 'mysql::server::start': }
anchor { 'mysql::server::end': }
Anchor['mysql::server::start'] ->
Class['mysql::server::install'] ->
Class['mysql::server::config'] ->
Class['mysql::server::service'] ->
Class['mysql::server::root_password']
Class['mysql::server::root_password'] ->
Anchor['mysql::server::end']
}

View file

@ -1,5 +1,3 @@
# Some installations have some default users which are not required.
# We remove them here. You can subclass this class to overwrite this behavior.
class mysql::server::account_security {
mysql_user {
[ "root@${::fqdn}",
@ -9,16 +7,16 @@ class mysql::server::account_security {
'@localhost',
'@%']:
ensure => 'absent',
require => Class['mysql::server::config'],
require => Anchor['mysql::server::end'],
}
if ($::fqdn != $::hostname) {
mysql_user { ["root@${::hostname}", "@${::hostname}"]:
ensure => 'absent',
require => Class['mysql::server::config'],
require => Anchor['mysql::server::end'],
}
}
mysql_database { 'test':
ensure => 'absent',
require => Class['mysql::server::config'],
require => Anchor['mysql::server::end'],
}
}

View file

@ -0,0 +1,56 @@
# See README.me for usage.
class mysql::server::backup (
$backupuser,
$backuppassword,
$backupdir,
$backupcompress = true,
$backuprotate = 30,
$delete_before_dump = false,
$backupdatabases = [],
$file_per_database = false,
$ensure = 'present',
$time = ['23', '5'],
) {
mysql_user { "${backupuser}@localhost":
ensure => $ensure,
password_hash => mysql_password($backuppassword),
provider => 'mysql',
require => Class['mysql::server::config'],
}
mysql_grant { "${backupuser}@localhost/*.*":
ensure => present,
user => "${backupuser}@localhost",
table => '*.*',
privileges => [ 'SELECT', 'RELOAD', 'LOCK TABLES', 'SHOW VIEW' ],
require => Mysql_user["${backupuser}@localhost"],
}
cron { 'mysql-backup':
ensure => $ensure,
command => '/usr/local/sbin/mysqlbackup.sh',
user => 'root',
hour => $time[0],
minute => $time[1],
require => File['mysqlbackup.sh'],
}
file { 'mysqlbackup.sh':
ensure => $ensure,
path => '/usr/local/sbin/mysqlbackup.sh',
mode => '0700',
owner => 'root',
group => 'root',
content => template('mysql/mysqlbackup.sh.erb'),
}
file { 'mysqlbackupdir':
ensure => 'directory',
path => $backupdir,
mode => '0700',
owner => 'root',
group => 'root',
}
}

View file

@ -1,27 +1,13 @@
# See README.me for options.
class mysql::server::config {
$options = $mysql::globals::options
File {
owner => 'root',
group => $options['root_group'],
group => $mysql::globals::root_group,
mode => '0400',
notify => Class['mysql::server::service'],
}
if ( $options['ssl'] ) and ( $options['ssl_ca'] == undef ) {
fail('The ssl_ca parameter is required when ssl is true')
}
if ( $options['ssl'] ) and ( $options['ssl_cert'] == undef ) {
fail('The ssl_cert parameter is required when ssl is true')
}
if ( $options['ssl'] ) and ( $options['ssl_key'] ) == undef {
fail('The ssl_key parameter is required when ssl is true')
}
file { '/etc/mysql':
ensure => directory,
mode => '0755',
@ -30,12 +16,12 @@ class mysql::server::config {
file { '/etc/mysql/conf.d':
ensure => directory,
mode => '0755',
recurse => $options['purge_conf_dir'],
purge => $options['purge_conf_dir'],
recurse => $mysql::globals::purge_conf_dir,
purge => $mysql::globals::purge_conf_dir,
}
if $options['manage_config_file'] {
file { $options['config_file']:
if $mysql::globals::manage_config_file {
file { $mysql::globals::config_file:
content => template('mysql/my.cnf.erb'),
mode => '0644',
}

View file

@ -1,12 +1,11 @@
#This is a helper class to add a monitoring user to the database
#
class mysql::server::monitor (
$mysql_monitor_username,
$mysql_monitor_password,
$mysql_monitor_hostname
) {
Class['mysql::server'] -> Class['mysql::server::monitor']
Anchor['mysql::server::end'] -> Class['mysql::server::monitor']
mysql_user{ "${mysql_monitor_username}@${mysql_monitor_hostname}":
ensure => present,

View file

@ -1,20 +1,7 @@
# Copyright 2009 Larry Ludwig (larrylud@gmail.com)
#
# 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 mysql::server::mysqltuner {
# mysql performance tester
file { '/usr/bin/mysqltuner':
file { '/usr/local/bin/mysqltuner':
ensure => present,
mode => '0550',
source => 'puppet:///modules/mysql/mysqltuner.pl',

View file

@ -1,111 +0,0 @@
# Creates a my.cnf like config file in the conf.d/ directory.
#
# IMPORTANT: this should be used AFTER the inclusion of
# mysql::server because it needs some variables
# out of the mysql::config class which will be
# included!
#
# == Parameters:
#
# - name: is the name of the file
# - notify_service: whether to notify the mysql daemon or not (default: true)
# - settings: either a string which should be the content of the file
# or a hash with the following structure
#
# section => {
# <key> => <value>,
# ...
# },
# ...
#
# +section+ means all these sections you can set in
# an configuration file like +mysqld+, +client+,
# +mysqldump+ and so on
# +key+ has to be a valid property which you can set like
# +datadir+, +socket+ or even flags like +read-only+
#
# +value+ can be
# a) a string as the value
# b) +true+ or +false+ to set a flag like 'read-only' or leave
# it out (+false+ means, nothing will be done)
# c) an array of values which can be of type a) and/or b)
#
#
# == Examples:
#
# Easy one:
#
# mysql::server::config { 'basic_config':
# settings => "[mysqld]\nskip-external-locking\n"
# }
#
# This will create the file /etc/mysql/conf.d/basic_config.cnf with
# the following content:
#
# [mysqld]
# skip-external-locking
#
#
# More complex example:
#
# mysql::server::config { 'basic_config':
# settings => {
# 'mysqld' => {
# 'query_cache_limit' => '5M',
# 'query_cache_size' => '128M',
# 'port' => 3300,
# 'skip-external-locking' => true,
# 'replicate-ignore-db' => [
# 'tmp_table',
# 'whateveryouwant'
# ]
# },
#
# 'client' => {
# 'port' => 3300
# }
# }
# }
#
# This will create the file /etc/mysql/conf.d/basic_config.cnf with
# the following content:
#
# [mysqld]
# query_cache_limit = 5M
# query_cache_size = 128M
# port = 3300
# skip-external-locking
# replicate-ignore-db = tmp_table
# replicate-ignore-db = whateveryouwant
#
# [client]
# port = 3300
#
define mysql::server::config (
$settings,
$notify_service = true
) {
include mysql::config
if is_hash($settings) {
$content = template('mysql/my.conf.cnf.erb')
} else {
$content = $settings
}
file { "/etc/mysql/conf.d/${name}.cnf":
ensure => file,
content => $content,
owner => 'root',
group => $mysql::config::root_group,
mode => '0644',
require => Package['mysql-server'],
}
if $notify_service {
File["/etc/mysql/conf.d/${name}.cnf"] {
# XXX notifying the Service gives us a dependency circle but I don't understand why
notify => Exec['mysqld-restart']
}
}
}

View file

@ -2,53 +2,17 @@
class mysql::server::root_password {
$options = $mysql::globals::options
$service_restart = $options['restart'] ? {
true => Exec['mysqld-restart'],
false => undef,
}
# This kind of sucks, that I have to specify a difference resource for
# restart. the reason is that I need the service to be started before mods
# to the config file which can cause a refresh
exec { 'mysqld-restart':
command => "service ${options['service_name']} restart",
logoutput => on_failure,
refreshonly => true,
path => '/sbin/:/usr/sbin/:/usr/bin/:/bin/',
}
# manage root password if it is set
if $options['root_password'] != 'UNSET' {
case $options['old_root_password'] {
'': { $old_pw='' }
default: { $old_pw="-p'${options[old_root_password]}'" }
}
exec { 'set_mysql_rootpw':
command => "mysqladmin -u root ${old_pw} password '${options[root_password]}'",
logoutput => true,
environment => "HOME=${::root_home}",
unless => "mysqladmin -u root -p'${options[root_password]}' status > /dev/null",
path => '/usr/local/sbin:/usr/bin:/usr/local/bin',
notify => $service_restart,
require => File['/etc/mysql/conf.d'],
if $mysql::server::root_password != 'UNSET' {
mysql_user { 'root@localhost':
ensure => present,
password_hash => mysql_password($mysql::server::root_password),
}
file { "${::root_home}/.my.cnf":
content => template('mysql/my.cnf.pass.erb'),
require => Exec['set_mysql_rootpw'],
notify => undef,
}
if $options['etc_root_password'] {
file{ '/etc/my.cnf':
content => template('mysql/my.cnf.pass.erb'),
require => Exec['set_mysql_rootpw'],
}
}
} else {
file { "${::root_home}/.my.cnf":
ensure => present,
require => Mysql_user['root@localhost'],
}
}

View file

@ -1,17 +1,17 @@
#
class mysql::server::service {
if $mysql::server::enabled {
if $mysql::server::real_service_enabled {
$service_ensure = 'running'
} else {
$service_ensure = 'stopped'
}
if $mysql::server::manage_service {
if $mysql::server::real_service_manage {
service { 'mysqld':
ensure => $service_ensure,
name => $mysql::server::service_name,
enable => $mysql::server::enabled,
enable => $mysql::server::real_service_enabled,
provider => $mysql::server::service_provider,
}
}