diff options
-rw-r--r-- | README.md | 2 | ||||
-rw-r--r-- | TODO.md | 33 | ||||
-rw-r--r-- | lib/hydra/config | 2 | ||||
-rw-r--r-- | lib/hydra/deploy | 112 | ||||
-rw-r--r-- | lib/hydra/misc | 3 | ||||
-rwxr-xr-x | share/hydra/config | 1 | ||||
-rwxr-xr-x | share/hydra/deploy | 102 | ||||
-rwxr-xr-x | share/hydra/import-keys | 2 | ||||
-rwxr-xr-x | share/hydra/init | 57 | ||||
-rwxr-xr-x | share/hydra/install | 13 | ||||
-rwxr-xr-x | share/hydra/newkeys | 8 | ||||
-rwxr-xr-x | share/hydra/newnode | 34 | ||||
-rwxr-xr-x | share/hydra/nodes | 18 | ||||
-rwxr-xr-x | share/hydra/register | 45 | ||||
-rwxr-xr-x | share/hydra/sync | 6 | ||||
-rwxr-xr-x | share/hydractl/deploy | 58 | ||||
-rwxr-xr-x | share/hydractl/install | 4 | ||||
-rwxr-xr-x | share/hydractl/provision | 9 | ||||
-rwxr-xr-x | share/hydractl/provision-chroot | 16 | ||||
-rwxr-xr-x | share/hydractl/provision-raspi | 2 | ||||
-rwxr-xr-x | share/hydractl/upgrade | 8 |
21 files changed, 324 insertions, 211 deletions
@@ -37,7 +37,7 @@ If you have enough credentials (ssh pubkey set in the server), you can fetch all the needed repositories and configurations to a local folder `~/file/example` using simply the following command: - hydra example init ~/file/example git@admin.example.org:config.git + hydra example init ~/file/example git@admin.example.org:example.git Creating a new network ---------------------- @@ -4,34 +4,13 @@ TODO Hydra ----- -- ansible integration. -- module-commit: - - check and set git-flow and production branch in all repositories. - - check, install and test puppet pre-commit via git-hooks on all repositories using module-commit. +- implement a general test suite. +- install: move to /usr/local/share/hydra. - bootless: properly support `$subdevice` in parted or always use first partition (like `/dev/sdb1`). +- init: add new repositories as superproject's submodules. +- newnode: do not generate manifest file, only hiera. - ssh-config: hydra integration. - init: version control in the superproject? - deploy: - - install keys? - - use /etc/hydra/{puppet,keyring,etc}? - -Hydractl --------- - -- provision: - - command line parameters using key=value pairs. - - config parser using a custom function with `include` directive, avoiding `source`. -- install: PREFIX support. -- deploy: install keys -- upgrade: run docker upgrade on all available images. -- wrapper to import/export monkeysphere keys into keyringer. -- backup-{site,copy,restore}: call backup-restore-user. -- backup-restore-site {debian,wiki}. -- backup-restore-user and backup-restore-users. -- backup-restore-SERVICE: stop/start service. -- backup-copy action. -- backup-restore-reprepro: rsync -av /var/backups/remote/$ORIG/restore/$DATE/var/reprepro/ /var/reprepro/. -- backup-restore-sites: support for other backup locations. -- backup-restore-site: - - metastore integration for fine-grained permissions. - - use metadata do detect drupal series. + - fix /etc/puppet permissions. + - import keys and certs. diff --git a/lib/hydra/config b/lib/hydra/config index d1eb411..5390159 100644 --- a/lib/hydra/config +++ b/lib/hydra/config @@ -52,7 +52,7 @@ function hydra_check_preferences { PUPPET="$HYDRA_FOLDER/puppet" PUPPET_KEYS="$PUPPET/keys" - export HYDRA_CONNECT="ssh -T -o ConnectTimeout=15" + export HYDRA_CONNECT="ssh -T -q -o ConnectTimeout=15" } # Load a parameter from config diff --git a/lib/hydra/deploy b/lib/hydra/deploy index d5df1a0..771c42e 100644 --- a/lib/hydra/deploy +++ b/lib/hydra/deploy @@ -4,63 +4,91 @@ function hydra_deploy_setup { # Common parameters # Exclude eventual keys and version control files - DEPLOY_RSYNC="rsync -CrltDv --no-perms --exclude=keys --exclude=hiera/secrets --delete" + DEPLOY_DEPENDENCIES="puppet-common ruby-sqlite3 ruby-activerecord ruby-activerecord-deprecated-finders augeas-tools" + DEPLOY_RSYNC="rsync -CrltDvpq --no-owner --exclude=/ssl --exclude=keys --exclude=site_keys --exclude=hiera/secrets --delete --rsync-path" + RSYNC_PATH="rsync -q" if [ "$1" == "remote" ]; then - # Deploy in a local folder + # Deploy in a remote host if [ ! -z "$2" ]; then NODE="$2" + DEPLOY_BASE="/etc" DEPLOY_COMMAND="$HYDRA_CONNECT $NODE sudo" - DEPLOY_RSYNC="$DEPLOY_RSYNC --rsync-path \"sudo rsync\" $HYDRA_FOLDER/puppet/ $NODE:/etc/puppet/" - FQDN="`$DEPLOY_COMMAND facter fqdn`" + FQDN="`$DEPLOY_COMMAND cat /etc/hostname`" + DEPLOY_OPTS="$HYDRA_FOLDER/puppet/ $NODE:/etc/puppet/" DEPLOY_DEST="$FQDN:" - DEPLOY_COPY="$DEPLOY_RSYNC" - PUPPET_MANIFEST="/etc/puppet/manifests/nodes/$FQDN.pp" + RSYNC_PATH="sudo rsync -q" + REMOTE_ENV="LC_ALL=C" + hydra_deploy_set_manifest else echo "No folder specified." exit 1 fi elif [ "$1" == "folder" ]; then - # Deploy in a remote host + # Deploy in a local folder if [ ! -z "$2" ]; then FOLDER="$2" + DEPLOY_BASE="/etc" DEPLOY_COMMAND="$SUDO chroot $FOLDER" - DEPLOY_RSYNC="$DEPLOY_RSYNC $HYDRA_FOLDER/puppet/ $FOLDER/etc/puppet/" - DEPLOY_COPY="$SUDO cp" + DEPLOY_RSYNC="$SUDO $DEPLOY_RSYNC" + DEPLOY_OPTS="$HYDRA_FOLDER/puppet/ $FOLDER/etc/puppet/" DEPLOY_DEST="$FOLDER" - PUPPET_MANIFEST="/etc/puppet/manifests/nodes/$FQDN.pp" - - if [ ! -d "$FOLDER"]; then - echo "folder not found: $FOLDER" - exit 1 - fi # Fix hostname if [ -s "$FOLDER/etc/hostname" ]; then FQDN="`cat $FOLDER/etc/hostname`" fi + + hydra_deploy_set_manifest + + if [ ! -d "$FOLDER" ]; then + echo "folder not found: $FOLDER" + exit 1 + fi else echo "No node specified." exit 1 fi else # Deploy on the localhost + DEPLOY_BASE="$HYDRA_FOLDER" DEPLOY_COMMAND="$SUDO" - FQDN="`facter fqdn`" - PUPPET_OPTS="--confdir=$HYDRA_FOLDER/puppet --modulepath=$HYDRA_FOLDER/modules" - PUPPET_MANIFEST="$HYDRA_FOLDER/puppet/manifests/nodes/$FQDN.pp" + DEPLOY_RSYNC="" + FQDN="`cat /etc/hostname`" + PUPPET_OPTS="--confdir=$HYDRA_FOLDER/puppet --modulepath=$HYDRA_FOLDER/puppet/modules" + hydra_deploy_set_manifest $HYDRA_FOLDER fi # Common parameters DOMAIN="`echo $FQDN | cut -d . -f 2-`" - ROLE="`hydra_yaml_param nodo::role $HYDRA_FOLDER/$DOMAIN/$FQDN.yaml`" - LOCATION="`hydra_yaml_param nodo::location $HYDRA_FOLDER/$DOMAIN/$FQDN.yaml`" - DEPLOY_PUPPET="puppet appy $PUPPET_OPTS $PUPPET_MANIFEST" + ROLE="`hydra_yaml_param nodo::role $HYDRA_FOLDER/puppet/hiera/node/$FQDN.yaml`" + LOCATION="`hydra_yaml_param nodo::location $HYDRA_FOLDER/puppet/hiera/node/$FQDN.yaml`" + + # Puppet command + if [ -e "$HYDRA_FOLDER/puppet/bin/deploy" ]; then + DEPLOY_PUPPET="$DEPLOY_BASE/puppet/bin/deploy" + else + DEPLOY_PUPPET="$REMOTE_ENV puppet apply $PUPPET_OPTS $PUPPET_MANIFEST" + fi + + # Deployment command DEPLOY_APPLY="$DEPLOY_COMMAND $DEPLOY_PUPPET" +} + +# Manifest +function hydra_deploy_set_manifest { + local prefix="$1" - # Check for manifest - if [ ! -e "$HYDRA_FOLDER/puppet/manifests/nodes/$FQDN.pp" ]; then - echo "Not found: $HYDRA_FOLDER/puppet/manifests/nodes/$FQDN.pp" + if [ -z "$prefix" ]; then + prefix="/etc" + fi + + if [ -e "$HYDRA_FOLDER/puppet/manifests/nodes/$FQDN.pp" ]; then + PUPPET_MANIFEST="$prefix/puppet/manifests/nodes/$FQDN.pp" + elif [ -e "$HYDRA_FOLDER/puppet/manifests/nodes/default.pp" ]; then + PUPPET_MANIFEST="$prefix/puppet/manifests/nodes/default.pp" + else + echo "no manifest found for $FQDN" exit 1 fi } @@ -81,23 +109,43 @@ function hydra_deploy_mkdirs { $DEPLOY_COMMAND chmod -R 640 /etc/puppet } -# Create hiera folder structure -function hydra_hiera_copy { - $DEPLOY_COMMAND mkdir -p $FOLDER/etc/puppet/secrets/{domain,location,node,role} +# Copy hiera secrets +function hydra_deploy_copy_secrets { + local location="$1" + + if [ -z "$location" ]; then + location="remote" + fi + + $DEPLOY_COMMAND mkdir -p $FOLDER/etc/puppet/hiera/secrets/{domain,location,node,role} if [ ! -z "$DOMAIN" ] && [ -e "$HYDRA_FOLDER/puppet/hiera/secrets/domain/$DOMAIN.yaml" ]; then - $DEPLOY_COPY $HYDRA_FOLDER/puppet/hiera/secrets/domain/$DOMAIN.yaml $DEPLOY_DEST/etc/puppet/hiera/secrets/domain/ + hydra_deploy_copy $location $HYDRA_FOLDER/puppet/hiera/secrets/domain/$DOMAIN.yaml $DEPLOY_DEST/etc/puppet/hiera/secrets/domain/ fi if [ ! -z "$LOCATION" ] && [ -e "$HYDRA_FOLDER/puppet/hiera/secrets/location/$LOCATION.yaml" ]; then - $DEPLOY_COPY $HYDRA_FOLDER/puppet/hiera/secrets/location/$LOCATION.yaml $DEPLOY_DEST/etc/puppet/hiera/secrets/location/ + hydra_deploy_copy $location $HYDRA_FOLDER/puppet/hiera/secrets/location/$LOCATION.yaml $DEPLOY_DEST/etc/puppet/hiera/secrets/location/ fi if [ ! -z "$ROLE" ] && [ -e "$HYDRA_FOLDER/puppet/hiera/secrets/role/$ROLE.yaml" ]; then - $DEPLOY_COPY $HYDRA_FOLDER/puppet/hiera/secrets/role/$ROLE.yaml $DEPLOY_DEST/etc/puppet/hiera/secrets/role/ + hydra_deploy_copy $location $HYDRA_FOLDER/puppet/hiera/secrets/role/$ROLE.yaml $DEPLOY_DEST/etc/puppet/hiera/secrets/role/ fi - if [ ! -z "$NODE" ] && [ -e "$HYDRA_FOLDER/puppet/hiera/secrets/node/$NODE.yaml" ]; then - $DEPLOY_COPY $HYDRA_FOLDER/puppet/hiera/secrets/node/$NODE.yaml $DEPLOY_DEST/etc/puppet/hiera/secrets/node/ + if [ ! -z "$FQDN" ] && [ -e "$HYDRA_FOLDER/puppet/hiera/secrets/node/$FQDN.yaml" ]; then + hydra_deploy_copy $location $HYDRA_FOLDER/puppet/hiera/secrets/node/$FQDN.yaml $DEPLOY_DEST/etc/puppet/hiera/secrets/node/ + fi +} + +# Copy a single file +function hydra_deploy_copy { + local location="$1" + local orig="$2" + local dest="$3" + + if [ "$location" == "folder" ]; then + $SUDO mkdir -p $dest + $SUDO cp $orig $dest + elif [ "$location" == "remote" ]; then + $DEPLOY_RSYNC "$RSYNC_PATH" $orig $dest fi } diff --git a/lib/hydra/misc b/lib/hydra/misc index 2c44503..d8dfb3b 100644 --- a/lib/hydra/misc +++ b/lib/hydra/misc @@ -2,7 +2,8 @@ # Set needed environment variables and do basic checks function hydra_set_env { - export COMMIT="`( cd $APP_BASE && git log -n 1 --pretty=oneline | cut -d " " -f 1 )`" + export OSVERSION="`cut -d . -f 1 /etc/debian_version`" + export COMMIT="`( cd $APP_BASE && git log -n 1 --pretty=oneline 2> /dev/null | cut -d " " -f 1 )`" export CONFIG="$HOME/.hydra/config" export ACTION="$1" diff --git a/share/hydra/config b/share/hydra/config index 1b730b8..371d031 100755 --- a/share/hydra/config +++ b/share/hydra/config @@ -39,6 +39,7 @@ elif [ -z "$VALUE" ]; then echo "No such config parameter $KEY." fi else + mkdir -p `dirname $KEY` echo "$VALUE" > $HYDRA_FOLDER/config/$KEY hydra $HYDRA git config add $KEY echo "" diff --git a/share/hydra/deploy b/share/hydra/deploy index 4bf6686..efbaeba 100755 --- a/share/hydra/deploy +++ b/share/hydra/deploy @@ -1,6 +1,11 @@ #!/bin/bash # -# Deploy a node using automated recipes. +# Deploy a node using automated recipes. See discussion at +# +# - http://current.workingdirectory.net/posts/2011/puppet-without-masters/ +# - http://andrewbunday.co.uk/2012/12/04/masterless-puppet-wrapper/ +# - http://semicomplete.com/presentations/puppet-at-loggly/puppet-at-loggly.pdf.html +# - https://github.com/jordansissel/puppet-examples/tree/master/masterless # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU Affero General Public License as @@ -28,31 +33,88 @@ if [ -z "$NODES" ]; then NODES="`hydra $HYDRA nodes`" fi +# Banner +echo '.__ .___ .___ .__ ._.' +echo '| |__ ___.__. __| _/___________ __| _/____ ______ | | ____ ___.__.| |' +echo '| | < | |/ __ |\_ __ \__ \ / __ |/ __ \\____ \| | / _ < | || |' +echo '| Y \___ / /_/ | | | \// __ \_ / /_/ \ ___/| |_> > |_( <_> )___ | \|' +echo '|___| / ____\____ | |__| (____ / \____ |\___ > __/|____/\____// ____| __' +echo ' \/\/ \/ \/ \/ \/|__| \/ \/' +echo '' + # Deploy for node in $NODES; do - echo "Deploying to $node..." + if [ -d "$node" ]; then + echo "Deploying to $node folder..." - # Setup deploy environment - hydra_deploy_setyp remote $node - hydra_deploy_mkdirs + # Setup deploy environment + FOLDER=$node + hydra_deploy_setup folder $FOLDER - # Sync repository to server - $DEPLOY_RSYNC + # Check if puppet is installed + if [ ! -e "$FOLDER/usr/bin/puppet" ]; then + echo "Installing dependencies..." + $DEPLOY_COMMAND apt-get update + $DEPLOY_COMMAND apt-get install $DEPLOY_DEPENDENCIES -y + fi - # Copy hiera configuration - hydra_hiera_copy + # Create folders + hydra_deploy_mkdirs - # Check if puppet is installed - $HYDRA_CONNECT $node <<EOF - ##### BEGIN REMOTE SCRIPT ##### - if ! which puppet &> /dev/null; then - echo "Installing puppet..." - sudo aptitude update - sudo aptitude install puppet -y - fi - ##### END REMOTE SCRIPT ####### + # Sync repository to server + echo "Syncing configuration..." + $DEPLOY_RSYNC "$RSYNC_PATH" $DEPLOY_OPTS + + # Copy hiera configuration + hydra_deploy_copy_secrets folder + + # Run puppet, overriding FQDN + echo "Applying configuration..." + LC_ALL=C HOSTNAME=$FQDN FACTER_domain=$DOMAIN FACTER_hostname=$FQDN FACTER_fqdn=$HOSTNAME.$DOMAIN $DEPLOY_APPLY + elif [ "$node" == "localhost" ] || [ "$node" == "`facter fqdn`" ] || [ "$node" == "`facter hostname`" ]; then + echo "Deploying to localhost..." + + # Setup deploy environment + hydra_deploy_setup + + # Check if puppet is installed + if [ ! -e "/usr/bin/puppet" ]; then + $SUDO apt-get update + $SUDO apt-get install $DEPLOY_DEPENDENCIES -y + fi + + # Run puppet + echo "Applying configuration..." + $DEPLOY_APPLY + else + echo "Deploying to $node..." + + # Setup deploy environment + hydra_deploy_setup remote $node + + # Check if puppet is installed + $HYDRA_CONNECT $node <<EOF + ##### BEGIN REMOTE SCRIPT ##### + if ! which puppet &> /dev/null; then + echo "Installing dependencies..." + sudo apt-get update + sudo apt-get install $DEPLOY_DEPENDENCIES -y + fi + ##### END REMOTE SCRIPT ####### EOF - # Run puppet - $DEPLOY_APPLY + # Create folders + hydra_deploy_mkdirs + + # Sync repository to server + echo "Syncing configuration..." + $DEPLOY_RSYNC "$RSYNC_PATH" $DEPLOY_OPTS + + # Copy hiera configuration + hydra_deploy_copy_secrets remote + + # Run puppet + echo "Applying configuration..." + $DEPLOY_APPLY + fi done diff --git a/share/hydra/import-keys b/share/hydra/import-keys index 784deae..b180d28 100755 --- a/share/hydra/import-keys +++ b/share/hydra/import-keys @@ -22,7 +22,7 @@ hydra_config_load # Import OpenPGP keypair function hydra_import_keys_openpgp { - key="$(keyringer $HYDRA decrypt $hostname/gpg/key 2> /dev/null | sed -ne '1,$p')" + key="$(keyringer $HYDRA decrypt nodes/$hostname/gpg/key 2> /dev/null | sed -ne '1,$p')" key_id="$(echo "$key" | gpg --with-colons | grep sec | cut -d : -f 5)" if [ -z "$key" ]; then diff --git a/share/hydra/init b/share/hydra/init index d21c003..4a6d0c1 100755 --- a/share/hydra/init +++ b/share/hydra/init @@ -29,29 +29,30 @@ if [ -z "$BASEDIR" ]; then echo "Usage: hydra [hydra] init <path> [remote]" exit 1 elif grep -q -e "^$HYDRA=" $CONFIG &> /dev/null; then - echo "Hydra $HYDRA already defined" + echo "Hydra $HYDRA already registered" exit 1 elif [ -d "$BASEDIR" ]; then - echo "Folder $BASEDIR already exists, hydra $HYDRA already defined?" + echo "Folder $BASEDIR already exists, maybe you want to run 'hydra $HYDRA register'?" exit 1 fi -# Create base -mkdir -p $BASEDIR - -# Reparse basedir to force absolute folder -BASEDIR="`cd $BASEDIR && pwd`" - -# Add entry -echo "Registering hydra $HYDRA..." -mkdir -p $BASEDIR -chmod 700 $BASEDIR -echo "$HYDRA=\"$BASEDIR\"" >> $CONFIG - # Clone configuration repository or setup a new hydra if [ ! -z "$REMOTE" ]; then - git clone $REMOTE $BASEDIR/config + git clone $REMOTE $BASEDIR + + ( + cd $BASEDIR + + # Initialize only the required repositories + for repo in $BASEREPOS; do + git submodule update --init $repo + done + ) else + # Create the superproject + mkdir -p $BASEDIR + hydra_git_init $BASEDIR + # Create config repository if [ ! -d "$BASEDIR/config" ]; then # Setup repository from template @@ -67,18 +68,30 @@ else fi # Create bootless repository - echo "Initializing bootless repository..." - hydra $HYDRA bootless init + if [ ! -d "$BASEDIR/bootless" ]; then + echo "Initializing bootless repository..." + hydra $HYDRA bootless init + fi # Create puppet repository - echo "Cloning initial puppet repository..." - git clone git://git.sarava.org/puppet-bootstrap.git $BASEDIR/puppet + if [ ! -d "$BASEDIR/puppet" ]; then + echo "Cloning initial puppet repository..." + git clone git://git.fluxo.info/puppet-bootstrap.git $BASEDIR/puppet - # Config puppet - echo "Configuring puppet repository..." - hydra_bootstrap_config $BASEDIR/puppet + # Config puppet + echo "Configuring puppet repository..." + hydra_bootstrap_config $BASEDIR/puppet + fi fi +# Reparse basedir to force absolute folder +BASEDIR="`cd $BASEDIR && pwd`" + +# Add entry +echo "Registering hydra $HYDRA..." +chmod 700 $BASEDIR +echo "$HYDRA=\"$BASEDIR\"" >> $CONFIG + cat<<-EOF Hydra suite relies heavilly in the address in the form of "admin.example.org" as the repository server which hosts configuration. diff --git a/share/hydra/install b/share/hydra/install index 8b93ae7..00154b7 100755 --- a/share/hydra/install +++ b/share/hydra/install @@ -28,8 +28,13 @@ if [ -z "$NODES" ]; then NODES="`hydra $HYDRA nodes`" fi -# Validation -if [ -z "$ORIGIN" ]; then +# Get origin +ORIGIN_CONFIG="`hydra $HYDRA config git`" + +# Validate origin +if [ ! -z "$ORIGIN_CONFIG" ]; then + ORIGIN="$ORIGIN_CONFIG/hydra.git" +else ORIGIN="git://git.fluxo.info/hydra.git" fi @@ -44,8 +49,8 @@ for node in $NODES; do ##### BEGIN REMOTE SCRIPT ##### if ! which git &> /dev/null; then echo "Installing git..." - sudo aptitude update - sudo aptitude install git-core -y + sudo apt-get update + sudo apt-get install git-core -y fi # Git version diff --git a/share/hydra/newkeys b/share/hydra/newkeys index 37e76e8..3fe782f 100755 --- a/share/hydra/newkeys +++ b/share/hydra/newkeys @@ -19,7 +19,13 @@ function hydra_newkeys { # Generates ssh and gpg keys for new or existing nodes # GPG keys should be manually imported in the nodes - for host in `hydra $HYDRA nodes`; do + if [ ! -z "$1" ]; then + NODES="$*" + else + NODES="`hydra $HYDRA nodes`" + fi + + for host in $NODES; do node="`echo $host | cut -d . -f 1`" sshkey="$HYDRA_FOLDER/keyring/keys/nodes/$node/ssh/id_rsa.asc" gpgkey="$HYDRA_FOLDER/keyring/keys/nodes/$node/gpg/key.asc" diff --git a/share/hydra/newnode b/share/hydra/newnode index 7cb7ae4..e78b9bb 100755 --- a/share/hydra/newnode +++ b/share/hydra/newnode @@ -32,10 +32,8 @@ if [ -z "$NODE" ]; then elif [ ! -e "$HYDRA_FOLDER/config/domain" ]; then echo "fatal: please configure your domain at $HYDRA_FOLDER/config/domain" exit 1 -elif [ ! -f "$NODES" ]; then - echo "fatal: $NODES not found" - exit 1 -elif grep -qe "^import \"nodes/$NODE.pp\"$" $NODES &> /dev/null; then +#elif grep -qe "^import \"nodes/$NODE.pp\"$" $NODES &> /dev/null; then +elif [ -e "$HYDRA_FOLDER/puppet/manifest/nodes/$NODE.pp" ]; then echo "fatal: node $NODE already defined" exit 1 fi @@ -43,8 +41,15 @@ fi # Domain DOMAIN="`cat $HYDRA_FOLDER/config/domain`" +# Check if node was given by fqdn or just hostname +if ! echo $NODE | grep -q '\.'; then + NODE="$NODE.$DOMAIN" +fi + # Create node -echo "import \"nodes/$NODE.$DOMAIN.pp\"" >> $NODES +if [ -e "$NODES" ]; then + echo "import \"nodes/$NODE.pp\"" >> $NODES +fi # Set YAML template if [ -e "$HYDRA_FOLDER/config/templates/node/nodo.example.org.yaml" ]; then @@ -61,19 +66,26 @@ else fi # Copy YAML template -mkdir -p $HYDRA_FOLDER/puppet/hiera/production/domain/$DOMAIN/node -cp $YAML $HYDRA_FOLDER/puppet/hiera/production/domain/$DOMAIN/node/$NODE.$DOMAIN.yaml +mkdir -p $HYDRA_FOLDER/puppet/hiera/node +cp $YAML $HYDRA_FOLDER/puppet/hiera/node/$NODE.yaml + +# Setup secret YAML template +mkdir -p $HYDRA_FOLDER/puppet/hiera/secrets/node +echo "---" > $HYDRA_FOLDER/puppet/hiera/secrets/node/$NODE.yaml # Copy node template mkdir -p $HYDRA_FOLDER/puppet/manifests/nodes -cp $PP $HYDRA_FOLDER/puppet/manifests/nodes/$NODE.$DOMAIN.pp +cp $PP $HYDRA_FOLDER/puppet/manifests/nodes/$NODE.pp # Edit the template -sed -i -e "s/nodename/$NODE/g" $HYDRA_FOLDER/puppet/manifests/nodes/$NODE.pp -sed -i -e "s/example.org/$DOMAIN/g" $HYDRA_FOLDER/puppet/manifests/nodes/$NODE.pp +sed -i -e "s/nodename.example.org/$NODE/g" $HYDRA_FOLDER/puppet/manifests/nodes/$NODE.pp # Add to git ( cd $HYDRA_FOLDER/puppet - git add manifests/site.pp manifests/nodes/$NODE.pp hiera/production/domain/$DOMAIN/node/$NODE.$DOMAIN.yaml + git add manifests/nodes/$NODE.pp hiera/node/$NODE.yaml hiera/secrets/node/$NODE.yaml + + if [ -e 'manifests/site.pp' ]; then + git add manifests/site.pp + fi ) diff --git a/share/hydra/nodes b/share/hydra/nodes index b070680..e2a318d 100755 --- a/share/hydra/nodes +++ b/share/hydra/nodes @@ -18,22 +18,16 @@ # Get a list of puppet node files function hydra_node_files { - if [ -d "$PUPPET/manifests/nodes/" ]; then - FILES="$PUPPET/manifests/nodes/*" - else - FILES="`find $PUPPET -name 'nodes.pp'`" + if [ -d "$PUPPET/hiera/node/" ]; then + FILES="$PUPPET/hiera/node/*" fi } -# Get all lines matching a node definition -function hydra_node_lines { - # See http://www.mail-archive.com/puppet-users@googlegroups.com/msg01615.html - grep ^node $FILES | sed -e 's/^node //' | awk -F, '{for(i=1;i<=NF;i++) {print $i}}' -} - -# Default node retrieval method +# Return node names function hydra_nodes { - hydra_node_lines | cut -d "'" -f2 + for file in $FILES; do + basename $file .yaml + done } # Load diff --git a/share/hydra/register b/share/hydra/register new file mode 100755 index 0000000..c15e41f --- /dev/null +++ b/share/hydra/register @@ -0,0 +1,45 @@ +#!/bin/bash +# +# Register an existing hydra +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as +# published by the Free Software Foundation, either version 3 of the +# License, or (at your option) any later version. +# +# This program 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 Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public +# License along with this program. If not, see +# <http://www.gnu.org/licenses/>. + +# Load +source $APP_BASE/lib/hydra/functions || exit 1 +hydra_config_load + +# Command line arguments +BASEDIR="$1" +REMOTE="$2" + +# Validation +if [ -z "$BASEDIR" ]; then + echo "Usage: hydra [hydra] register <path>" + exit 1 +elif grep -q -e "^$HYDRA=" $CONFIG &> /dev/null; then + echo "Hydra $HYDRA already registered" + exit 1 +elif [ ! -d "$BASEDIR" ]; then + echo "Folder $BASEDIR does not exists, maybe you want to run 'hydra $HYDRA init'?" + exit 1 +fi + +# Reparse basedir to force absolute folder +BASEDIR="`cd $BASEDIR && pwd`" + +# Add entry +echo "Registering hydra $HYDRA..." +chmod 700 $BASEDIR +echo "$HYDRA=\"$BASEDIR\"" >> $CONFIG diff --git a/share/hydra/sync b/share/hydra/sync index 3406014..9b1d097 100755 --- a/share/hydra/sync +++ b/share/hydra/sync @@ -21,6 +21,10 @@ hydra_config_load # Sync each repository. function hydra_sync { for repository in $*; do + if [ -e "$HYDRA_FOLDER/config/repository/ignore/$repository" ]; then + continue + fi + if [ "$repository" == "keyringer" ]; then UPDATE_KEYRINGER="yes" continue @@ -38,7 +42,7 @@ function hydra_sync { url="git@admin.`cat $HYDRA_FOLDER/config/domain`:$repository" fi - git clone $url $HYDRA_FOLDER/$repository + git clone ${url}${repository} $HYDRA_FOLDER/$repository fi if [ -d "$HYDRA_FOLDER/$repository/.git" ]; then diff --git a/share/hydractl/deploy b/share/hydractl/deploy deleted file mode 100755 index 191b060..0000000 --- a/share/hydractl/deploy +++ /dev/null @@ -1,58 +0,0 @@ -#!/bin/bash -# -# Deploy a node using automated recipes. -# -# This program is free software: you can redistribute it and/or modify -# it under the terms of the GNU Affero General Public License as -# published by the Free Software Foundation, either version 3 of the -# License, or (at your option) any later version. -# -# This program 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 Affero General Public License for more details. -# -# You should have received a copy of the GNU Affero General Public -# License along with this program. If not, see -# <http://www.gnu.org/licenses/>. - -# Load. -source $APP_BASE/lib/hydra/functions || exit 1 -hydra_config_load - -# Parameters -FOLDER="$1" - -# Dispatch -if [ ! -z "$FOLDER" ]; then - echo "Deploying to $FOLDER..." - - # Setup deploy environment - hydra_deploy_setyp remote $node - hydra_deploy_mkdirs - - # Sync repository to server - $DEPLOY_RSYNC - - # Copy hiera configuration - hydra_hiera_copy - - # Check if puppet is installed - if [ ! -e "$FOLDER/usr/bin/puppet" ]; then - $DEPLOY_COMMAND apt-get install puppet -y - fi - - # Run puppet, overriding FQDN - FACTER_domain=$DOMAIN FACTER_hostname=$HOSTNAME FACTER_fqdn=$HOSTNAME.$DOMAIN $DEPLOY_APPLY -elif [ -e "$HYDRA_FOLDER/puppet/manifests/nodes/$FQDN.pp" ]; then - echo "Deploying to localhost..." - - # Setup deploy environment - hydra_deploy_setup - - # Check if puppet is installed - hydra_install_package puppet - - # Run puppet - $DEPLOY_APPLY -fi diff --git a/share/hydractl/install b/share/hydractl/install index 0f43b4f..baae176 100755 --- a/share/hydractl/install +++ b/share/hydractl/install @@ -35,8 +35,8 @@ echo "Installing to local node..." if ! which git &> /dev/null; then echo "Installing git..." - $sudo aptitude update - $sudo aptitude install git-core -y + $sudo apt-get update + $sudo apt-get install git-core -y fi # Git version diff --git a/share/hydractl/provision b/share/hydractl/provision index 087b703..1a9b98d 100755 --- a/share/hydractl/provision +++ b/share/hydractl/provision @@ -94,7 +94,7 @@ function hydra_provision_config { hydra_user_config interactive y "Interactive mode? (y/n)" hydra_user_config device /dev/sdb "Destination device" - hydra_user_config root_size 20G "Size of root partition" + hydra_user_config root_size 20G "Size of root partition (-1 for all free space)" hydra_user_config swap_size 2000 "Swap size (in MB, 0 to not create it)" hydra_user_config home_size 20G "Size of home partition (0 to not create it, -1 for all free space)" hydra_user_config var_size 20G "Size of var partition (0 to not create it, -1 for all free space)" @@ -402,11 +402,8 @@ else kernel_arch="$arch" fi -if [ "$version" == "squeeze" ]; then - hydra_sudo_run chroot $WORK apt-get install linux-image-2.6-vserver-$kernel_arch -y -else - hydra_sudo_run chroot $WORK apt-get install linux-image-$kernel_arch -y -fi +# Kernel. +hydra_sudo_run chroot $WORK apt-get install linux-image-$kernel_arch -y # Initramfs. echo "Creating initramfs..." diff --git a/share/hydractl/provision-chroot b/share/hydractl/provision-chroot index 7910879..bd7430a 100755 --- a/share/hydractl/provision-chroot +++ b/share/hydractl/provision-chroot @@ -34,26 +34,30 @@ function hydra_provision_config { # Load configuration hydra_provision_config_load $1 +# Get config parameters. +hydra_provision_config + # Parameters WORK="$folder" CHROOT="hydra_sudo_run chroot $WORK" -# Get config parameters. -hydra_provision_config - # Check for requirements. for req in debootstrap qemu-user-static; do hydra_install_package $req done hydra_sudo_run mkdir -p /var/chroot -hydra_sudo_run sudo debootstrap --variant=minbase --arch $arch $version $WORK $mirror +hydra_sudo_run debootstrap --variant=minbase --arch $arch $version $WORK $mirror # Arch specific procedures -if [ "$arch" != "armel" ] && [ "$arch" != "armhf" ]; then +if [ "$arch" == "armel" ] || [ "$arch" == "armhf" ]; then + if [ ! -f '/usr/bin/qemu-arm-static' ]; then + hydra_sudo run apt-get install qemu-user-static + fi + hydra_sudo_run cp /usr/bin/qemu-arm-static $WORK/usr/bin/ $CHROOT /debootstrap/debootstrap --second-stage fi -echo "$hostname.$domain" | hydra_sudo_run tee /var/chroot/squeeze/etc/hostname > /dev/null +echo "$hostname.$domain" | hydra_sudo_run tee $WORK/etc/hostname > /dev/null $CHROOT apt-get install locales diff --git a/share/hydractl/provision-raspi b/share/hydractl/provision-raspi index 38bc0b7..6495de4 100755 --- a/share/hydractl/provision-raspi +++ b/share/hydractl/provision-raspi @@ -79,7 +79,7 @@ echo "deb http://security.debian.org/ $version/updates main contrib non-free" | # Basic packages $CHROOT apt-get update $CHROOT apt-get install -y locales && $CHROOT dpkg-reconfigure locales -$CHROOT apt-get install -y screen cron lsb-release openssl openssh-server less ntp +$CHROOT apt-get install -y screen cron lsb-release openssl openssh-server less ntp curl # Hostname echo $hostname.$domain | hydra_sudo_run tee $WORK/etc/hostname > /dev/null diff --git a/share/hydractl/upgrade b/share/hydractl/upgrade index e3c1141..350d795 100755 --- a/share/hydractl/upgrade +++ b/share/hydractl/upgrade @@ -26,8 +26,8 @@ fi # Issue upgrade if ! $sudo lsof /var/lib/dpkg/lock &> /dev/null; then - $sudo aptitude update - $sudo aptitude full-upgrade -y + $sudo apt-get update + $sudo apt-get dist-upgrade -y else echo "Apt is locked, aborting." fi @@ -39,6 +39,6 @@ hydractl chroot-upgrade hydractl pbuilder-upgrade # Cleanup -if [ "$CLEAN" == "clean" ]; then - $sudo aptitude clean +if [ "$CLEAN" != "noclean" ]; then + $sudo apt-get clean fi |