Merge remote branch 'nico/master'
This commit is contained in:
commit
09c842e479
21 changed files with 231 additions and 276 deletions
|
@ -32,31 +32,16 @@ if [ ! -d "$(__cdist_object_dir "$object")" ]; then
|
||||||
__cdist_exit_err "Object $object is missing."
|
__cdist_exit_err "Object $object is missing."
|
||||||
fi
|
fi
|
||||||
|
|
||||||
finished="$(__cdist_object_code_finished "$object")"
|
|
||||||
require="$(__cdist_object_require "$object")"
|
|
||||||
|
|
||||||
code="$(__cdist_object_code "$object")-${__cdist_gencode_type}"
|
code="$(__cdist_object_code "$object")-${__cdist_gencode_type}"
|
||||||
|
|
||||||
# Do nothing if our work has been done
|
|
||||||
if [ -f "$finished" ]; then
|
|
||||||
exit 0
|
|
||||||
fi
|
|
||||||
|
|
||||||
echo "Checking code-${__cdist_gencode_type} for $object ..."
|
echo "Checking code-${__cdist_gencode_type} for $object ..."
|
||||||
|
|
||||||
if [ -f "$require" ]; then
|
|
||||||
while read requirement; do
|
|
||||||
echo "Requiring dependency $requirement for $object ..."
|
|
||||||
cdist-code-run "$requirement" "$__cdist_gencode_type"
|
|
||||||
done < "$require"
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [ -e "$code" ]; then
|
if [ -e "$code" ]; then
|
||||||
if [ -f "$code" ]; then
|
if [ -f "$code" ]; then
|
||||||
if [ -x "$code" ]; then
|
if [ -x "$code" ]; then
|
||||||
echo "Executing code-${__cdist_gencode_type} for $object ..."
|
echo "Executing code-${__cdist_gencode_type} for $object ..."
|
||||||
"$code"
|
"$code"
|
||||||
touch "$finished"
|
|
||||||
else
|
else
|
||||||
__cdist_exit_err "$code exists, but is not executable."
|
__cdist_exit_err "$code exists, but is not executable."
|
||||||
fi
|
fi
|
||||||
|
|
|
@ -43,7 +43,6 @@ __cdist_abs_myname="$__cdist_abs_mydir/$__cdist_myname"
|
||||||
: ${__cdist_name_bin:=bin}
|
: ${__cdist_name_bin:=bin}
|
||||||
: ${__cdist_name_cache:=cache}
|
: ${__cdist_name_cache:=cache}
|
||||||
: ${__cdist_name_code:=code}
|
: ${__cdist_name_code:=code}
|
||||||
: ${__cdist_name_code_finished:=codedone}
|
|
||||||
: ${__cdist_name_conf_dir:=conf}
|
: ${__cdist_name_conf_dir:=conf}
|
||||||
: ${__cdist_name_dot_cdist:=.cdist}
|
: ${__cdist_name_dot_cdist:=.cdist}
|
||||||
: ${__cdist_name_explorer:=explorer}
|
: ${__cdist_name_explorer:=explorer}
|
||||||
|
@ -58,17 +57,20 @@ __cdist_abs_myname="$__cdist_abs_mydir/$__cdist_myname"
|
||||||
: ${__cdist_name_object_finished:=done}
|
: ${__cdist_name_object_finished:=done}
|
||||||
: ${__cdist_name_object_id:=object_id}
|
: ${__cdist_name_object_id:=object_id}
|
||||||
: ${__cdist_name_object_source:=source}
|
: ${__cdist_name_object_source:=source}
|
||||||
|
: ${__cdist_name_objects_created:=.objects_created}
|
||||||
: ${__cdist_name_out_dir:=out}
|
: ${__cdist_name_out_dir:=out}
|
||||||
: ${__cdist_name_parameter:=parameter}
|
: ${__cdist_name_parameter:=parameter}
|
||||||
: ${__cdist_name_parameter_required:=required}
|
: ${__cdist_name_parameter_required:=required}
|
||||||
: ${__cdist_name_parameter_optional:=optional}
|
: ${__cdist_name_parameter_optional:=optional}
|
||||||
: ${__cdist_name_require:=require}
|
: ${__cdist_name_require:=require}
|
||||||
|
: ${__cdist_name_self:=self}
|
||||||
: ${__cdist_name_singleton:=singleton}
|
: ${__cdist_name_singleton:=singleton}
|
||||||
: ${__cdist_name_target_host:=target_host}
|
: ${__cdist_name_target_host:=target_host}
|
||||||
: ${__cdist_name_target_user:=target_user}
|
: ${__cdist_name_target_user:=target_user}
|
||||||
: ${__cdist_name_type:=type}
|
: ${__cdist_name_type:=type}
|
||||||
: ${__cdist_name_type_bin:=type_bin}
|
: ${__cdist_name_type_bin:=type_bin}
|
||||||
: ${__cdist_name_type_explorer:=type_explorer}
|
: ${__cdist_name_type_explorer:=type_explorer}
|
||||||
|
: ${__cdist_name_type_explorer_pushed:=.explorer_pushed}
|
||||||
|
|
||||||
# Used for IDs: Allow everything not starting with - and .
|
# Used for IDs: Allow everything not starting with - and .
|
||||||
: ${__cdist_sane_regexp:=[^-\.].*}
|
: ${__cdist_sane_regexp:=[^-\.].*}
|
||||||
|
@ -88,6 +90,7 @@ __cdist_abs_myname="$__cdist_abs_mydir/$__cdist_myname"
|
||||||
: ${__cdist_name_var_target_user:=__$__cdist_name_target_user}
|
: ${__cdist_name_var_target_user:=__$__cdist_name_target_user}
|
||||||
: ${__cdist_name_var_object:=__$__cdist_name_object}
|
: ${__cdist_name_var_object:=__$__cdist_name_object}
|
||||||
: ${__cdist_name_var_object_id:=__$__cdist_name_object_id}
|
: ${__cdist_name_var_object_id:=__$__cdist_name_object_id}
|
||||||
|
: ${__cdist_name_var_self:=__$__cdist_name_self}
|
||||||
: ${__cdist_name_var_type:=__$__cdist_name_type}
|
: ${__cdist_name_var_type:=__$__cdist_name_type}
|
||||||
|
|
||||||
|
|
||||||
|
@ -116,8 +119,11 @@ __cdist_tmp_file=$(mktemp "$__cdist_tmp_dir/cdist.XXXXXXXXXXXX")
|
||||||
: ${__cdist_out_dir:=$__cdist_local_base_dir/$__cdist_name_out_dir}
|
: ${__cdist_out_dir:=$__cdist_local_base_dir/$__cdist_name_out_dir}
|
||||||
: ${__cdist_out_explorer_dir:=$__cdist_out_dir/$__cdist_name_explorer}
|
: ${__cdist_out_explorer_dir:=$__cdist_out_dir/$__cdist_name_explorer}
|
||||||
: ${__cdist_out_object_dir:=$__cdist_out_dir/$__cdist_name_object}
|
: ${__cdist_out_object_dir:=$__cdist_out_dir/$__cdist_name_object}
|
||||||
|
: ${__cdist_out_type_dir:=$__cdist_out_dir/$__cdist_name_type}
|
||||||
: ${__cdist_out_type_bin_dir:=$__cdist_out_dir/$__cdist_name_type_bin}
|
: ${__cdist_out_type_bin_dir:=$__cdist_out_dir/$__cdist_name_type_bin}
|
||||||
|
|
||||||
|
: ${__cdist_objects_created:=$__cdist_out_object_dir/$__cdist_name_objects_created}
|
||||||
|
|
||||||
################################################################################
|
################################################################################
|
||||||
# Remote base
|
# Remote base
|
||||||
#
|
#
|
||||||
|
@ -135,6 +141,7 @@ __cdist_tmp_file=$(mktemp "$__cdist_tmp_dir/cdist.XXXXXXXXXXXX")
|
||||||
: ${__cdist_remote_out_explorer_dir:=$__cdist_remote_out_dir/$__cdist_name_explorer}
|
: ${__cdist_remote_out_explorer_dir:=$__cdist_remote_out_dir/$__cdist_name_explorer}
|
||||||
: ${__cdist_remote_out_object_dir:=$__cdist_remote_out_dir/$__cdist_name_object}
|
: ${__cdist_remote_out_object_dir:=$__cdist_remote_out_dir/$__cdist_name_object}
|
||||||
|
|
||||||
|
|
||||||
################################################################################
|
################################################################################
|
||||||
# Internal functions
|
# Internal functions
|
||||||
#
|
#
|
||||||
|
@ -187,9 +194,9 @@ __cdist_object_code()
|
||||||
echo "$(__cdist_object_dir "$1")/${__cdist_name_code}"
|
echo "$(__cdist_object_dir "$1")/${__cdist_name_code}"
|
||||||
}
|
}
|
||||||
|
|
||||||
__cdist_object_code_finished()
|
__cdist_object_finished()
|
||||||
{
|
{
|
||||||
echo "$(__cdist_object_dir "$1")/${__cdist_name_code_finished}"
|
echo "$(__cdist_object_dir "$1")/${__cdist_name_object_finished}"
|
||||||
}
|
}
|
||||||
|
|
||||||
__cdist_object_dir()
|
__cdist_object_dir()
|
||||||
|
@ -321,6 +328,18 @@ __cdist_type_has_explorer()
|
||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
|
__cdist_type_explorer_pushed()
|
||||||
|
{
|
||||||
|
[ -f "${__cdist_out_type_dir}/${__cdist_name_type_explorer_pushed}" ] \
|
||||||
|
&& grep -q "$1" "${__cdist_out_type_dir}/${__cdist_name_type_explorer_pushed}"
|
||||||
|
}
|
||||||
|
|
||||||
|
__cdist_type_explorer_pushed_add()
|
||||||
|
{
|
||||||
|
[ -d "$__cdist_out_type_dir" ] || mkdir "$__cdist_out_type_dir"
|
||||||
|
echo "$1" >> "${__cdist_out_type_dir}/${__cdist_name_type_explorer_pushed}"
|
||||||
|
}
|
||||||
|
|
||||||
__cdist_type_gencode()
|
__cdist_type_gencode()
|
||||||
{
|
{
|
||||||
echo "${__cdist_type_dir}/$1/${__cdist_name_gencode}"
|
echo "${__cdist_type_dir}/$1/${__cdist_name_gencode}"
|
||||||
|
|
|
@ -49,7 +49,6 @@ cdist-dir push "$__cdist_target_host" "${__cdist_abs_mydir}" "${__cdist_remote_b
|
||||||
|
|
||||||
cdist-explorer-run-global "$__cdist_target_host"
|
cdist-explorer-run-global "$__cdist_target_host"
|
||||||
cdist-manifest-run-init "$__cdist_target_host"
|
cdist-manifest-run-init "$__cdist_target_host"
|
||||||
cdist-manifest-run-all "$__cdist_target_host"
|
|
||||||
cdist-object-run-all "$__cdist_target_host"
|
cdist-object-run-all "$__cdist_target_host"
|
||||||
cdist-cache "$__cdist_target_host"
|
cdist-cache "$__cdist_target_host"
|
||||||
|
|
||||||
|
|
|
@ -1,77 +0,0 @@
|
||||||
#!/bin/sh
|
|
||||||
#
|
|
||||||
# 2010-2011 Nico Schottelius (nico-cdist at schottelius.org)
|
|
||||||
#
|
|
||||||
# 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/>.
|
|
||||||
#
|
|
||||||
# Run all manifests
|
|
||||||
#
|
|
||||||
|
|
||||||
. cdist-config
|
|
||||||
[ $# -eq 1 ] || __cdist_usage "<target host>"
|
|
||||||
set -eu
|
|
||||||
|
|
||||||
__cdist_target_host="$1"; shift
|
|
||||||
|
|
||||||
__cdist_objects_list="${__cdist_tmp_dir}/objects_file"
|
|
||||||
__cdist_new_objects_list="${__cdist_tmp_dir}/new_objects_file"
|
|
||||||
|
|
||||||
# Loop until we do not create new objects anymore
|
|
||||||
# which is equal to all objects have been run
|
|
||||||
__cdist_new_objects_created=y
|
|
||||||
while [ "$__cdist_new_objects_created" = "y" ]; do
|
|
||||||
# Assume we're done after this run
|
|
||||||
__cdist_new_objects_created=n
|
|
||||||
|
|
||||||
__cdist_object_list "$__cdist_out_object_dir" > "$__cdist_objects_list"
|
|
||||||
|
|
||||||
# Check every object, if we need to run it
|
|
||||||
while read __cdist_object_self; do
|
|
||||||
# Full path to current object
|
|
||||||
__cdist_cur_object_dir="$(__cdist_object_dir "$__cdist_object_self")"
|
|
||||||
|
|
||||||
# Only the id
|
|
||||||
__cdist_object_id="$(__cdist_object_id_from_object "$__cdist_object_self")"
|
|
||||||
|
|
||||||
if [ ! -f "${__cdist_cur_object_dir}/$__cdist_name_object_finished" ]; then
|
|
||||||
echo "Checking manifest for ${__cdist_object_self} ..."
|
|
||||||
|
|
||||||
__cdist_type="$(__cdist_type_from_object "$__cdist_object_self")"
|
|
||||||
__cdist_manifest="$(__cdist_type_manifest "${__cdist_type}")"
|
|
||||||
|
|
||||||
if [ -f "$__cdist_manifest" ]; then
|
|
||||||
if [ -x "$__cdist_manifest" ]; then
|
|
||||||
# Make __cdist_manifest available for cdist-type-emulator
|
|
||||||
export __cdist_manifest
|
|
||||||
|
|
||||||
echo "Executing manifest ${__cdist_manifest} ..."
|
|
||||||
# Make variables available to non-core - FIXME: beatify
|
|
||||||
export $__cdist_name_var_object="$__cdist_cur_object_dir"
|
|
||||||
export $__cdist_name_var_object_id="$__cdist_object_id"
|
|
||||||
export $__cdist_name_var_type="$(__cdist_type_dir "$__cdist_type")"
|
|
||||||
|
|
||||||
cdist-manifest-run "$__cdist_target_host" "$__cdist_manifest"
|
|
||||||
__cdist_new_objects_created=y
|
|
||||||
else
|
|
||||||
__cdist_exit_err "${__cdist_manifest} needs to be executable."
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
|
|
||||||
# done with this object
|
|
||||||
touch "$__cdist_cur_object_dir/$__cdist_name_object_finished"
|
|
||||||
done < "$__cdist_objects_list"
|
|
||||||
done
|
|
|
@ -39,4 +39,3 @@ cdist-run-remote "$__cdist_target_host" \
|
||||||
"export __cdist_out_object_dir=\"$__cdist_remote_out_object_dir\";" \
|
"export __cdist_out_object_dir=\"$__cdist_remote_out_object_dir\";" \
|
||||||
"cdist-code-run" "$__cdist_object" "${__cdist_name_gencode_remote}" \
|
"cdist-code-run" "$__cdist_object" "${__cdist_name_gencode_remote}" \
|
||||||
|| __cdist_exit_err "Remote code failed for $__cdist_object"
|
|| __cdist_exit_err "Remote code failed for $__cdist_object"
|
||||||
|
|
||||||
|
|
|
@ -24,38 +24,45 @@
|
||||||
|
|
||||||
. cdist-config
|
. cdist-config
|
||||||
[ $# -eq 2 ] || __cdist_usage "<target host> <object>"
|
[ $# -eq 2 ] || __cdist_usage "<target host> <object>"
|
||||||
|
|
||||||
set -eu
|
set -eu
|
||||||
|
|
||||||
__cdist_target_host="$1"; shift
|
__cdist_target_host="$1"; shift
|
||||||
__object="$1"; shift
|
__cdist_object="$1"; shift
|
||||||
|
|
||||||
|
__object_id="$(__cdist_object_id_from_object "$__cdist_object")"
|
||||||
|
__cdist_type="$(__cdist_type_from_object "$__cdist_object")"
|
||||||
|
|
||||||
__object_id="$(__cdist_object_id_from_object "$__object")"
|
|
||||||
__cdist_type="$(__cdist_type_from_object "$__object")"
|
|
||||||
|
|
||||||
# Check if type of object has >= 1 explorer
|
# Check if type of object has >= 1 explorer
|
||||||
has_explorer="$(__cdist_type_has_explorer "$__cdist_type")"
|
__cdist_has_explorer="$(__cdist_type_has_explorer "$__cdist_type")"
|
||||||
|
# Run the type explorers for the current object if any
|
||||||
|
if [ "$__cdist_has_explorer" ]; then
|
||||||
|
if ! __cdist_type_explorer_pushed "$__cdist_type"; then
|
||||||
|
src_dir="$(__cdist_type_explorer_dir "$__cdist_type")"
|
||||||
|
dst_dir="$(__cdist_remote_type_explorer_dir "$__cdist_type")"
|
||||||
|
echo "Transfering explorers for $__cdist_type ..."
|
||||||
|
cdist-dir push "$__cdist_target_host" "$src_dir" "$dst_dir"
|
||||||
|
__cdist_type_explorer_pushed_add "$__cdist_type"
|
||||||
|
fi
|
||||||
|
|
||||||
# If so, run explorers on remote side
|
echo "Running explorers for $__cdist_object ..."
|
||||||
if [ "$has_explorer" ]; then
|
|
||||||
echo "Running explorers for $__object ..."
|
|
||||||
# Copy object parameters
|
# Copy object parameters
|
||||||
cdist-dir push "$__cdist_target_host" \
|
cdist-dir push "$__cdist_target_host" \
|
||||||
"$(__cdist_object_parameter_dir "$__object")" \
|
"$(__cdist_object_parameter_dir "$__cdist_object")" \
|
||||||
"$(__cdist_remote_object_parameter_dir "$__object")"
|
"$(__cdist_remote_object_parameter_dir "$__cdist_object")"
|
||||||
|
|
||||||
# Execute explorers
|
# Execute explorers
|
||||||
cdist-run-remote "$__cdist_target_host" \
|
cdist-run-remote "$__cdist_target_host" \
|
||||||
"__object=\"$(__cdist_remote_object_dir "$__object")\"" \
|
"$__cdist_name_var_object=\"$(__cdist_remote_object_dir "$__cdist_object")\"" \
|
||||||
"__object_id=\"$__object_id\"" \
|
"$__cdist_name_var_object_id=\"$__object_id\"" \
|
||||||
|
"$__cdist_name_var_self=\"$__cdist_object\"" \
|
||||||
cdist-remote-explorer-run \
|
cdist-remote-explorer-run \
|
||||||
"$__cdist_name_var_type_explorer" \
|
"$__cdist_name_var_type_explorer" \
|
||||||
"$(__cdist_remote_type_explorer_dir "$__cdist_type")" \
|
"$(__cdist_remote_type_explorer_dir "$__cdist_type")" \
|
||||||
"$(__cdist_remote_object_type_explorer_dir "$__object")"
|
"$(__cdist_remote_object_type_explorer_dir "$__cdist_object")"
|
||||||
|
|
||||||
# Copy back results
|
# Copy back results
|
||||||
cdist-dir pull "$__cdist_target_host" \
|
cdist-dir pull "$__cdist_target_host" \
|
||||||
"$(__cdist_remote_object_type_explorer_dir "$__object")" \
|
"$(__cdist_remote_object_type_explorer_dir "$__cdist_object")" \
|
||||||
"$(__cdist_object_type_explorer_dir "$__object")"
|
"$(__cdist_object_type_explorer_dir "$__cdist_object")"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
|
|
@ -41,4 +41,3 @@ cdist-object-gencode "$__cdist_target_host" "$__cdist_object" \
|
||||||
"${__cdist_name_gencode_remote}" > "${code_remote}"
|
"${__cdist_name_gencode_remote}" > "${code_remote}"
|
||||||
|
|
||||||
chmod u+x "${code_local}" "${code_remote}"
|
chmod u+x "${code_local}" "${code_remote}"
|
||||||
|
|
||||||
|
|
60
bin/cdist-object-manifest-run
Executable file
60
bin/cdist-object-manifest-run
Executable file
|
@ -0,0 +1,60 @@
|
||||||
|
#!/bin/sh
|
||||||
|
#
|
||||||
|
# 2010 Nico Schottelius (nico-cdist at schottelius.org)
|
||||||
|
# 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 <http://www.gnu.org/licenses/>.
|
||||||
|
#
|
||||||
|
#
|
||||||
|
# Run the manifest for the given object.
|
||||||
|
#
|
||||||
|
|
||||||
|
. cdist-config
|
||||||
|
[ $# -eq 2 ] || __cdist_usage "<target host> <object>"
|
||||||
|
set -eu
|
||||||
|
|
||||||
|
__cdist_target_host="$1"; shift
|
||||||
|
__cdist_object="$1"; shift
|
||||||
|
|
||||||
|
# Full path to current object
|
||||||
|
__cdist_cur_object_dir="$(__cdist_object_dir "$__cdist_object")"
|
||||||
|
|
||||||
|
# Only the id
|
||||||
|
__cdist_object_id="$(__cdist_object_id_from_object "$__cdist_object")"
|
||||||
|
|
||||||
|
echo "Checking manifest for $__cdist_object ..."
|
||||||
|
|
||||||
|
__cdist_type="$(__cdist_type_from_object "$__cdist_object")"
|
||||||
|
__cdist_manifest="$(__cdist_type_manifest "$__cdist_type")"
|
||||||
|
|
||||||
|
if [ -f "$__cdist_manifest" ]; then
|
||||||
|
if [ -x "$__cdist_manifest" ]; then
|
||||||
|
# Make __cdist_manifest available for cdist-type-emulator
|
||||||
|
export __cdist_manifest
|
||||||
|
|
||||||
|
echo "Executing manifest ${__cdist_manifest} ..."
|
||||||
|
# Make variables available to non-core - FIXME: beatify
|
||||||
|
export $__cdist_name_var_object="$__cdist_cur_object_dir"
|
||||||
|
export $__cdist_name_var_object_id="$__cdist_object_id"
|
||||||
|
export $__cdist_name_var_type="$(__cdist_type_dir "$__cdist_type")"
|
||||||
|
|
||||||
|
cdist-manifest-run "$__cdist_target_host" "$__cdist_manifest"
|
||||||
|
# Tell cdist-object-run-all that there may be new objects
|
||||||
|
touch "$__cdist_objects_created"
|
||||||
|
else
|
||||||
|
__cdist_exit_err "${__cdist_manifest} needs to be executable."
|
||||||
|
fi
|
||||||
|
fi
|
|
@ -29,9 +29,7 @@ set -eu
|
||||||
__cdist_target_host="$1"; shift
|
__cdist_target_host="$1"; shift
|
||||||
__cdist_object="$1"; shift
|
__cdist_object="$1"; shift
|
||||||
|
|
||||||
|
echo "Transferring object $__cdist_object to $__cdist_target_host ..."
|
||||||
echo "Transferring object $__cdist_object to target host ..."
|
|
||||||
cdist-dir push "$__cdist_target_host" \
|
cdist-dir push "$__cdist_target_host" \
|
||||||
"$(__cdist_object_dir "$__cdist_object")" \
|
"$(__cdist_object_dir "$__cdist_object")" \
|
||||||
"$(__cdist_remote_object_dir "$__cdist_object")"
|
"$(__cdist_remote_object_dir "$__cdist_object")"
|
||||||
|
|
||||||
|
|
|
@ -21,6 +21,7 @@
|
||||||
#
|
#
|
||||||
# For the given object:
|
# For the given object:
|
||||||
# - run type explorers
|
# - run type explorers
|
||||||
|
# - run type manifest
|
||||||
# - generate code
|
# - generate code
|
||||||
# - copy object to target
|
# - copy object to target
|
||||||
# - execute code on target
|
# - execute code on target
|
||||||
|
@ -32,24 +33,38 @@ set -eu
|
||||||
|
|
||||||
__cdist_target_host="$1"; shift
|
__cdist_target_host="$1"; shift
|
||||||
__cdist_object="$1"; shift
|
__cdist_object="$1"; shift
|
||||||
|
# Export to non-core for use in manifest and gencode scripts
|
||||||
|
export $__cdist_name_var_self=$__cdist_object
|
||||||
|
|
||||||
__cdist_type="$(__cdist_type_from_object "$__cdist_object")"
|
__cdist_type="$(__cdist_type_from_object "$__cdist_object")"
|
||||||
|
|
||||||
# Check if type of object has >= 1 explorer
|
__cdist_object_finished="$(__cdist_object_finished "$__cdist_object")"
|
||||||
__cdist_has_explorer="$(__cdist_type_has_explorer "$__cdist_type")"
|
if [ ! -f "$__cdist_object_finished" ]; then
|
||||||
|
|
||||||
# Run the type explorers for the current object if any
|
# Resolve dependencies if any
|
||||||
if [ "$__cdist_has_explorer" ]; then
|
__cdist_object_require="$(__cdist_object_require "$__cdist_object")"
|
||||||
|
if [ -f "$__cdist_object_require" ]; then
|
||||||
|
echo
|
||||||
|
# NEED TO CREATE ARRAY, SSH DESTROYS WHILE READ LOOP
|
||||||
|
while read __cdist_requirement; do
|
||||||
|
set -- "$@" "$__cdist_requirement"
|
||||||
|
done < "$__cdist_object_require"
|
||||||
|
|
||||||
|
while [ $# -gt 0 ]; do
|
||||||
|
__cdist_requirement="$1"; shift
|
||||||
|
echo "Resolving dependency $__cdist_requirement for $__cdist_object ..."
|
||||||
|
cdist-object-run "$__cdist_target_host" "$__cdist_requirement"
|
||||||
|
done
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo
|
||||||
|
echo "Running object $__cdist_object"
|
||||||
cdist-object-explorer-run "$__cdist_target_host" "$__cdist_object"
|
cdist-object-explorer-run "$__cdist_target_host" "$__cdist_object"
|
||||||
|
cdist-object-manifest-run "$__cdist_target_host" "$__cdist_object"
|
||||||
|
cdist-object-gencode-run "$__cdist_target_host" "$__cdist_object"
|
||||||
|
cdist-object-push "$__cdist_target_host" "$__cdist_object"
|
||||||
|
cdist-object-code-run "$__cdist_target_host" "$__cdist_object"
|
||||||
|
|
||||||
|
# Mark this object as done
|
||||||
|
touch "$__cdist_object_finished"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Run the gencode scripts for the current object
|
|
||||||
cdist-object-gencode-run "$__cdist_target_host" "$__cdist_object"
|
|
||||||
|
|
||||||
# Transfer the current object to the target
|
|
||||||
cdist-object-push "$__cdist_target_host" "$__cdist_object"
|
|
||||||
|
|
||||||
# Run the code for the current object
|
|
||||||
cdist-object-code-run "$__cdist_target_host" "$__cdist_object"
|
|
||||||
|
|
||||||
|
|
|
@ -29,37 +29,25 @@ set -eu
|
||||||
__cdist_target_host="$1"; shift
|
__cdist_target_host="$1"; shift
|
||||||
|
|
||||||
__cdist_objects="$__cdist_tmp_dir/objects"
|
__cdist_objects="$__cdist_tmp_dir/objects"
|
||||||
__cdist_types_pushed="$__cdist_tmp_dir/types_pushed"
|
|
||||||
touch "$__cdist_types_pushed"
|
|
||||||
|
|
||||||
|
# Loop until we do not create new objects anymore
|
||||||
|
# which is equal to all objects have been run
|
||||||
|
touch "$__cdist_objects_created"
|
||||||
|
while [ -f "$__cdist_objects_created" ]; do
|
||||||
|
# Assume we're done after this run
|
||||||
|
rm "$__cdist_objects_created"
|
||||||
|
|
||||||
# Get listing of objects
|
# Get listing of objects
|
||||||
__cdist_object_list "$__cdist_out_object_dir" > "$__cdist_objects"
|
__cdist_object_list "$__cdist_out_object_dir" > "$__cdist_objects"
|
||||||
|
|
||||||
|
# NEED TO CREATE ARRAY, SSH DESTROYS WHILE READ LOOP
|
||||||
# NEED TO CREATE ARRAY, SSH DESTROYS WHILE READ LOOP
|
while read __cdist_object; do
|
||||||
while read __cdist_object; do
|
|
||||||
set -- "$@" "$__cdist_object"
|
set -- "$@" "$__cdist_object"
|
||||||
done < "$__cdist_objects"
|
done < "$__cdist_objects"
|
||||||
|
|
||||||
while [ $# -gt 0 ]; do
|
while [ $# -gt 0 ]; do
|
||||||
__cdist_object="$1"; shift
|
__cdist_object="$1"; shift
|
||||||
|
# Process the object
|
||||||
__cdist_type="$(__cdist_type_from_object "$__cdist_object")"
|
|
||||||
|
|
||||||
# Check if type of object has >= 1 explorer
|
|
||||||
__cdist_has_explorer="$(__cdist_type_has_explorer "$__cdist_type")"
|
|
||||||
|
|
||||||
# Transfer the type explorers if any
|
|
||||||
if [ "$__cdist_has_explorer" ]; then
|
|
||||||
if ! grep -q "$__cdist_type" "$__cdist_types_pushed"; then
|
|
||||||
cdist-type-explorer-push "$__cdist_target_host" "$__cdist_type"
|
|
||||||
echo "$__cdist_type" >> "$__cdist_types_pushed"
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Process the given object
|
|
||||||
cdist-object-run "$__cdist_target_host" "$__cdist_object"
|
cdist-object-run "$__cdist_target_host" "$__cdist_object"
|
||||||
|
done
|
||||||
done
|
done
|
||||||
|
|
||||||
|
|
|
@ -25,9 +25,7 @@
|
||||||
#
|
#
|
||||||
|
|
||||||
. cdist-config
|
. cdist-config
|
||||||
if [ $# -ne 3 ]; then
|
[ $# -eq 3 ] || __cdist_usage "<variable name> <explorer dir> <out dir>"
|
||||||
__cdist_usage "<variable name> <explorer dir> <out dir>"
|
|
||||||
fi
|
|
||||||
set -ue
|
set -ue
|
||||||
|
|
||||||
# Variable that defines the home of the explorers
|
# Variable that defines the home of the explorers
|
||||||
|
|
|
@ -1,40 +0,0 @@
|
||||||
#!/bin/sh
|
|
||||||
#
|
|
||||||
# 2010-2011 Nico Schottelius (nico-cdist at schottelius.org)
|
|
||||||
# 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 <http://www.gnu.org/licenses/>.
|
|
||||||
#
|
|
||||||
#
|
|
||||||
# Push the given types explorers to the target host
|
|
||||||
#
|
|
||||||
|
|
||||||
. cdist-config
|
|
||||||
[ $# -eq 2 ] || __cdist_usage "<target host> <type>"
|
|
||||||
|
|
||||||
set -eu
|
|
||||||
|
|
||||||
__cdist_target_host="$1"; shift
|
|
||||||
__cdist_type="$1"; shift
|
|
||||||
|
|
||||||
src_dir="$(__cdist_type_explorer_dir "$__cdist_type")"
|
|
||||||
dst_dir="$(__cdist_remote_type_explorer_dir "$__cdist_type")"
|
|
||||||
|
|
||||||
if [ -d "$src_dir" ]; then
|
|
||||||
echo "Transfering explorers for $__cdist_type ..."
|
|
||||||
cdist-dir push "$__cdist_target_host" "$src_dir" "$dst_dir"
|
|
||||||
fi
|
|
||||||
|
|
9
build.sh
9
build.sh
|
@ -51,8 +51,8 @@ case "$1" in
|
||||||
manbuild)
|
manbuild)
|
||||||
for src in ${MAN1DSTDIR}/*.text ${MAN7DSTDIR}/*.text; do
|
for src in ${MAN1DSTDIR}/*.text ${MAN7DSTDIR}/*.text; do
|
||||||
echo "Compiling manpage and html for $src"
|
echo "Compiling manpage and html for $src"
|
||||||
$A2XM "$src" &
|
$A2XM "$src"
|
||||||
$A2XH "$src" &
|
$A2XH "$src"
|
||||||
done
|
done
|
||||||
wait
|
wait
|
||||||
;;
|
;;
|
||||||
|
@ -70,12 +70,11 @@ case "$1" in
|
||||||
;;
|
;;
|
||||||
|
|
||||||
man1)
|
man1)
|
||||||
for man in cdist-code-run.text cdist-code-run-all.text cdist-config.text \
|
for man in cdist-code-run.text cdist-config.text \
|
||||||
cdist-dir.text cdist-env.text cdist-explorer-run-global.text \
|
cdist-dir.text cdist-env.text cdist-explorer-run-global.text \
|
||||||
cdist-deploy-to.text cdist-explorer.text cdist-manifest.text \
|
cdist-deploy-to.text cdist-explorer.text cdist-manifest.text \
|
||||||
cdist-manifest-run.text cdist-manifest-run-init.text \
|
cdist-manifest-run.text cdist-manifest-run-init.text \
|
||||||
cdist-manifest-run-all.text cdist-object-explorer-all.text \
|
cdist-object-gencode.text \
|
||||||
cdist-object-gencode.text cdist-object-gencode-all.text \
|
|
||||||
cdist-remote-explorer-run.text cdist-run-remote.text \
|
cdist-remote-explorer-run.text cdist-run-remote.text \
|
||||||
cdist-type-build-emulation.text cdist-type-emulator.text \
|
cdist-type-build-emulation.text cdist-type-emulator.text \
|
||||||
cdist-type-template.text
|
cdist-type-template.text
|
||||||
|
|
|
@ -1,7 +1,11 @@
|
||||||
1.5.0:
|
1.5.0:
|
||||||
* Add cache functionality
|
* Add basic cache functionality
|
||||||
* New type __process
|
* New type __process
|
||||||
* Restructured execution: Run whole object at once (REPHRASE) (Steven Armstrong)
|
* Restructured execution: (Steven Armstrong)
|
||||||
|
Process each object as a whole, resolve dependencies and ensure
|
||||||
|
correct execution order.
|
||||||
|
* Documentation: Rewrite stages docs (Steven Armstrong)
|
||||||
|
* Documentation: Remove legacy man pages (Steven Armstrong)
|
||||||
|
|
||||||
1.4.1: 2011-03-25
|
1.4.1: 2011-03-25
|
||||||
* New type __key_value (Steven Armstrong)
|
* New type __key_value (Steven Armstrong)
|
||||||
|
|
|
@ -6,7 +6,6 @@ Feel free to pick one!
|
||||||
CORE
|
CORE
|
||||||
----
|
----
|
||||||
- Only build manpages if necessary for types as well as for the core!
|
- Only build manpages if necessary for types as well as for the core!
|
||||||
- support $__self = relative_type/object_id
|
|
||||||
|
|
||||||
TYPES
|
TYPES
|
||||||
------
|
------
|
||||||
|
@ -18,4 +17,7 @@ Types to be written/extended:
|
||||||
-> aka sed.
|
-> aka sed.
|
||||||
- __cron
|
- __cron
|
||||||
|
|
||||||
|
DOCUMENTATION
|
||||||
|
--------------
|
||||||
|
- asciidoc interprets __, which we use for variables
|
||||||
|
names -> seek through docs and replace with \_\_!
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
/ prefix all internal variables with __cdist! -> Nico
|
||||||
|
|
||||||
Cache:
|
Cache:
|
||||||
- add example how to use
|
- add example how to use
|
||||||
- export variable $__cache
|
- export variable $__cache
|
||||||
|
|
5
doc/dev/todo/steven-from-nico
Normal file
5
doc/dev/todo/steven-from-nico
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
- align messages (already in todo for steven, but makes life much easier, thus repeated)
|
||||||
|
-> prefix all object stuff with $__self
|
||||||
|
-> __cdist_echo object string
|
||||||
|
-> $__cdist_object_self :-)
|
||||||
|
|
|
@ -1,32 +0,0 @@
|
||||||
cdist-manifest-run-all(1)
|
|
||||||
==========================
|
|
||||||
Nico Schottelius <nico-cdist--@--schottelius.org>
|
|
||||||
|
|
||||||
|
|
||||||
NAME
|
|
||||||
----
|
|
||||||
cdist-manifest-run-all - Run manifests of all created types
|
|
||||||
|
|
||||||
|
|
||||||
SYNOPSIS
|
|
||||||
--------
|
|
||||||
cdist-manifest-run-all HOSTNAME
|
|
||||||
|
|
||||||
|
|
||||||
DESCRIPTION
|
|
||||||
-----------
|
|
||||||
cdist-manifest-run-all iterates over every existing object and
|
|
||||||
executes the manifest of its type.
|
|
||||||
|
|
||||||
|
|
||||||
SEE ALSO
|
|
||||||
--------
|
|
||||||
- cdist(7)
|
|
||||||
- cdist-deploy-to(1)
|
|
||||||
- cdist-manifest-run-init(1)
|
|
||||||
|
|
||||||
|
|
||||||
COPYING
|
|
||||||
-------
|
|
||||||
Copyright \(C) 2011 Nico Schottelius. Free use of this software is
|
|
||||||
granted under the terms of the GNU General Public License version 3 (GPLv3).
|
|
|
@ -1,29 +1,29 @@
|
||||||
cdist-type-explorer-push(1)
|
cdist-object-manifest-run(1)
|
||||||
===========================
|
============================
|
||||||
Nico Schottelius <nico-cdist--@--schottelius.org>
|
Nico Schottelius <nico-cdist--@--schottelius.org>
|
||||||
Steven Armstrong <steven-dist--@--armstrong.cc>
|
Steven Armstrong <steven-dist--@--armstrong.cc>
|
||||||
|
|
||||||
|
|
||||||
NAME
|
NAME
|
||||||
----
|
----
|
||||||
cdist-type-explorer-push - Transfer type explorers to the target host
|
cdist-object-manifest-run - Run an objects manifest
|
||||||
|
|
||||||
|
|
||||||
SYNOPSIS
|
SYNOPSIS
|
||||||
--------
|
--------
|
||||||
cdist-type-explorer-push HOSTNAME TYPE
|
cdist-object-manifest-run HOSTNAME OBJECT
|
||||||
|
|
||||||
|
|
||||||
DESCRIPTION
|
DESCRIPTION
|
||||||
-----------
|
-----------
|
||||||
Transfers the explorers of the given type to the target host.
|
Run the manifest for the given object.
|
||||||
|
|
||||||
|
|
||||||
SEE ALSO
|
SEE ALSO
|
||||||
--------
|
--------
|
||||||
- cdist(7)
|
- cdist(7)
|
||||||
- cdist-object-run(1)
|
- cdist-deploy-to(1)
|
||||||
- cdist-type(1)
|
- cdist-manifest-run(1)
|
||||||
|
|
||||||
|
|
||||||
COPYING
|
COPYING
|
|
@ -1,6 +1,7 @@
|
||||||
cdist-stages(7)
|
cdist-stages(7)
|
||||||
===============
|
===============
|
||||||
Nico Schottelius <nico-cdist--@--schottelius.org>
|
Nico Schottelius <nico-cdist--@--schottelius.org>
|
||||||
|
Steven Armstrong <steven-dist--@--armstrong.cc>
|
||||||
|
|
||||||
|
|
||||||
NAME
|
NAME
|
||||||
|
@ -12,8 +13,8 @@ DESCRIPTION
|
||||||
-----------
|
-----------
|
||||||
Starting the execution of deployment with cdist-deploy-to(1), cdist passes
|
Starting the execution of deployment with cdist-deploy-to(1), cdist passes
|
||||||
through different stages, each can be triggered and debugged on its own.
|
through different stages, each can be triggered and debugged on its own.
|
||||||
Reading the source of the cdist-deploy-to executable shous the scripts
|
Reading the source of the cdist-deploy-to and cdist-object-run-all executables
|
||||||
responsible for each stage.
|
shows the scripts responsible for each stage.
|
||||||
|
|
||||||
|
|
||||||
STAGE 0: INTERNAL PREPERATION
|
STAGE 0: INTERNAL PREPERATION
|
||||||
|
@ -22,8 +23,8 @@ Before running the user facing stages, cdist prepares the target host
|
||||||
to contain cdist binaries and creates a clean environment for the
|
to contain cdist binaries and creates a clean environment for the
|
||||||
configuration run.
|
configuration run.
|
||||||
|
|
||||||
Related manpages:
|
Related documentation:
|
||||||
- cdist-bin-transfer(1)
|
- Source of cdist-deploy-to
|
||||||
|
|
||||||
|
|
||||||
STAGE 1: TARGET INFORMATION RETRIEVAL
|
STAGE 1: TARGET INFORMATION RETRIEVAL
|
||||||
|
@ -33,7 +34,9 @@ explorers. Every existing explorer is run on the target and the output of all
|
||||||
explorers are copied back into the local cache. The results can be used by
|
explorers are copied back into the local cache. The results can be used by
|
||||||
manifests and types.
|
manifests and types.
|
||||||
|
|
||||||
Related manpages:
|
Related documentation:
|
||||||
|
- cdist-explorer-run-global(1)
|
||||||
|
- cdist-remote-explorer-run(1)
|
||||||
- cdist-explorer(7)
|
- cdist-explorer(7)
|
||||||
|
|
||||||
|
|
||||||
|
@ -45,14 +48,28 @@ 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.
|
||||||
|
|
||||||
Related manpages:
|
Related documentation:
|
||||||
- cdist-manifest(7)
|
|
||||||
- cdist-manifest-run(1)
|
|
||||||
- cdist-manifest-run-init(1)
|
- cdist-manifest-run-init(1)
|
||||||
|
- cdist-manifest-run(1)
|
||||||
|
- cdist-manifest(7)
|
||||||
|
|
||||||
|
|
||||||
STAGE 3: EXECUTION OF TYPES
|
STAGE 3: OBJECT INFORMATION RETRIEVAL
|
||||||
---------------------------
|
-------------------------------------
|
||||||
|
Every object is checked whether its type has explorers and if so, these are
|
||||||
|
transfered to the target host and executed. The results are transfered back
|
||||||
|
and can be used in the following stages to decide what changes need to made
|
||||||
|
on the target to implement the desired state.
|
||||||
|
|
||||||
|
Related documentation:
|
||||||
|
- cdist-object-explorer-run(1)
|
||||||
|
- cdist-remote-explorer-run(1)
|
||||||
|
- cdist-type(7)
|
||||||
|
- cdist-explorer(7)
|
||||||
|
|
||||||
|
|
||||||
|
STAGE 4: RUN THE OBJECT MANIFEST
|
||||||
|
--------------------------------
|
||||||
Every object is checked whether its type has a manifest file. If the type has
|
Every object is checked whether its type has a manifest file. If the type has
|
||||||
a manifest file and it is executable, it will be executed. The manifest script
|
a manifest file and it is executable, it will be executed. The manifest script
|
||||||
may generate and change the created objects. In other words, one type can reuse
|
may generate and change the created objects. In other words, one type can reuse
|
||||||
|
@ -65,13 +82,13 @@ The newly created objects are merged back into the existing tree. No conflicts
|
||||||
may occur during the merge. A conflict would mean that two different objects
|
may occur during the merge. A conflict would mean that two different objects
|
||||||
try to create the same object, which indicates a broken configuration.
|
try to create the same object, which indicates a broken configuration.
|
||||||
|
|
||||||
Related manpages:
|
Related documentation:
|
||||||
|
- cdist-object-manifest-run(1)
|
||||||
- cdist-manifest-run(1)
|
- cdist-manifest-run(1)
|
||||||
- cdist-manifest-run-all(1)
|
|
||||||
- cdist-type(7)
|
- cdist-type(7)
|
||||||
|
|
||||||
|
|
||||||
STAGE 4: CODE GENERATION
|
STAGE 5: CODE GENERATION
|
||||||
------------------------
|
------------------------
|
||||||
In this stage for every created objects its type is checked whether it has a
|
In this stage for every created objects its type is checked whether it has a
|
||||||
gencode script. If the type has a gencode script and it is executable it will
|
gencode script. If the type has a gencode script and it is executable it will
|
||||||
|
@ -79,20 +96,28 @@ be executed. This executable should create code to be executed on the target
|
||||||
on stdout. If the gencode executable fails, it must print diagnostic messages
|
on stdout. If the gencode executable fails, it must print diagnostic messages
|
||||||
on stderr and exit non-zero.
|
on stderr and exit non-zero.
|
||||||
|
|
||||||
Related manpages:
|
Related documentation:
|
||||||
- cdist-gencode(1)
|
- cdist-object-gencode-run(1)
|
||||||
- cdist-gencode-all(1)
|
- cdist-object-gencode(1)
|
||||||
- cdist-type(7)
|
- cdist-type(7)
|
||||||
|
|
||||||
|
|
||||||
STAGE 5: CODE EXECUTION
|
STAGE 6: CODE EXECUTION
|
||||||
-----------------------
|
-----------------------
|
||||||
The resulting code from the previous stage is transferred to the target host
|
For every object the resulting code from the previous stage is transferred to
|
||||||
and executed there to apply the configuration changes,
|
the target host and executed there to apply the configuration changes.
|
||||||
|
|
||||||
Related manpages:
|
Related documentation:
|
||||||
- cdist-exec-run(1)
|
- cdist-object-code-run(1)
|
||||||
- cdist-exec-transfer(1)
|
- cdist-code-run(1)
|
||||||
|
|
||||||
|
|
||||||
|
STAGE 7: CACHE
|
||||||
|
--------------
|
||||||
|
The cache stores the information from the current run for later use.
|
||||||
|
|
||||||
|
Related documentation:
|
||||||
|
- cdist-cache(1)
|
||||||
|
|
||||||
|
|
||||||
SUMMARY
|
SUMMARY
|
||||||
|
@ -112,5 +137,5 @@ SEE ALSO
|
||||||
|
|
||||||
COPYING
|
COPYING
|
||||||
-------
|
-------
|
||||||
Copyright \(C) 2010-2011 Nico Schottelius. Free use of this software is
|
Copyright \(C) 2010-2011 Nico Schottelius, Steven Armstrong. Free use of this software is
|
||||||
granted under the terms of the GNU General Public License version 3 (GPLv3).
|
granted under the terms of the GNU General Public License version 3 (GPLv3).
|
||||||
|
|
Loading…
Reference in a new issue