Merge branch 'master' into __jail

This commit is contained in:
Jake Guffey 2012-04-03 14:08:18 -04:00
commit ace13f3582
34 changed files with 564 additions and 129 deletions

1
README
View file

@ -38,6 +38,7 @@ Design | Define target state, do not focus on methods or scripts
Design | Push architecture: Instantly apply your changes
Small core | cdist's core is very small - less code, less bugs
Fast development | Focus on straightforwardness of type creation is a main development objective
Fast development | Batteries included: A lot of requirements can be solved using standard types
Modern Programming Language | cdist is written in Python
Requirements, Scalability | No central server needed, cdist operates in push mode and can be run from any computer
Requirements, Scalability, Upgrade | cdist only needs to be updated on the master, not on the target hosts

122
bin/cdist
View file

@ -1,7 +1,7 @@
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
#
# 2010-2011 Nico Schottelius (nico-cdist at schottelius.org)
# 2010-2012 Nico Schottelius (nico-cdist at schottelius.org)
#
# This file is part of cdist.
#
@ -108,55 +108,48 @@ def configinstall(args, mode):
if args.manifest == '-':
# read initial manifest from stdin
import tempfile
handle, initial_manifest_temp_path = tempfile.mkstemp(prefix='cdist.stdin.')
with os.fdopen(handle, 'w') as fd:
fd.write(sys.stdin.read())
try:
handle, initial_manifest_temp_path = tempfile.mkstemp(prefix='cdist.stdin.')
with os.fdopen(handle, 'w') as fd:
fd.write(sys.stdin.read())
except (IOError, OSError) as e:
raise cdist.Error("Creating tempfile for stdin data failed: %s" % e)
args.manifest = initial_manifest_temp_path
import atexit
atexit.register(lambda: os.remove(initial_manifest_temp_path))
try:
process = {}
failed_hosts = []
time_start = time.time()
for host in args.host:
if args.parallel:
log.debug("Creating child process for %s", host)
process[host] = multiprocessing.Process(target=configinstall_onehost, args=(host, args, mode, True))
process[host].start()
else:
if not configinstall_onehost(host, args, mode, parallel=False):
failed_hosts.append(host)
process = {}
failed_hosts = []
time_start = time.time()
for host in args.host:
if args.parallel:
for p in process.keys():
log.debug("Joining process %s", p)
process[p].join()
log.debug("Creating child process for %s", host)
process[host] = multiprocessing.Process(target=configinstall_onehost, args=(host, args, mode, True))
process[host].start()
else:
try:
configinstall_onehost(host, args, mode, parallel=False)
except cdist.Error as e:
failed_hosts.append(host)
if not process[p].exitcode == 0:
failed_hosts.append(p)
# Catch errors in parallel mode when joining
if args.parallel:
for host in process.keys():
log.debug("Joining process %s", host)
process[host].join()
if len(failed_hosts) > 0:
log.warn("Failed to deploy to the following hosts: " +
" ".join(failed_hosts))
if not process[host].exitcode == 0:
failed_hosts.append(host)
time_end = time.time()
log.info("Total processing time for %s host(s): %s", len(args.host),
(time_end - time_start))
except KeyboardInterrupt:
if args.parallel:
for p in process.keys():
# NOT needed: KeyBoardInterrupet (aka SIGINT)
# is forwarded to processes spawned by multiprocess!
# pid = process[p].pid.__str__()
#log.warn("Terminating deploy " + p + " (" + pid + ")")
# process[p].terminate()
pass
sys.exit(0)
time_end = time.time()
log.info("Total processing time for %s host(s): %s", len(args.host),
(time_end - time_start))
if len(failed_hosts) > 0:
raise cdist.Error("Failed to deploy to the following hosts: " +
" ".join(failed_hosts))
def configinstall_onehost(host, args, mode, parallel):
"""Configure or install ONE remote system"""
@ -176,33 +169,33 @@ def configinstall_onehost(host, args, mode, parallel):
context.cleanup()
except cdist.Error as e:
log.error(e)
return False
except KeyboardInterrupt:
# Do not care in sequential mode, catch in parallel mode
if not parallel:
raise
# We are running in our own process here, need to sys.exit!
if parallel:
log.error(e)
sys.exit(1)
else:
# Catch here, above does not need to know about our errors
return False
raise
return True
except KeyboardInterrupt:
# Ignore in parallel mode, we are existing anyway
if parallel:
sys.exit(0)
# Pass back to controlling code in sequential mode
else:
raise
def emulator():
"""Prepare and run emulator"""
try:
import cdist.emulator
emulator = cdist.emulator.Emulator(sys.argv)
emulator.run()
except cdist.Error as e:
log.error(e)
sys.exit(1)
import cdist.emulator
emulator = cdist.emulator.Emulator(sys.argv)
return emulator.run()
if __name__ == "__main__":
# Sys is needed for sys.exit()
import sys
exit_code = 0
try:
import logging
import os
@ -210,9 +203,8 @@ if __name__ == "__main__":
cdistpythonversion = '3.2'
if sys.version < cdistpythonversion:
print('Cdist requires Python >= ' + cdistpythonversion +
raise cdist.Error('Cdist requires Python >= ' + cdistpythonversion +
' on the source host.')
sys.exit(1)
# Ensure our /lib/ is included into PYTHON_PATH
sys.path.insert(0, os.path.abspath(
@ -230,7 +222,13 @@ if __name__ == "__main__":
else:
commandline()
sys.exit(0)
except KeyboardInterrupt:
sys.exit(0)
pass
except cdist.Error as e:
log.error(e)
exit_code = 1
# Determine exit code by return value of function
sys.exit(exit_code)

View file

@ -35,14 +35,25 @@ month::
See crontab(5). Defaults to *
day_of_week::
See crontab(5). Defaults to *
raw::
Take whatever the user has given instead of time and date fields.
If given, all other time and date fields are ignored.
Can for example be used to specify cron EXTENSIONS like reboot, yearly etc.
See crontab(5) for the extensions if any that your cron implementation
implements.
EXAMPLES
--------
--------------------------------------------------------------------------------
# add cronjob
__cron some-id --user root --command "/path/to/script"
# run Monday to Saturday at 23:15
__cron some-id --user root --command "/path/to/script" \
--hour 23 --minute 15 --day_of_week 1-6
# run on reboot
__cron some-id --user root --command "/path/to/script" \
--raw @reboot
# remove cronjob
__cron some-id --user root --command "/path/to/script" --state absent

View file

@ -23,44 +23,23 @@ user="$(cat "$__object/parameter/user")"
command="$(cat "$__object/parameter/command")"
# set defaults
if [ ! -f "$__object/parameter/state" ]; then
echo "present" > "$__object/parameter/state"
fi
if [ -f "$__object/parameter/minute" ]; then
minute="$(cat "$__object/parameter/minute")"
test -f "$__object/parameter/state" || echo "present" > "$__object/parameter/state"
if [ -f "$__object/parameter/raw" ]; then
raw="$(cat "$__object/parameter/raw")"
entry="$raw $command"
else
minute="*"
echo "$minute" > "$__object/parameter/minute"
fi
if [ -f "$__object/parameter/hour" ]; then
hour="$(cat "$__object/parameter/hour")"
else
hour="*"
echo "$hour" > "$__object/parameter/hour"
fi
if [ -f "$__object/parameter/day_of_month" ]; then
day_of_month="$(cat "$__object/parameter/day_of_month")"
else
day_of_month="*"
echo "$day_of_month" > "$__object/parameter/day_of_month"
fi
if [ -f "$__object/parameter/month" ]; then
month="$(cat "$__object/parameter/month")"
else
month="*"
echo "$month" > "$__object/parameter/month"
fi
if [ -f "$__object/parameter/day_of_week" ]; then
day_of_week="$(cat "$__object/parameter/day_of_week")"
else
day_of_week="*"
echo "$day_of_week" > "$__object/parameter/day_of_week"
minute="$(cat "$__object/parameter/minute" 2>/dev/null || echo "*")"
hour="$(cat "$__object/parameter/hour" 2>/dev/null || echo "*")"
day_of_month="$(cat "$__object/parameter/day_of_month" 2>/dev/null || echo "*")"
month="$(cat "$__object/parameter/month" 2>/dev/null || echo "*")"
day_of_week="$(cat "$__object/parameter/day_of_week" 2>/dev/null || echo "*")"
entry="$minute $hour $day_of_month $month $day_of_week $command"
fi
# NOTE: if changed, also change in explorers
prefix="#cdist:__cron/$name"
suffix="#/cdist:__cron/$name"
echo "$prefix" | tee "$__object/parameter/prefix" > "$__object/parameter/entry"
echo "$minute $hour $day_of_month $month $day_of_week $command" >> "$__object/parameter/entry"
echo "$entry" >> "$__object/parameter/entry"
echo "$suffix" | tee "$__object/parameter/suffix" >> "$__object/parameter/entry"

View file

@ -4,3 +4,4 @@ hour
day_of_month
month
day_of_week
raw

View file

@ -22,6 +22,15 @@
#
name=$__object_id
os_version="$($__explorer/os_version)"
getent gshadow "$name" || true
case "$os_version" in
"Red Hat Enterprise Linux Server release "[45]*|"CentOS release "[45]*)
# TODO: find a way to get this information
echo "$os_version does not have getent gshadow"
;;
*)
getent gshadow "$name" || true
;;
esac

View file

@ -23,23 +23,36 @@
#
name="$__object_id"
os_version="$(cat "$__global/explorer/os_version")"
cd "$__object/parameter"
if grep -q "^${name}:" "$__object/explorer/group"; then
for property in $(ls .); do
new_value="$(cat "$property")"
# argument to pass the groupmod command for this property (exceptions
# are made in the case statement below)
proparg="--$property"
case "$property" in
password)
current_value="$(awk -F: '{ print $2 }' < "$__object/explorer/gshadow")"
case "$os_version" in
"Red Hat Enterprise Linux Server release "[45]*|"CentOS release "[45]*)
# TODO: Use gpasswd? Need to fix gshadow explorer first.
echo "group/$name: '$os_version' groupmod does not support password modification" >&2
exit 1
;;
esac
;;
gid)
# set to -g to support older redhat/centos
proparg="-g"
current_value="$(awk -F: '{ print $3 }' < "$__object/explorer/group")"
;;
esac
if [ "$new_value" != "$current_value" ]; then
set -- "$@" "--$property" \"$new_value\"
set -- "$@" "$proparg" \"$new_value\"
fi
done

View file

@ -0,0 +1,55 @@
#!/bin/sh
#
# 2012 Benedikt Koeppel (code@benediktkoeppel.ch)
#
# This file is part of cdist.
#
# cdist is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# cdist is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with cdist. If not, see <http://www.gnu.org/licenses/>.
#
#
# if --database was specified
if [ -f "$__object/parameter/name" ]; then
database="$(cat "$__object/parameter/name")"
else # otherwise use the object id as database name
database="$__object_id"
fi
cat <<-EOFF
mysql -u root <<-EOF
CREATE DATABASE IF NOT EXISTS $database
EOF
EOFF
# if --user was specified
if [ -f "$__object/parameter/user" ]; then
user="$(cat "$__object/parameter/user")"
# if --password was specified
if [ -f "$__object/parameter/password" ]; then
password="$(cat "$__object/parameter/password")"
cat <<-EOFF
mysql -u root <<-EOF
GRANT ALL PRIVILEGES ON $database.* to '$user'@'localhost' IDENTIFIED BY '$password';
EOF
EOFF
else
password=""
cat <<-EOFF
mysql -u root <<-EOF
GRANT ALL PRIVILEGES ON $database.* to '$user'@'localhost';
EOF
EOFF
fi
fi

View file

@ -0,0 +1,49 @@
cdist-type__mysql_database(7)
=============================
Benedikt Koeppel <code@benediktkoeppel.ch>
NAME
----
cdist-type__mysql_database - Manage a MySQL database
DESCRIPTION
-----------
This cdist type allows you to install a MySQL database.
REQUIRED PARAMETERS
-------------------
None.
OPTIONAL PARAMETERS
-------------------
name::
The name of the database to install
defaults to the object id
user::
A user that should have access to the database
password::
The password for the user who manages the database
EXAMPLES
--------
--------------------------------------------------------------------------------
__mysql_database "cdist" --name "cdist" --user "myuser" --password "mypwd"
--------------------------------------------------------------------------------
SEE ALSO
--------
- cdist-type(7)
COPYING
-------
Copyright \(C) 2012 Benedikt Koeppel. Free use of this software is
granted under the terms of the GNU General Public License version 3 (GPLv3).

View file

@ -0,0 +1,3 @@
name
user
password

View file

@ -30,6 +30,10 @@ fi
# Don't produce "no pkgs installed" output -- breaks things
PKG_OUTPUT=$(pkg_info 2>&1)
if [ ! "$PKG_OUTPUT" = "pkg_info: no packages installed" ]; then
echo "$(echo "$PKG_OUTPUT" | grep "^$name-" | cut '-d ' -f1 | sed "s/$name-//g")"
echo -n "$(echo "$PKG_OUTPUT" \
| awk '{print $1}' \
| sed 's/^\(.*\)-\([^-]*\)$/name:\1 ver:\2/g' \
| grep "name:$name ver:" \
| sed 's/^.*ver:\(.*\)/\1/g')"
fi

View file

@ -44,14 +44,13 @@ case "$os" in
done
;;
debian|ubuntu)
debian|ubuntu|openwrt)
state="present"
[ -f "/etc/rc$runlevel.d/S"??"$name" ] || state="absent"
;;
centos|fedora|owl|redhat)
state="present"
state=$(chkconfig --level "$runlevel" \"$name\" || echo absent)
amazon|centos|fedora|owl|redhat)
state=$(chkconfig --level "$runlevel" "$name" || echo absent)
[ "$state" ] || state="present"
;;

View file

@ -43,10 +43,17 @@ case "$state_should" in
# echo rc-update add \"$name\" default
# ;;
centos|fedora|owl|redhat)
amazon|centos|fedora|owl|redhat)
echo chkconfig \"$name\" on
;;
openwrt)
# 'enable' can be successful and still return a non-zero exit
# code, deal with it by checking for success ourselves in that
# case (the || ... part).
echo "/etc/init.d/\"$name\" enable || [ -f /etc/rc.d/S??\"$name\" ]"
;;
*)
echo "Unsupported os: $os" >&2
exit 1
@ -74,6 +81,10 @@ case "$state_should" in
echo chkconfig \"$name\" off
;;
openwrt)
echo "\"/etc/init.d/$name\" disable"
;;
*)
echo "Unsupported os: $os" >&2
exit 1

View file

@ -4,12 +4,23 @@ Changelog
* Changes are always commented with their author in (braces)
* Exception: No braces means author == Nico Schottelius
2.0.9:
2.0.10:
* Cleanup __group: No getent gshadow in old Redhat, use groupmod -g
(Matt Coddington)
2.0.9: 2012-03-12
* Cleanup documentation: Fix environment variable list to be properly
displayed (Giel van Schijndel)
* Cleanup documentation: Some minor corrections
* New Type: __package_opkg (Giel van Schijndel)
* New Type: __package_pkg_freebsd (Jake Guffey)
* Feature __package: Support OpenWRT (Giel van Schijndel)
* New Type: __mysql_database (Benedikt Koeppel)
* Feature __package: Support for OpenWRT (Giel van Schijndel)
* Feature __start_on_boot: Support for OpenWRT (Giel van Schijndel)
* Feature __start_on_boot: Support for Amazon Linux (Matt Coddington)
* New Example: Use rsync to backup files (Matt Coddington)
* Feature core: Exit non-zero, if configuration failed
* Documentation: Describe how to do templating (Aurélien Bondis)
2.0.8: 2012-02-20
* Bugfix core: Remove another nasty traceback when sending SIGINT (aka Ctrl-C)

View file

@ -0,0 +1,8 @@
require="__package/pkg-config" \
__package libxml2 --version "2.7.8_1" --state installed --pkgsite http://192.168.196.70
Kein
INFO: www: Generating and executing code for __package_pkg_freebsd/libxml2
für
__package/libxml2

View file

@ -3,6 +3,10 @@ UNASSIGNED TODOS
The following list of todos has not been assigned to any developer.
Feel free to pick one!
CORE
----
- support default parameter
TESTS
-----
- multiple defines of object:
@ -38,3 +42,8 @@ TYPES
- __user
add option to include --create-home
- Merge __addifnosuchline and __removeline into __line + --state present|absent
- __cron: Support --file to be used instead of user cron (probably direct support
of /etc/cron.d)
- Support uci from openwrt?
- http://wiki.openwrt.org/doc/uci

View file

@ -90,10 +90,20 @@ TMPDIR, TEMP, TMP::
more information. This is rather useful, if the standard
directory used does not allow executables.
EXIT STATUS
-----------
The following exit values shall be returned:
0::
Successful completion
1::
One or more host configuration failed.
SEE ALSO
--------
- cdist(7)
- cdist-type-emulator(1)
- cdist-reference(7)

View file

@ -153,6 +153,40 @@ implement this scenario with a gateway host and sudo:
For more details consult sudoers(5)
TEMPLATING
----------
* create directory templates/ in your type (convention)
* create the template as an executable file like templates/basic.conf.sh, it will output text using shell variables for the values
--------------------------------------------------------------------------------------
#!/bin/sh
# in the template, use cat << eof (here document) to output the text
# and use standard shell variables in the template
# output everything in the template script to stdout
cat << EOF
server {
listen 80;
server_name $SERVERNAME;
root $ROOT;
access_log /var/log/nginx/$SERVERNAME_access.log
error_log /var/log/nginx/$SERVERNAME_error.log
}
EOF
--------------------------------------------------------------------------------------
* in the manifest, export the relevant variables and add the following lines in your manifest:
--------------------------------------------------------------------------------------
# export variables needed for the template
export SERVERNAME='test"
export ROOT='/var/www/test'
# render the template
mkdir -p "$__object/files"
"$__type/templates/basic.conf.sh" > "$__object/files/basic.conf"
# send the rendered template
__file /etc/nginx/sites-available/test.conf --state present --source "$__object/files/basic.conf"
--------------------------------------------------------------------------------------
SEE ALSO
--------
- cdist(1)

View file

@ -54,9 +54,9 @@ work nor kill the authors brain:
seperate branches. This way one feature can already be included, even if
the other needs to be improved.
As soon as your work meets these requirements, you can contact me
(IRC, Mailinglist, Phone, RFC 1149) and I'll check your code before
including it.
As soon as your work meets these requirements, write a mail
for inclusion to the mailinglist **cdist at cdist -- at -- l.schottelius.org**
or open a pull request at http://github.com/telmich/cdist.
HOW TO SUBMIT A NEW TYPE
@ -75,6 +75,8 @@ code and thus such a type introduces redundant functionality that is given by
core cdist already.
SEE ALSO
--------
- cdist(7)

View file

@ -27,7 +27,7 @@ The initial manifest, which should be used for mappings of hosts to types,
is executed. This stage creates objects in a cconfig database that contains
the objects as defined in the manifest for the specific host. In this stage,
no conflicts may occur, i.e. no object of the same type with the same id may
be created.
be created, if it has different parameters.
STAGE 3: OBJECT INFORMATION RETRIEVAL
@ -44,7 +44,7 @@ Every object is checked whether its type has a executable manifest. The
manifest script may generate and change the created objects. In other words,
one type can reuse other types.
For instance the object __apache/www.test.ch is of type __apache, which may
For instance the object __apache/www.example.org is of type __apache, which may
contain a manifest script, which creates new objects of type __file.
The newly created objects are merged back into the existing tree. No conflicts

View file

@ -139,8 +139,8 @@ Always ensure the manifest is executable, otherwise cdist will not be able
to execute it. For more information about manifests see cdist-manifest(7).
SINGLETON - ONLY INSTANCE ONLY
------------------------------
SINGLETON - ONE INSTANCE ONLY
-----------------------------
If you want to ensure that a type can only be used once per target, you can
mark it as a singleton: Just create the (empty) file "singleton" in your type
directory:
@ -186,10 +186,8 @@ WRITING THE GENCODE SCRIPT
There are two gencode scripts: ***gencode-local*** and ***gencode-remote***.
The output of gencode-local is executed locally, whereas
the output of gencode-remote is executed on the target.
The gencode scripts can make use of the parameters, the global explorers
and the type specific explorers. The output (stdout) of these script is
saved by cdist and will be executed on the target.
and the type specific explorers.
If the gencode scripts encounter an error, it should print diagnostic
messages to stderr and exit non-zero. If you need to debug the gencode
@ -224,17 +222,13 @@ never ever touch this folder).
HOW TO INCLUDE A TYPE INTO UPSTREAM CDIST
-----------------------------------------
If you think your type may be useful for others, ensure it works with the
current master branch of cdist and submit the git url containing the type for
inclusion to the mailinglist **cdist at cdist -- at -- l.schottelius.org**
or open a pull request at http://github.com/telmich/cdist.
Ensure a corresponding manpage named man.text in asciidoc format with
the manpage-name "cdist-type__NAME" is included in the type directory.
current master branch of cdist and have a look at cdist-hacker(7) on
how to submit it.
SEE ALSO
--------
- cdist-explorer(7)
- cdist-hacker(7)
- cdist-stages(7)
- cdist-tutorial(7)

View file

@ -1,6 +1,6 @@
# -*- coding: utf-8 -*-
#
# 2010-2011 Nico Schottelius (nico-cdist at schottelius.org)
# 2010-2012 Nico Schottelius (nico-cdist at schottelius.org)
#
# This file is part of cdist.
#
@ -19,7 +19,7 @@
#
#
VERSION = "2.0.8"
VERSION = "2.0.9"
BANNER = """
.. . .x+=:. s

View file

@ -1,6 +1,6 @@
# -*- coding: utf-8 -*-
#
# 2011 Nico Schottelius (nico-cdist at schottelius.org)
# 2011-2012 Nico Schottelius (nico-cdist at schottelius.org)
#
# This file is part of cdist.
#

View file

@ -77,7 +77,12 @@ class Remote(object):
self.log.debug("Remote transfer: %s -> %s", source, destination)
self.rmdir(destination)
command = self._copy.split()
command.extend(["-r", source, self.target_host + ":" + destination])
# support rsync by appending a "/" to the source if it's a directory
if os.path.isdir(source):
command.extend(["-r", source + "/", self.target_host + ":" + destination])
else:
command.extend(["-r", source, self.target_host + ":" + destination])
self._run_command(command)
def run_script(self, script, env=None, return_output=False):

View file

@ -0,0 +1,30 @@
#!/bin/sh
#
# 2012 Matt Coddington (mcoddington at gmail.com)
#
# This file is part of cdist.
#
# cdist is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# cdist is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with cdist. If not, see <http://www.gnu.org/licenses/>.
#
#
# Use rsync over ssh to copy files. This particular invocation of
# rsync makes a backup of the file before overwriting it. For example,
# if cdist overwrites /etc/passwd then you'll end up with the old copy
# at /etc/passwd~cdist.
#
# Usage:
# __remote_copy="/path/to/this/script" cdist config target_host
#
rsync --backup --suffix=~cdist -e 'ssh -o User=root' $@

View file

@ -2,6 +2,7 @@ Description:
Type that will probably only work in a very specific environnment
(like a specific distribution only).
or has custom code that may not satisfy the "usual" or generic use case.
Problem:

View file

@ -0,0 +1 @@
../.readmes/README.inclusion.specific

View file

@ -0,0 +1 @@
[client]

View file

@ -0,0 +1,93 @@
#!/bin/sh
#
# 2012 Benedikt Koeppel (code@benediktkoeppel.ch)
#
# This file is part of cdist.
#
# cdist is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# cdist is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with cdist. If not, see <http://www.gnu.org/licenses/>.
#
#
if [ -f "$__object/parameter/no_my_cnf" ]; then
no_my_cnf="$(cat "$__object/parameter/no_my_cnf")"
else
no_my_cnf="false"
fi
if [ -f "$__object/parameter/password" ]; then
rootpassword="$(cat "$__object/parameter/password")"
else
rootpassword=""
fi
if [ "$rootpassword" != "" ]; then
# to the database without requiring a passwort input
# set root password
echo "mysqladmin -u root password $rootpassword"
# if we don't want to overwrite the .my.cnf, then take a backup now
if [ "$no_my_cnf" == "true" ]; then
mv /root/.my.cnf /root/.my.cnf.cdist.bkp
fi
# store the root password in /root/.my.cnf so that processes can connect
cat <<-EOFF
cat <<-EOF > /root/.my.cnf
[client]
password=$rootpassword
EOF
EOFF
# remove anonymous users
cat <<-EOFF
mysql -u root <<-EOF
DELETE FROM mysql.user WHERE User='';
EOF
EOFF
# remove remote-access for root
cat <<-EOFF
mysql -u root <<-EOF
DELETE FROM mysql.user WHERE User='root' AND Host!='localhost';
EOF
EOFF
# remove test database
cat <<-EOFF
mysql -u root <<-EOF
DROP DATABASE IF EXISTS test;
EOF
EOFF
cat <<-EOFF
mysql -u root <<-EOF
DELETE FROM mysql.db WHERE Db='test' OR Db='test\_%'
EOF
EOFF
# flush privileges
cat <<-EOFF
mysql -u root <<-EOF
FLUSH PRIVILEGES;
EOF
EOFF
# if we don't want to overwrite the .my.cnf, then restore the backup now
if [ "$no_my_cnf" == "true" ]; then
mv /root/.my.cnf.cdist.bkp /root/.my.cnf
fi
fi

View file

@ -0,0 +1,60 @@
cdist-type__mysql_server(7)
===========================
Benedikt Koeppel <code@benediktkoeppel.ch>
NAME
----
cdist-type__mysql_server - Manage a MySQL server
DESCRIPTION
-----------
This cdist type allows you to install a MySQL database server. The
__mysql_server type also takes care of a few basic security tweaks that are
normally done by running the mysql_secure_installation script that is provided
with MySQL.
REQUIRED PARAMETERS
-------------------
password::
The root password to set.
OPTIONAL PARAMETERS
-------------------
no_my_cnf::
The /root/.my.cnf file is used to temporary store the root password when doing
the mysql_secure_installation. If you want to have your own .my.cnf file, then
specify --no_my_cnf "true".
Cdist will then place your original /root/.my.cnf back once cdist has run.
EXAMPLES
--------
--------------------------------------------------------------------------------
# to install a MySQL server
__mysql_server
# to install a MySQL server, remove remote access, remove test databases
# similar to mysql_secure_installation, specify the root password
__mysql_server --password "Uu9jooKe"
# this will also write a /root/.my.cnf file
# if you don't want cdist to write a /root/.my.cnf file permanently, specify
# the --no_my_cnf option
__mysql_server --password "Uu9jooKe" --no_my_cnf
--------------------------------------------------------------------------------
SEE ALSO
--------
- cdist-type(7)
COPYING
-------
Copyright \(C) 2012 Benedikt Koeppel. Free use of this software is
granted under the terms of the GNU General Public License version 3 (GPLv3).

View file

@ -0,0 +1,41 @@
#!/bin/sh
#
# 2012 Benedikt Koeppel (code@benediktkoeppel.ch)
#
# This file is part of cdist.
#
# cdist is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# cdist is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with cdist. If not, see <http://www.gnu.org/licenses/>.
#
#
# install mysql-server
__package mysql-server --state installed
if [ -f "$__object/parameter/no_my_cnf" ]; then
no_my_cnf="$(cat "$__object/parameter/no_my_cnf")"
else
no_my_cnf="false"
fi
if [ -f "$__object/parameter/password" ]; then
rootpassword="$(cat "$__object/parameter/password")"
else
rootpassword=""
fi
if [ "$no_my_cnf" != "true" -a "$rootpassword" != "" ]; then
# store the root password in /root/.my.cnf so that processes can connect
# to the database without requiring a passwort input
__file "/root/.my.cnf" --group root --owner root --mode 600
fi

View file

@ -0,0 +1,2 @@
no_my_cnf
password