diff --git a/bin/cdist b/bin/cdist index 5456b134..c6467477 100755 --- a/bin/cdist +++ b/bin/cdist @@ -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) diff --git a/conf/type/__cron/man.text b/conf/type/__cron/man.text index c4852b7f..47f47456 100644 --- a/conf/type/__cron/man.text +++ b/conf/type/__cron/man.text @@ -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 diff --git a/conf/type/__cron/manifest b/conf/type/__cron/manifest index 01c4358c..7aca41ff 100755 --- a/conf/type/__cron/manifest +++ b/conf/type/__cron/manifest @@ -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" - diff --git a/conf/type/__cron/parameter/optional b/conf/type/__cron/parameter/optional index 1a4aae3d..517d821e 100644 --- a/conf/type/__cron/parameter/optional +++ b/conf/type/__cron/parameter/optional @@ -4,3 +4,4 @@ hour day_of_month month day_of_week +raw diff --git a/conf/type/__group/explorer/gshadow b/conf/type/__group/explorer/gshadow index 51d502a1..e3c2dd6c 100755 --- a/conf/type/__group/explorer/gshadow +++ b/conf/type/__group/explorer/gshadow @@ -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 diff --git a/conf/type/__group/gencode-remote b/conf/type/__group/gencode-remote index cf26a437..2b4774ab 100755 --- a/conf/type/__group/gencode-remote +++ b/conf/type/__group/gencode-remote @@ -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 diff --git a/conf/type/__mysql_database/gencode-remote b/conf/type/__mysql_database/gencode-remote new file mode 100755 index 00000000..7cd32242 --- /dev/null +++ b/conf/type/__mysql_database/gencode-remote @@ -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 . +# +# + +# 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 diff --git a/conf/type/__mysql_database/man.text b/conf/type/__mysql_database/man.text new file mode 100644 index 00000000..f184a30e --- /dev/null +++ b/conf/type/__mysql_database/man.text @@ -0,0 +1,49 @@ +cdist-type__mysql_database(7) +============================= +Benedikt Koeppel + + +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). diff --git a/conf/type/__mysql_database/parameter/optional b/conf/type/__mysql_database/parameter/optional new file mode 100644 index 00000000..756afee7 --- /dev/null +++ b/conf/type/__mysql_database/parameter/optional @@ -0,0 +1,3 @@ +name +user +password diff --git a/conf/type/__start_on_boot/explorer/state b/conf/type/__start_on_boot/explorer/state index ff092a65..bf24738a 100755 --- a/conf/type/__start_on_boot/explorer/state +++ b/conf/type/__start_on_boot/explorer/state @@ -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" ;; diff --git a/conf/type/__start_on_boot/gencode-remote b/conf/type/__start_on_boot/gencode-remote index be2bd98b..cefdc385 100755 --- a/conf/type/__start_on_boot/gencode-remote +++ b/conf/type/__start_on_boot/gencode-remote @@ -47,6 +47,13 @@ case "$state_should" in 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 diff --git a/doc/changelog b/doc/changelog index dc498b9e..ce9f798b 100644 --- a/doc/changelog +++ b/doc/changelog @@ -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) diff --git a/doc/man/man1/cdist.text b/doc/man/man1/cdist.text index 99c28f8b..e46e84a3 100644 --- a/doc/man/man1/cdist.text +++ b/doc/man/man1/cdist.text @@ -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) diff --git a/doc/man/man7/cdist-best-practice.text b/doc/man/man7/cdist-best-practice.text index bbfd084a..a8851f7f 100644 --- a/doc/man/man7/cdist-best-practice.text +++ b/doc/man/man7/cdist-best-practice.text @@ -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) diff --git a/doc/man/man7/cdist-hacker.text b/doc/man/man7/cdist-hacker.text index 646439a3..ee88ca29 100644 --- a/doc/man/man7/cdist-hacker.text +++ b/doc/man/man7/cdist-hacker.text @@ -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) diff --git a/doc/man/man7/cdist-stages.text b/doc/man/man7/cdist-stages.text index c1b73a8d..fa5e28d1 100644 --- a/doc/man/man7/cdist-stages.text +++ b/doc/man/man7/cdist-stages.text @@ -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 diff --git a/doc/man/man7/cdist-type.text b/doc/man/man7/cdist-type.text index 1147511e..92a2b36d 100644 --- a/doc/man/man7/cdist-type.text +++ b/doc/man/man7/cdist-type.text @@ -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) diff --git a/lib/cdist/__init__.py b/lib/cdist/__init__.py index c1e16ffb..bd8e6483 100644 --- a/lib/cdist/__init__.py +++ b/lib/cdist/__init__.py @@ -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 diff --git a/lib/cdist/banner.py b/lib/cdist/banner.py index 4148fa72..edfa72e8 100644 --- a/lib/cdist/banner.py +++ b/lib/cdist/banner.py @@ -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. # diff --git a/lib/cdist/exec/remote.py b/lib/cdist/exec/remote.py index 124c1b4f..11b8c78e 100644 --- a/lib/cdist/exec/remote.py +++ b/lib/cdist/exec/remote.py @@ -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): diff --git a/other/examples/remote/rsync/copy b/other/examples/remote/rsync/copy new file mode 100755 index 00000000..f6b93c5c --- /dev/null +++ b/other/examples/remote/rsync/copy @@ -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 . +# +# +# 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' $@ diff --git a/other/types_submitted_for_inclusion/.readmes/README.inclusion.specific b/other/types_submitted_for_inclusion/.readmes/README.inclusion.specific index 0a1eb22e..3afdb7b4 100644 --- a/other/types_submitted_for_inclusion/.readmes/README.inclusion.specific +++ b/other/types_submitted_for_inclusion/.readmes/README.inclusion.specific @@ -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: diff --git a/other/types_submitted_for_inclusion/__mysql_server/README.inclusion b/other/types_submitted_for_inclusion/__mysql_server/README.inclusion new file mode 120000 index 00000000..573e1f5f --- /dev/null +++ b/other/types_submitted_for_inclusion/__mysql_server/README.inclusion @@ -0,0 +1 @@ +../.readmes/README.inclusion.specific \ No newline at end of file diff --git a/other/types_submitted_for_inclusion/__mysql_server/files/my.cnf b/other/types_submitted_for_inclusion/__mysql_server/files/my.cnf new file mode 100644 index 00000000..bd651c46 --- /dev/null +++ b/other/types_submitted_for_inclusion/__mysql_server/files/my.cnf @@ -0,0 +1 @@ +[client] diff --git a/other/types_submitted_for_inclusion/__mysql_server/gencode-remote b/other/types_submitted_for_inclusion/__mysql_server/gencode-remote new file mode 100755 index 00000000..4c160671 --- /dev/null +++ b/other/types_submitted_for_inclusion/__mysql_server/gencode-remote @@ -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 . +# +# + +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 diff --git a/other/types_submitted_for_inclusion/__mysql_server/man.text b/other/types_submitted_for_inclusion/__mysql_server/man.text new file mode 100644 index 00000000..f8573051 --- /dev/null +++ b/other/types_submitted_for_inclusion/__mysql_server/man.text @@ -0,0 +1,60 @@ +cdist-type__mysql_server(7) +=========================== +Benedikt Koeppel + + +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). diff --git a/other/types_submitted_for_inclusion/__mysql_server/manifest b/other/types_submitted_for_inclusion/__mysql_server/manifest new file mode 100755 index 00000000..ce331998 --- /dev/null +++ b/other/types_submitted_for_inclusion/__mysql_server/manifest @@ -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 . +# +# + +# 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 diff --git a/other/types_submitted_for_inclusion/__mysql_server/parameter/optional b/other/types_submitted_for_inclusion/__mysql_server/parameter/optional new file mode 100644 index 00000000..4c40596c --- /dev/null +++ b/other/types_submitted_for_inclusion/__mysql_server/parameter/optional @@ -0,0 +1,2 @@ +no_my_cnf +password diff --git a/other/types_submitted_for_inclusion/__mysql_server/parameter/required b/other/types_submitted_for_inclusion/__mysql_server/parameter/required new file mode 100644 index 00000000..e69de29b diff --git a/other/types_submitted_for_inclusion/__mysql_server/singleton b/other/types_submitted_for_inclusion/__mysql_server/singleton new file mode 100644 index 00000000..e69de29b