This commit is contained in:
Jake Guffey 2012-03-12 16:44:25 -04:00
commit 33cb887acf
30 changed files with 540 additions and 127 deletions

122
bin/cdist
View file

@ -1,7 +1,7 @@
#!/usr/bin/env python3 #!/usr/bin/env python3
# -*- coding: utf-8 -*- # -*- 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. # This file is part of cdist.
# #
@ -108,55 +108,48 @@ def configinstall(args, mode):
if args.manifest == '-': if args.manifest == '-':
# read initial manifest from stdin # read initial manifest from stdin
import tempfile import tempfile
handle, initial_manifest_temp_path = tempfile.mkstemp(prefix='cdist.stdin.') try:
with os.fdopen(handle, 'w') as fd: handle, initial_manifest_temp_path = tempfile.mkstemp(prefix='cdist.stdin.')
fd.write(sys.stdin.read()) 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 args.manifest = initial_manifest_temp_path
import atexit import atexit
atexit.register(lambda: os.remove(initial_manifest_temp_path)) atexit.register(lambda: os.remove(initial_manifest_temp_path))
try: process = {}
process = {} failed_hosts = []
failed_hosts = [] time_start = time.time()
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)
for host in args.host:
if args.parallel: if args.parallel:
for p in process.keys(): log.debug("Creating child process for %s", host)
log.debug("Joining process %s", p) process[host] = multiprocessing.Process(target=configinstall_onehost, args=(host, args, mode, True))
process[p].join() 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: # Catch errors in parallel mode when joining
failed_hosts.append(p) if args.parallel:
for host in process.keys():
log.debug("Joining process %s", host)
process[host].join()
if len(failed_hosts) > 0: if not process[host].exitcode == 0:
log.warn("Failed to deploy to the following hosts: " + failed_hosts.append(host)
" ".join(failed_hosts))
time_end = time.time() time_end = time.time()
log.info("Total processing time for %s host(s): %s", len(args.host), log.info("Total processing time for %s host(s): %s", len(args.host),
(time_end - time_start)) (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)
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): def configinstall_onehost(host, args, mode, parallel):
"""Configure or install ONE remote system""" """Configure or install ONE remote system"""
@ -176,33 +169,33 @@ def configinstall_onehost(host, args, mode, parallel):
context.cleanup() context.cleanup()
except cdist.Error as e: except cdist.Error as e:
log.error(e) # We are running in our own process here, need to sys.exit!
return False if parallel:
except KeyboardInterrupt: log.error(e)
# Do not care in sequential mode, catch in parallel mode sys.exit(1)
if not parallel:
raise
else: else:
# Catch here, above does not need to know about our errors raise
return False
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(): def emulator():
"""Prepare and run emulator""" """Prepare and run emulator"""
try: import cdist.emulator
import cdist.emulator emulator = cdist.emulator.Emulator(sys.argv)
emulator = cdist.emulator.Emulator(sys.argv) return emulator.run()
emulator.run()
except cdist.Error as e:
log.error(e)
sys.exit(1)
if __name__ == "__main__": if __name__ == "__main__":
# Sys is needed for sys.exit() # Sys is needed for sys.exit()
import sys import sys
exit_code = 0
try: try:
import logging import logging
import os import os
@ -210,9 +203,8 @@ if __name__ == "__main__":
cdistpythonversion = '3.2' cdistpythonversion = '3.2'
if sys.version < cdistpythonversion: if sys.version < cdistpythonversion:
print('Cdist requires Python >= ' + cdistpythonversion + raise cdist.Error('Cdist requires Python >= ' + cdistpythonversion +
' on the source host.') ' on the source host.')
sys.exit(1)
# Ensure our /lib/ is included into PYTHON_PATH # Ensure our /lib/ is included into PYTHON_PATH
sys.path.insert(0, os.path.abspath( sys.path.insert(0, os.path.abspath(
@ -230,7 +222,13 @@ if __name__ == "__main__":
else: else:
commandline() commandline()
sys.exit(0)
except KeyboardInterrupt: 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 * See crontab(5). Defaults to *
day_of_week:: day_of_week::
See crontab(5). Defaults to * 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 EXAMPLES
-------- --------
-------------------------------------------------------------------------------- --------------------------------------------------------------------------------
# add cronjob # run Monday to Saturday at 23:15
__cron some-id --user root --command "/path/to/script" __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 # remove cronjob
__cron some-id --user root --command "/path/to/script" --state absent __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")" command="$(cat "$__object/parameter/command")"
# set defaults # set defaults
if [ ! -f "$__object/parameter/state" ]; then test -f "$__object/parameter/state" || echo "present" > "$__object/parameter/state"
echo "present" > "$__object/parameter/state"
fi if [ -f "$__object/parameter/raw" ]; then
if [ -f "$__object/parameter/minute" ]; then raw="$(cat "$__object/parameter/raw")"
minute="$(cat "$__object/parameter/minute")" entry="$raw $command"
else else
minute="*" minute="$(cat "$__object/parameter/minute" 2>/dev/null || echo "*")"
echo "$minute" > "$__object/parameter/minute" hour="$(cat "$__object/parameter/hour" 2>/dev/null || echo "*")"
fi day_of_month="$(cat "$__object/parameter/day_of_month" 2>/dev/null || echo "*")"
if [ -f "$__object/parameter/hour" ]; then month="$(cat "$__object/parameter/month" 2>/dev/null || echo "*")"
hour="$(cat "$__object/parameter/hour")" day_of_week="$(cat "$__object/parameter/day_of_week" 2>/dev/null || echo "*")"
else entry="$minute $hour $day_of_month $month $day_of_week $command"
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"
fi fi
# NOTE: if changed, also change in explorers # NOTE: if changed, also change in explorers
prefix="#cdist:__cron/$name" prefix="#cdist:__cron/$name"
suffix="#/cdist:__cron/$name" suffix="#/cdist:__cron/$name"
echo "$prefix" | tee "$__object/parameter/prefix" > "$__object/parameter/entry" 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" echo "$suffix" | tee "$__object/parameter/suffix" >> "$__object/parameter/entry"

View file

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

View file

@ -22,6 +22,15 @@
# #
name=$__object_id 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" name="$__object_id"
os_version="$(cat "$__global/explorer/os_version")"
cd "$__object/parameter" cd "$__object/parameter"
if grep -q "^${name}:" "$__object/explorer/group"; then if grep -q "^${name}:" "$__object/explorer/group"; then
for property in $(ls .); do for property in $(ls .); do
new_value="$(cat "$property")" 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 case "$property" in
password) password)
current_value="$(awk -F: '{ print $2 }' < "$__object/explorer/gshadow")" 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) gid)
# set to -g to support older redhat/centos
proparg="-g"
current_value="$(awk -F: '{ print $3 }' < "$__object/explorer/group")" current_value="$(awk -F: '{ print $3 }' < "$__object/explorer/group")"
;; ;;
esac esac
if [ "$new_value" != "$current_value" ]; then if [ "$new_value" != "$current_value" ]; then
set -- "$@" "--$property" \"$new_value\" set -- "$@" "$proparg" \"$new_value\"
fi fi
done 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

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

View file

@ -47,6 +47,13 @@ case "$state_should" in
echo chkconfig \"$name\" on 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 echo "Unsupported os: $os" >&2
exit 1 exit 1
@ -74,6 +81,10 @@ case "$state_should" in
echo chkconfig \"$name\" off echo chkconfig \"$name\" off
;; ;;
openwrt)
echo "\"/etc/init.d/$name\" disable"
;;
*) *)
echo "Unsupported os: $os" >&2 echo "Unsupported os: $os" >&2
exit 1 exit 1

View file

@ -4,12 +4,23 @@ Changelog
* Changes are always commented with their author in (braces) * Changes are always commented with their author in (braces)
* Exception: No braces means author == Nico Schottelius * 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 * Cleanup documentation: Fix environment variable list to be properly
displayed (Giel van Schijndel) displayed (Giel van Schijndel)
* Cleanup documentation: Some minor corrections
* New Type: __package_opkg (Giel van Schijndel) * New Type: __package_opkg (Giel van Schijndel)
* New Type: __package_pkg_freebsd (Jake Guffey) * 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 2.0.8: 2012-02-20
* Bugfix core: Remove another nasty traceback when sending SIGINT (aka Ctrl-C) * Bugfix core: Remove another nasty traceback when sending SIGINT (aka Ctrl-C)

View file

@ -90,10 +90,20 @@ TMPDIR, TEMP, TMP::
more information. This is rather useful, if the standard more information. This is rather useful, if the standard
directory used does not allow executables. 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 SEE ALSO
-------- --------
- cdist(7) - cdist(7)
- cdist-type-emulator(1)
- cdist-reference(7) - cdist-reference(7)

View file

@ -153,6 +153,40 @@ implement this scenario with a gateway host and sudo:
For more details consult sudoers(5) 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 SEE ALSO
-------- --------
- cdist(1) - 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 seperate branches. This way one feature can already be included, even if
the other needs to be improved. the other needs to be improved.
As soon as your work meets these requirements, you can contact me As soon as your work meets these requirements, write a mail
(IRC, Mailinglist, Phone, RFC 1149) and I'll check your code before for inclusion to the mailinglist **cdist at cdist -- at -- l.schottelius.org**
including it. or open a pull request at http://github.com/telmich/cdist.
HOW TO SUBMIT A NEW TYPE 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. core cdist already.
SEE ALSO SEE ALSO
-------- --------
- cdist(7) - 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 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, 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 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 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, manifest script may generate and change the created objects. In other words,
one type can reuse other types. 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. contain a manifest script, which creates new objects of type __file.
The newly created objects are merged back into the existing tree. No conflicts 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). 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 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 mark it as a singleton: Just create the (empty) file "singleton" in your type
directory: directory:
@ -186,10 +186,8 @@ WRITING THE GENCODE SCRIPT
There are two gencode scripts: ***gencode-local*** and ***gencode-remote***. There are two gencode scripts: ***gencode-local*** and ***gencode-remote***.
The output of gencode-local is executed locally, whereas The output of gencode-local is executed locally, whereas
the output of gencode-remote is executed on the target. the output of gencode-remote is executed on the target.
The gencode scripts can make use of the parameters, the global explorers The gencode scripts can make use of the parameters, the global explorers
and the type specific explorers. The output (stdout) of these script is and the type specific explorers.
saved by cdist and will be executed on the target.
If the gencode scripts encounter an error, it should print diagnostic 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 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 HOW TO INCLUDE A TYPE INTO UPSTREAM CDIST
----------------------------------------- -----------------------------------------
If you think your type may be useful for others, ensure it works with the 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 current master branch of cdist and have a look at cdist-hacker(7) on
inclusion to the mailinglist **cdist at cdist -- at -- l.schottelius.org** how to submit it.
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.
SEE ALSO SEE ALSO
-------- --------
- cdist-explorer(7) - cdist-explorer(7)
- cdist-hacker(7)
- cdist-stages(7) - cdist-stages(7)
- cdist-tutorial(7) - cdist-tutorial(7)

View file

@ -1,6 +1,6 @@
# -*- coding: utf-8 -*- # -*- 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. # This file is part of cdist.
# #
@ -19,7 +19,7 @@
# #
# #
VERSION = "2.0.8" VERSION = "2.0.9"
BANNER = """ BANNER = """
.. . .x+=:. s .. . .x+=:. s

View file

@ -1,6 +1,6 @@
# -*- coding: utf-8 -*- # -*- 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. # 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.log.debug("Remote transfer: %s -> %s", source, destination)
self.rmdir(destination) self.rmdir(destination)
command = self._copy.split() 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) self._run_command(command)
def run_script(self, script, env=None, return_output=False): 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 Type that will probably only work in a very specific environnment
(like a specific distribution only). (like a specific distribution only).
or has custom code that may not satisfy the "usual" or generic use case.
Problem: 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