From ddebf5b1537e6c3203383927a80390dbb4b14868 Mon Sep 17 00:00:00 2001 From: Nico Schottelius Date: Thu, 3 Nov 2011 10:37:10 +0100 Subject: [PATCH 01/20] __cron for 2.0.4 Signed-off-by: Nico Schottelius --- doc/changelog | 1 + 1 file changed, 1 insertion(+) diff --git a/doc/changelog b/doc/changelog index aad067b7..7217a6f2 100644 --- a/doc/changelog +++ b/doc/changelog @@ -3,6 +3,7 @@ * Cleanup: __object_fq variable removed (never used) * Cleanup: Environment variable __self DEPRECATED, use __object_name instead * Cleanup: Environment variable __self scheduled for removal in cdist 2.1 + * New Type: __cron (Steven Armstrong) 2.0.3: 2011-10-18 * Improved logging, added --verbose, by more quiet by default From efedfbf47c2cd184d8827c050ba23ffb4b5cb227 Mon Sep 17 00:00:00 2001 From: Steven Armstrong Date: Thu, 3 Nov 2011 15:44:12 +0100 Subject: [PATCH 02/20] test for singleton requirement Signed-off-by: Steven Armstrong --- lib/cdist/test/emulator/__init__.py | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/lib/cdist/test/emulator/__init__.py b/lib/cdist/test/emulator/__init__.py index 91150334..8f1b9776 100644 --- a/lib/cdist/test/emulator/__init__.py +++ b/lib/cdist/test/emulator/__init__.py @@ -73,3 +73,18 @@ class EmulatorTestCase(test.CdistTestCase): os.environ['require'] = '__file/bad/id/with/.cdist/inside' emu = emulator.Emulator(argv) self.assertRaises(core.IllegalObjectIdError, emu.run) + + def test_missing_object_id_requirement(self): + argv = ['__file', '/tmp/foobar'] + os.environ.update(self.env) + os.environ['require'] = '__file' + emu = emulator.Emulator(argv) + self.assertRaises(emulator.IllegalRequirementError, emu.run) + + def test_singleton_object_requirement(self): + argv = ['__file', '/tmp/foobar'] + os.environ.update(self.env) + os.environ['require'] = '__issue' + emu = emulator.Emulator(argv) + emu.run() + # if we get here all is fine From d0123acc2a6f7f2db05f25b4e63abce2f22a8649 Mon Sep 17 00:00:00 2001 From: Steven Armstrong Date: Thu, 3 Nov 2011 15:44:51 +0100 Subject: [PATCH 03/20] implement singleton as requirement Signed-off-by: Steven Armstrong --- lib/cdist/emulator.py | 21 ++++++++++++--------- 1 file changed, 12 insertions(+), 9 deletions(-) diff --git a/lib/cdist/emulator.py b/lib/cdist/emulator.py index 4880c6e6..7ae89294 100644 --- a/lib/cdist/emulator.py +++ b/lib/cdist/emulator.py @@ -156,19 +156,22 @@ class Emulator(object): self.log.debug("Recording requirement: " + requirement) requirement_parts = requirement.split(os.sep, 1) requirement_type_name = requirement_parts[0] - requirement_object_id = requirement_parts[1] - - # FIXME: Add support for omitted object id == singleton - #if len(requirement_parts) == 1: - #except IndexError: - # # no object id, must be singleton - # requirement_object_id = 'singleton' - - # Remove / if existent in object id + try: + requirement_object_id = requirement_parts[1] + except IndexError: + # no object id, assume singleton + requirement_object_id = 'singleton' + + # Remove leading / from object id requirement_object_id = requirement_object_id.lstrip('/') # Instantiate type which fails if type does not exist requirement_type = core.Type(self.type_base_path, requirement_type_name) + + if requirement_object_id == 'singleton' \ + and not requirement_type.is_singleton: + raise IllegalRequirementError(requirement, "Missing object_id and type is not a singleton.") + # Instantiate object which fails if the object_id is illegal requirement_object = core.Object(requirement_type, self.object_base_path, requirement_object_id) From 360a03a34940b59fdf2fa449f184f225d059a6fd Mon Sep 17 00:00:00 2001 From: Steven Armstrong Date: Thu, 3 Nov 2011 17:21:14 +0100 Subject: [PATCH 04/20] add examples for __remote_{copy,exec} scripts Signed-off-by: Steven Armstrong --- other/examples/remote/README | 2 ++ other/examples/remote/chroot/copy | 28 +++++++++++++++++++++++++ other/examples/remote/chroot/exec | 35 +++++++++++++++++++++++++++++++ other/examples/remote/ssh/copy | 10 +++++++++ other/examples/remote/ssh/exec | 10 +++++++++ 5 files changed, 85 insertions(+) create mode 100644 other/examples/remote/README create mode 100755 other/examples/remote/chroot/copy create mode 100755 other/examples/remote/chroot/exec create mode 100755 other/examples/remote/ssh/copy create mode 100755 other/examples/remote/ssh/exec diff --git a/other/examples/remote/README b/other/examples/remote/README new file mode 100644 index 00000000..288fc293 --- /dev/null +++ b/other/examples/remote/README @@ -0,0 +1,2 @@ +Some examples of using alternative __remote_copy and __remote_exec prefixes. +This allows you to change how cdist interacts with the target host (or directory, or whatever :-) diff --git a/other/examples/remote/chroot/copy b/other/examples/remote/chroot/copy new file mode 100755 index 00000000..eb284ced --- /dev/null +++ b/other/examples/remote/chroot/copy @@ -0,0 +1,28 @@ +#!/bin/sh +# +# __remote_copy script to run cdist against a local chroot instead of via ssh +# to a remote target host. +# +# Usage: +# __remote_copy="/path/to/this/script /path/to/your/chroot" cdist config target-id +# + +log() { + #echo "$@" | logger -t "cdist-chroot-copy" + : +} + +chroot="$1"; shift +target_host="$__target_host" + +# replace target_host with chroot location +code="$(echo "$@" | sed "s|$target_host:|$chroot|g")" + +log "$@" +log "target_host: $target_host" +log "$code" + +# copy files into chroot +cp $code + +log "-----" diff --git a/other/examples/remote/chroot/exec b/other/examples/remote/chroot/exec new file mode 100755 index 00000000..21efe421 --- /dev/null +++ b/other/examples/remote/chroot/exec @@ -0,0 +1,35 @@ +#!/bin/sh +# +# __remote_exec script to run cdist against a local chroot instead of via ssh +# on a remote target host. +# +# Usage: +# __remote_exec="/path/to/this/script /path/to/your/chroot" cdist config target-id +# + +log() { + #echo "$@" | logger -t "cdist-chroot-exec" + : +} + +chroot="$1"; shift +target_host="$1"; shift +script=$(mktemp "${chroot}/tmp/chroot-${0##*/}.XXXXXXXXXX") +trap cleanup INT TERM EXIT +cleanup() { + [ $__cdist_debug ] || rm "$script" +} + +log "$script" +log "$@" +echo "#!/bin/sh -l" > "$script" +echo "$@" >> "$script" +chmod +x "$script" + +relative_script="${script#$chroot}" +log "relative_script: $relative_script" + +# run in chroot +chroot "$chroot" "$relative_script" + +log "-----" diff --git a/other/examples/remote/ssh/copy b/other/examples/remote/ssh/copy new file mode 100755 index 00000000..76c0b2c8 --- /dev/null +++ b/other/examples/remote/ssh/copy @@ -0,0 +1,10 @@ +#!/bin/sh +# +# same as cdist default +# +# Usage: +# __remote_copy="/path/to/this/script" cdist config target_host +# + +#echo "$@" | logger -t "cdist-ssh-copy" +scp -o User=root -q $@ diff --git a/other/examples/remote/ssh/exec b/other/examples/remote/ssh/exec new file mode 100755 index 00000000..63994973 --- /dev/null +++ b/other/examples/remote/ssh/exec @@ -0,0 +1,10 @@ +#!/bin/sh +# +# same as cdist default +# +# Usage: +# __remote_exec="/path/to/this/script" cdist config target_host +# + +#echo "$@" | logger -t "cdist-ssh-exec" +ssh -o User=root -q $@ From f864d307be95aec568a05a401784822ae21923e6 Mon Sep 17 00:00:00 2001 From: Steven Armstrong Date: Thu, 3 Nov 2011 22:35:06 +0100 Subject: [PATCH 05/20] +licence, +logging Signed-off-by: Steven Armstrong --- other/examples/remote/chroot/copy | 21 ++++++++++++++++++++- other/examples/remote/chroot/exec | 24 ++++++++++++++++++++++-- other/examples/remote/ssh/copy | 18 ++++++++++++++++++ other/examples/remote/ssh/exec | 18 ++++++++++++++++++ 4 files changed, 78 insertions(+), 3 deletions(-) diff --git a/other/examples/remote/chroot/copy b/other/examples/remote/chroot/copy index eb284ced..528a5faf 100755 --- a/other/examples/remote/chroot/copy +++ b/other/examples/remote/chroot/copy @@ -1,5 +1,23 @@ #!/bin/sh # +# 2011 Steven Armstrong (steven-cdist at armstrong.cc) +# +# 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 . +# +# # __remote_copy script to run cdist against a local chroot instead of via ssh # to a remote target host. # @@ -18,8 +36,9 @@ target_host="$__target_host" # replace target_host with chroot location code="$(echo "$@" | sed "s|$target_host:|$chroot|g")" -log "$@" log "target_host: $target_host" +log "chroot: $chroot" +log "$@" log "$code" # copy files into chroot diff --git a/other/examples/remote/chroot/exec b/other/examples/remote/chroot/exec index 21efe421..19e76b0e 100755 --- a/other/examples/remote/chroot/exec +++ b/other/examples/remote/chroot/exec @@ -1,5 +1,23 @@ #!/bin/sh # +# 2011 Steven Armstrong (steven-cdist at armstrong.cc) +# +# 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 . +# +# # __remote_exec script to run cdist against a local chroot instead of via ssh # on a remote target host. # @@ -14,14 +32,16 @@ log() { chroot="$1"; shift target_host="$1"; shift + script=$(mktemp "${chroot}/tmp/chroot-${0##*/}.XXXXXXXXXX") trap cleanup INT TERM EXIT cleanup() { [ $__cdist_debug ] || rm "$script" } -log "$script" -log "$@" +log "target_host: $target_host" +log "script: $script" +log "@: $@" echo "#!/bin/sh -l" > "$script" echo "$@" >> "$script" chmod +x "$script" diff --git a/other/examples/remote/ssh/copy b/other/examples/remote/ssh/copy index 76c0b2c8..0ecd8c52 100755 --- a/other/examples/remote/ssh/copy +++ b/other/examples/remote/ssh/copy @@ -1,5 +1,23 @@ #!/bin/sh # +# 2011 Steven Armstrong (steven-cdist at armstrong.cc) +# +# 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 . +# +# # same as cdist default # # Usage: diff --git a/other/examples/remote/ssh/exec b/other/examples/remote/ssh/exec index 63994973..b597a47f 100755 --- a/other/examples/remote/ssh/exec +++ b/other/examples/remote/ssh/exec @@ -1,5 +1,23 @@ #!/bin/sh # +# 2011 Steven Armstrong (steven-cdist at armstrong.cc) +# +# 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 . +# +# # same as cdist default # # Usage: From dad14af100453d467ded44647196d538a5cf9959 Mon Sep 17 00:00:00 2001 From: Steven Armstrong Date: Thu, 3 Nov 2011 22:37:05 +0100 Subject: [PATCH 06/20] add example for __remote_{copy,exec} scripts using schroot over ssh on remote host Signed-off-by: Steven Armstrong --- other/examples/remote/schroot/copy | 50 ++++++++++++++++++++++++++++++ other/examples/remote/schroot/exec | 45 +++++++++++++++++++++++++++ 2 files changed, 95 insertions(+) create mode 100755 other/examples/remote/schroot/copy create mode 100755 other/examples/remote/schroot/exec diff --git a/other/examples/remote/schroot/copy b/other/examples/remote/schroot/copy new file mode 100755 index 00000000..3587a4f2 --- /dev/null +++ b/other/examples/remote/schroot/copy @@ -0,0 +1,50 @@ +#!/bin/sh +# +# 2011 Steven Armstrong (steven-cdist at armstrong.cc) +# +# 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 . +# +# +# __remote_copy script to run cdist against a chroot on the target host over ssh. +# +# Usage: +# __remote_copy="/path/to/this/script schroot-chroot-name" cdist config target_host +# + +log() { + #echo "$@" | logger -t "cdist-schroot-copy" + : +} + +chroot_name="$1"; shift +target_host="$__target_host" + +# get directory for given chroot_name +chroot="$(ssh -o User=root -q $target_host schroot $chroot_name --config | awk -F = '/directory=/ {print $2}')" + +# prefix destination with chroot +code="$(echo "$@" | sed "s|$target_host:|$target_host:$chroot|g")" + +log "target_host: $target_host" +log "chroot_name: $chroot_name" +log "chroot: $chroot" +log "@: $@" +log "code: $code" + +# copy files into remote chroot +scp -o User=root -q $code + +log "-----" diff --git a/other/examples/remote/schroot/exec b/other/examples/remote/schroot/exec new file mode 100755 index 00000000..5b561de0 --- /dev/null +++ b/other/examples/remote/schroot/exec @@ -0,0 +1,45 @@ +#!/bin/sh +# +# 2011 Steven Armstrong (steven-cdist at armstrong.cc) +# +# 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 . +# +# +# __remote_exec script to run cdist against a chroot on the target host over ssh. +# +# Usage: +# __remote_exec="/path/to/this/script schroot-chroot-name" cdist config target_host +# + +log() { + #echo "$@" | logger -t "cdist-schroot-exec" + : +} + +chroot_name="$1"; shift +target_host="$1"; shift + +code="ssh -o User=root -q $target_host schroot -c $chroot_name -- $@" + +log "target_host: $target_host" +log "chroot_name: $chroot_name" +log "@: $@" +log "code: $code" + +# run in remote chroot +$code + +log "-----" From e18bd97c862af7e9f683a349ddbd0418a75667d6 Mon Sep 17 00:00:00 2001 From: Nico Schottelius Date: Tue, 8 Nov 2011 08:28:04 +0100 Subject: [PATCH 07/20] SUCESSFUL is very helpful to grep for :-) Signed-off-by: Nico Schottelius --- lib/cdist/config_install.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/cdist/config_install.py b/lib/cdist/config_install.py index 75b07e78..c109e131 100644 --- a/lib/cdist/config_install.py +++ b/lib/cdist/config_install.py @@ -71,7 +71,7 @@ class ConfigInstall(object): start_time = time.time() self.deploy_to() self.cleanup() - self.log.info("Finished run in %s seconds", + self.log.info("Finished successful run in %s seconds", time.time() - start_time) def stage_prepare(self): From 45c9f629ae2cccae44c2dd790ff44352a837ab6b Mon Sep 17 00:00:00 2001 From: Steven Armstrong Date: Tue, 8 Nov 2011 13:29:11 +0100 Subject: [PATCH 08/20] another more complete __remote_{copy,exec} example, including usage instructions for dispatching in .../manifest/init Signed-off-by: Steven Armstrong --- other/examples/remote/schroot-uri | 132 ++++++++++++++++++++++++++++++ 1 file changed, 132 insertions(+) create mode 100755 other/examples/remote/schroot-uri diff --git a/other/examples/remote/schroot-uri b/other/examples/remote/schroot-uri new file mode 100755 index 00000000..06dce369 --- /dev/null +++ b/other/examples/remote/schroot-uri @@ -0,0 +1,132 @@ +#!/bin/sh -e +# +# 2011 Steven Armstrong (steven-cdist at armstrong.cc) +# +# 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 . +# +# +# __remote_{exec,copy} script to run cdist against a schroot target uri +# +# Usage: +# __remote_exec="/path/to/this/script exec" cdist config target_uri +# __remote_copy="/path/to/this/script copy" cdist config target_uri +# +# # target_uri examples: +# schroot:///chroot-name +# schroot://foo.ethz.ch/chroot-name +# schroot://user-name@foo.ethz.ch/chroot-name +# +# # and how to match them in .../manifest/init +# case "$target_host" in +# schroot://*) +# # any schroot +# ;; +# schroot://foo.ethz.ch/*) +# # any schroot on specific host +# ;; +# schroot://foo.ethz.ch/chroot-name) +# # specific schroot on specific host +# ;; +# schroot:///chroot-name) +# # specific schroot on localhost +# ;; +# esac + +my_name="${0##*/}" +mode="$1"; shift + +log() { + #echo "$@" | logger -t "cdist-$my_name-$mode" + : +} + +die() { + echo "$@" >&2 + exit 1 +} + + +uri="$__target_host" + +scheme="${uri%%:*}"; rest="${uri#$scheme:}"; rest="${rest#//}" +authority="${rest%%/*}"; rest="${rest#$authority}" +path="${rest%\?*}"; rest="${rest#$path}" +schroot_name="${path#/}" + +[ "$scheme" = "schroot" ] || die "Failed to parse scheme from __target_host ($__target_host). Expected 'schroot', got '$scheme'" +[ -n "$schroot_name" ] || die "Failed to parse schroot name from __target_host: $__target_host" + +case "$authority" in + '') + # authority is empty, neither user nor host given + user="" + host="" + ;; + *@*) + # authority contains @, take user from authority + user="${authority%@*}" + host="${authority#*@}" + ;; + *) + # no user in authority, default to root + user="root" + host="$authority" + ;; +esac + +log "mode: $mode" +log "@: $@" +log "uri: $uri" +log "scheme: $scheme" +log "authority: $authority" +log "user: $user" +log "host: $host" +log "path: $path" +log "schroot_name: $schroot_name" + +exec_prefix="" +copy_prefix="" +if [ -n "$host" ]; then + # we are working on a remote host + exec_prefix="ssh -o User=$user -q $host" + copy_prefix="scp -o User=$user -q" + copy_destination_prefix="$host:" +else + # working on local machine + copy_prefix="cp" + copy_destination_prefix="" +fi + +case "$mode" in + exec) + code="$exec_prefix schroot -c $schroot_name -- $@" + ;; + copy) + # get directory for given chroot_name + schroot_directory="$($exec_prefix schroot $chroot_name --config | awk -F = '/directory=/ {print $2}')" + [ -n "$schroot_directory" ] || die "Failed to retreive schroot directory for schroot: $schroot_name" + # prefix destination with chroot + code="$copy_prefix $(echo "$@" | sed "s|$uri:|${copy_destination_prefix}${schroot_directory}|g")" + ;; + *) die "Unknown mode: $mode";; +esac + +log "code: $code" + +# Run the code +$code + +log "-----" From b3337a18b9718fbaf4cda2424589d1bbfe49fe17 Mon Sep 17 00:00:00 2001 From: Nico Schottelius Date: Wed, 9 Nov 2011 18:30:12 +0100 Subject: [PATCH 09/20] in theory catch error when requiring an undefined object (in practise not) Error message trying to fix: ERROR: [Errno 2] No such file or directory: '/home/users/nico/.tmp/tmptvy1ic/out/object/__localch_yum_repos/singleton/.cdist/state' Signed-off-by: Nico Schottelius --- lib/cdist/config_install.py | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/lib/cdist/config_install.py b/lib/cdist/config_install.py index c109e131..055a3b89 100644 --- a/lib/cdist/config_install.py +++ b/lib/cdist/config_install.py @@ -106,7 +106,7 @@ class ConfigInstall(object): """Run gencode and code for an object""" self.log.debug("Trying to run object " + cdist_object.name) if cdist_object.state == core.Object.STATE_RUNNING: - # FIXME: resolve dependency circle + # FIXME: resolve dependency circle / show problem source raise cdist.Error("Detected circular dependency in " + cdist_object.name) elif cdist_object.state == core.Object.STATE_DONE: self.log.debug("Ignoring run of already finished object %s", cdist_object) @@ -119,6 +119,13 @@ class ConfigInstall(object): for requirement in cdist_object.requirements: self.log.debug("Object %s requires %s", cdist_object, requirement) required_object = cdist_object.object_from_name(requirement) + + # The user may have created dependencies without satisfying them + if not required_object.exists(): + raise cdist.Error(cdist_object.name + " requires non-existing " + requirement.name) + else + self.log.debug("Required object %s exists", requirement.name) + self.object_run(required_object) # Generate From c7d0d581b1bf044d42d5ffadea64a1ce840e6c0e Mon Sep 17 00:00:00 2001 From: Nico Schottelius Date: Wed, 9 Nov 2011 18:41:46 +0100 Subject: [PATCH 10/20] we pass base_path, not object_path (clearification) Signed-off-by: Nico Schottelius --- lib/cdist/core/object.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/cdist/core/object.py b/lib/cdist/core/object.py index 778bebe8..db818f11 100644 --- a/lib/cdist/core/object.py +++ b/lib/cdist/core/object.py @@ -132,9 +132,9 @@ class Object(object): """ type_path = self.type.base_path - object_path = self.base_path + base_path = self.base_path type_name, object_id = self.split_name(object_name) - return self.__class__(self.type.__class__(type_path, type_name), object_path, object_id=object_id) + return self.__class__(self.type.__class__(type_path, type_name), base_path, object_id=object_id) # FIXME: still needed? @property From f95ee8062f6584d40eb0c54ee0397c554e8a411f Mon Sep 17 00:00:00 2001 From: Steven Armstrong Date: Wed, 9 Nov 2011 20:28:04 +0100 Subject: [PATCH 11/20] --SyntaxError Signed-off-by: Steven Armstrong --- lib/cdist/config_install.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/cdist/config_install.py b/lib/cdist/config_install.py index 055a3b89..0391dbc5 100644 --- a/lib/cdist/config_install.py +++ b/lib/cdist/config_install.py @@ -123,7 +123,7 @@ class ConfigInstall(object): # The user may have created dependencies without satisfying them if not required_object.exists(): raise cdist.Error(cdist_object.name + " requires non-existing " + requirement.name) - else + else: self.log.debug("Required object %s exists", requirement.name) self.object_run(required_object) From ae23f1576f8ce8fa93d88a0b73820538c7d573c4 Mon Sep 17 00:00:00 2001 From: Steven Armstrong Date: Wed, 9 Nov 2011 20:28:51 +0100 Subject: [PATCH 12/20] --TypeError Signed-off-by: Steven Armstrong --- lib/cdist/config_install.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/cdist/config_install.py b/lib/cdist/config_install.py index 0391dbc5..fbb863c3 100644 --- a/lib/cdist/config_install.py +++ b/lib/cdist/config_install.py @@ -121,7 +121,7 @@ class ConfigInstall(object): required_object = cdist_object.object_from_name(requirement) # The user may have created dependencies without satisfying them - if not required_object.exists(): + if not required_object.exists: raise cdist.Error(cdist_object.name + " requires non-existing " + requirement.name) else: self.log.debug("Required object %s exists", requirement.name) From e1cf8d094b0ee74f62613ab5b81d1f08767986a0 Mon Sep 17 00:00:00 2001 From: Steven Armstrong Date: Wed, 9 Nov 2011 20:29:36 +0100 Subject: [PATCH 13/20] --AttributeError Signed-off-by: Steven Armstrong --- lib/cdist/config_install.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/cdist/config_install.py b/lib/cdist/config_install.py index fbb863c3..3b347eb1 100644 --- a/lib/cdist/config_install.py +++ b/lib/cdist/config_install.py @@ -122,7 +122,7 @@ class ConfigInstall(object): # The user may have created dependencies without satisfying them if not required_object.exists: - raise cdist.Error(cdist_object.name + " requires non-existing " + requirement.name) + raise cdist.Error(cdist_object.name + " requires non-existing " + required_object.name) else: self.log.debug("Required object %s exists", requirement.name) From b92ea62f72ad26a54c4a17dcfac688d714c1eb3a Mon Sep 17 00:00:00 2001 From: Steven Armstrong Date: Wed, 9 Nov 2011 20:36:40 +0100 Subject: [PATCH 14/20] export OBJECT_MARKER for use in tests Signed-off-by: Steven Armstrong --- lib/cdist/core/__init__.py | 1 + 1 file changed, 1 insertion(+) diff --git a/lib/cdist/core/__init__.py b/lib/cdist/core/__init__.py index ac5bbf2f..c61c659b 100644 --- a/lib/cdist/core/__init__.py +++ b/lib/cdist/core/__init__.py @@ -23,6 +23,7 @@ from cdist.core.type import Type from cdist.core.type import NoSuchTypeError from cdist.core.object import Object from cdist.core.object import IllegalObjectIdError +from cdist.core.object import OBJECT_MARKER from cdist.core.explorer import Explorer from cdist.core.manifest import Manifest from cdist.core.code import Code From 1729516414715d95ac71ac5c645ecd1683f6d279 Mon Sep 17 00:00:00 2001 From: Steven Armstrong Date: Wed, 9 Nov 2011 20:38:22 +0100 Subject: [PATCH 15/20] allow .cdist (OBJECT_MARKER) inside file names but not as _the_ file/folder name Signed-off-by: Steven Armstrong --- lib/cdist/core/object.py | 10 +++++----- lib/cdist/test/object/__init__.py | 10 ++++++++-- 2 files changed, 13 insertions(+), 7 deletions(-) diff --git a/lib/cdist/core/object.py b/lib/cdist/core/object.py index db818f11..9abb11eb 100644 --- a/lib/cdist/core/object.py +++ b/lib/cdist/core/object.py @@ -30,7 +30,7 @@ from cdist.util import fsproperty log = logging.getLogger(__name__) -DOT_CDIST = '.cdist' +OBJECT_MARKER = '.cdist' class IllegalObjectIdError(cdist.Error): @@ -72,7 +72,7 @@ class Object(object): def list_object_names(cls, object_base_path): """Return a list of object names""" for path, dirs, files in os.walk(object_base_path): - if DOT_CDIST in dirs: + if OBJECT_MARKER in dirs: yield os.path.relpath(path, object_base_path) @staticmethod @@ -100,13 +100,13 @@ class Object(object): if object_id: if object_id.startswith('/'): raise IllegalObjectIdError(object_id, 'object_id may not start with /') - if '.cdist' in object_id: - raise IllegalObjectIdError(object_id, 'object_id may not contain \'.cdist\'') + if OBJECT_MARKER in object_id.split(os.sep): + raise IllegalObjectIdError(object_id, 'object_id may not contain \'%s\'' % OBJECT_MARKER) self.type = cdist_type # instance of Type self.base_path = base_path self.object_id = object_id self.name = self.join_name(self.type.name, self.object_id) - self.path = os.path.join(self.type.path, self.object_id, DOT_CDIST) + self.path = os.path.join(self.type.path, self.object_id, OBJECT_MARKER) self.absolute_path = os.path.join(self.base_path, self.path) self.code_local_path = os.path.join(self.path, "code-local") self.code_remote_path = os.path.join(self.path, "code-remote") diff --git a/lib/cdist/test/object/__init__.py b/lib/cdist/test/object/__init__.py index 6681c916..f199ffb5 100644 --- a/lib/cdist/test/object/__init__.py +++ b/lib/cdist/test/object/__init__.py @@ -58,12 +58,18 @@ class ObjectIdTestCase(test.CdistTestCase): with self.assertRaises(core.IllegalObjectIdError): core.Object(cdist_type, object_base_path, illegal_object_id) - def test_object_id_contains_dotcdist(self): + def test_object_id_contains_object_marker(self): cdist_type = core.Type(type_base_path, '__third') - illegal_object_id = 'object_id/may/not/contain/.cdist/anywhere' + illegal_object_id = 'object_id/may/not/contain/%s/anywhere' % core.OBJECT_MARKER with self.assertRaises(core.IllegalObjectIdError): core.Object(cdist_type, object_base_path, illegal_object_id) + def test_object_id_contains_object_marker_string(self): + cdist_type = core.Type(type_base_path, '__third') + illegal_object_id = 'object_id/may/contain_%s_in_filename' % core.OBJECT_MARKER + core.Object(cdist_type, object_base_path, illegal_object_id) + # if we get here, the test passed + class ObjectTestCase(test.CdistTestCase): From 6dd1465aa8b43a31915002ddfbfc9dd79c3f536e Mon Sep 17 00:00:00 2001 From: Steven Armstrong Date: Mon, 14 Nov 2011 15:29:07 +0100 Subject: [PATCH 16/20] --AttributeError Signed-off-by: Steven Armstrong --- lib/cdist/config_install.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/cdist/config_install.py b/lib/cdist/config_install.py index 3b347eb1..2d2ab949 100644 --- a/lib/cdist/config_install.py +++ b/lib/cdist/config_install.py @@ -124,7 +124,7 @@ class ConfigInstall(object): if not required_object.exists: raise cdist.Error(cdist_object.name + " requires non-existing " + required_object.name) else: - self.log.debug("Required object %s exists", requirement.name) + self.log.debug("Required object %s exists", required_object.name) self.object_run(required_object) From b9301c8194e5a2fcf153ac5e27d04047773ac64e Mon Sep 17 00:00:00 2001 From: Steven Armstrong Date: Mon, 14 Nov 2011 23:05:13 +0100 Subject: [PATCH 17/20] bugfix: process names dont start with slash Signed-off-by: Steven Armstrong --- conf/type/__process/explorer/runs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/conf/type/__process/explorer/runs b/conf/type/__process/explorer/runs index 2bfa8f84..240ebef9 100755 --- a/conf/type/__process/explorer/runs +++ b/conf/type/__process/explorer/runs @@ -24,7 +24,7 @@ if [ -f "$__object/parameter/name" ]; then name="$(cat "$__object/parameter/name")" else - name="/$__object_id" + name="$__object_id" fi pgrep -x -f "$name" || true From d7623fcf217e5872ab60794b567c97068566b6df Mon Sep 17 00:00:00 2001 From: Steven Armstrong Date: Mon, 14 Nov 2011 23:18:44 +0100 Subject: [PATCH 18/20] pgrep -x -f is to restrictive -> impossible to guess/match Signed-off-by: Steven Armstrong --- conf/type/__process/explorer/runs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/conf/type/__process/explorer/runs b/conf/type/__process/explorer/runs index 240ebef9..3ac9ce2f 100755 --- a/conf/type/__process/explorer/runs +++ b/conf/type/__process/explorer/runs @@ -27,4 +27,4 @@ else name="$__object_id" fi -pgrep -x -f "$name" || true +pgrep -x "$name" || true From 98ff723b2406f8cef902d5fab87c794092e42904 Mon Sep 17 00:00:00 2001 From: Nico Schottelius Date: Tue, 15 Nov 2011 09:20:27 +0100 Subject: [PATCH 19/20] add another example for __process Signed-off-by: Nico Schottelius --- conf/type/__process/man.text | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/conf/type/__process/man.text b/conf/type/__process/man.text index fd3bcf49..065beeef 100644 --- a/conf/type/__process/man.text +++ b/conf/type/__process/man.text @@ -50,6 +50,10 @@ __process /usr/sbin/sshd --state stopped --stop "/etc/rc.d/sshd stop" # Ensure cups is running, which runs with -C ...: __process cups --start "/etc/rc.d/cups start" --state running \ --name "/usr/sbin/cupsd -C /etc/cups/cupsd.conf" + +# Ensure rpc.statd is running (which usually runs with -L) using a regexp +__process rpcstatd --state running --start "/etc/init.d/statd start" \ + --name "rpc.statd.*" -------------------------------------------------------------------------------- From 7d10560a6145f2e6fe8baf2330fd941a92e1689a Mon Sep 17 00:00:00 2001 From: Nico Schottelius Date: Tue, 15 Nov 2011 09:21:07 +0100 Subject: [PATCH 20/20] Revert "pgrep -x -f is to restrictive -> impossible to guess/match" It's not, regexp are your friends :-) This reverts commit d7623fcf217e5872ab60794b567c97068566b6df. --- conf/type/__process/explorer/runs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/conf/type/__process/explorer/runs b/conf/type/__process/explorer/runs index 3ac9ce2f..240ebef9 100755 --- a/conf/type/__process/explorer/runs +++ b/conf/type/__process/explorer/runs @@ -27,4 +27,4 @@ else name="$__object_id" fi -pgrep -x "$name" || true +pgrep -x -f "$name" || true