Enable reapply mode

Allows redeployment without providing any input SLAVE_IPS.

Changes in workflow:
* If you set env REAPPLY=yes and ADMIN_IP, fuel_devops is skipped
* If inventory exists and SLAVE_IPS is unset, it retrives SLAVE_IPS
  from inventory.
* Deploy fails if REAPPLY is set, but ADMIN_IP is unset.

Changes to inventory.py:
* Added new functions help, print_cfg, print_ips
* Default to print help if invoked with no args

Change-Id: I9729e326e3fe5b413e01d8ae8410916b555c0c99
This commit is contained in:
Matthew Mosesohn 2016-08-09 18:15:28 +03:00
parent 099686b2ca
commit 4aa7cf7a65
3 changed files with 63 additions and 7 deletions

View File

@ -12,6 +12,7 @@
# License for the specific language governing permissions and limitations
# under the License.
import mock
import unittest
from collections import OrderedDict
@ -25,7 +26,9 @@ import inventory
class TestInventory(unittest.TestCase):
def setUp(self):
@mock.patch('inventory.sys')
def setUp(self, sys_mock):
sys_mock.exit = mock.Mock()
super(TestInventory, self).setUp()
self.data = ['10.90.3.2', '10.90.3.3', '10.90.3.4']
self.inv = inventory.KargoInventory()

View File

@ -103,7 +103,7 @@ function wait_for_nodes {
mkdir -p tmp logs
# Allow non-Jenkins script to predefine info
if [[ -z "$SLAVE_IPS" && -z "$ADMIN_IP" ]]; then
if [[ -z "$REAPPLY" && -z "$SLAVE_IPS" && -z "$ADMIN_IP" ]]; then
ENV_TYPE="fuel-devops"
dos.py erase ${ENV_NAME} || true
rm -rf logs/*
@ -114,7 +114,7 @@ if [[ -z "$SLAVE_IPS" && -z "$ADMIN_IP" ]]; then
ADMIN_IP=${SLAVE_IPS[0]}
wait_for_nodes $ADMIN_IP
else
ENV_TYPE=${ENV_TYPE:-other}
ENV_TYPE=${ENV_TYPE:-other_or_reapply}
SLAVE_IPS=( $SLAVE_IPS )
ADMIN_IP=${ADMIN_IP:-${SLAVE_IPS[0]}}
fi
@ -193,8 +193,18 @@ if [ -n "$CUSTOM_YAML" ]; then
custom_opts="-e @$ADMIN_WORKSPACE/kargo/custom.yaml"
fi
echo "Generating ansible inventory on admin node..."
admin_node_command CONFIG_FILE=$ADMIN_WORKSPACE/kargo/inventory/inventory.cfg python3 $ADMIN_WORKSPACE/utils/kargo/inventory.py ${SLAVE_IPS[@]}
# Try to get IPs from inventory if it isn't provided
if [[ -z "$SLAVE_IPS" ]]; then
if admin_node_command stat $ADMIN_WORKSPACE/kargo/inventory/inventory.cfg; then
SLAVE_IPS=($(admin_node_command CONFIG_FILE=$ADMIN_WORKSPACE/kargo/inventory/inventory.cfg python3 $ADMIN_WORKSPACE/utils/kargo/inventory.py print_ips))
else
echo "No slave nodes available. Unable to proceed!"
exit_gracefully 1
fi
else
echo "Generating ansible inventory on admin node..."
admin_node_command CONFIG_FILE=$ADMIN_WORKSPACE/kargo/inventory/inventory.cfg python3 $ADMIN_WORKSPACE/utils/kargo/inventory.py ${SLAVE_IPS[@]}
fi
echo "Waiting for all nodes to be reachable by SSH..."
wait_for_nodes ${SLAVE_IPS[@]}
@ -292,5 +302,6 @@ set -x
rm -f VLAN_IPS
fi
# TODO(mattymo): Shift to FORCE_NEW instead of REAPPLY
echo "To reapply deployment, run env REAPPLY=yes ADMIN_IP=$ADMIN_IP $0"
exit_gracefully ${deploy_res}

View File

@ -1,4 +1,4 @@
#!/usr/bin/python
#!/usr/bin/python3
# Usage: kargo_inventory.py ip1 [ip2 ...]
# Examples: kargo_inventory.py 10.10.1.3 10.10.1.4 10.10.1.5
#
@ -19,6 +19,7 @@ import sys
ROLES = ['kube-master', 'all', 'k8s-cluster:children', 'kube-node', 'etcd']
PROTECTED_NAMES = ROLES
AVAILABLE_COMMANDS = ['help', 'print_cfg', 'print_ips']
_boolean_states = {'1': True, 'yes': True, 'true': True, 'on': True,
'0': False, 'no': False, 'false': False, 'off': False}
@ -40,6 +41,10 @@ class KargoInventory(object):
if config_file:
self.config.read(config_file)
if changed_hosts and changed_hosts[0] in AVAILABLE_COMMANDS:
self.parse_command(changed_hosts[0], changed_hosts[1:])
sys.exit(0)
self.ensure_required_groups(ROLES)
if changed_hosts:
@ -50,6 +55,9 @@ class KargoInventory(object):
self.set_k8s_cluster()
self.set_kube_node(self.hosts.keys())
self.set_etcd(list(self.hosts.keys())[:3])
else: # Show help if no options
self.show_help()
sys.exit(0)
if config_file:
with open(config_file, 'w') as f:
@ -174,6 +182,40 @@ class KargoInventory(object):
for host in hosts:
self.add_host_to_group('etcd', host)
def parse_command(self, command, args=None):
if command == 'help':
self.show_help()
elif command == 'print_cfg':
self.print_config()
elif command == 'print_ips':
self.print_ips()
else:
raise Exception("Invalid command specified.")
def show_help(self):
help_text = '''Usage: inventory.py ip1 [ip2 ...]
Examples: inventory.py 10.10.1.3 10.10.1.4 10.10.1.5
Available commands:
help - Display this message
print_cfg - Write inventory file to stdout
print_ips - Write a space-delimited list of IPs from "all" group
Advanced usage:
Add another host after initial creation: inventory.py 10.10.1.5
Delete a host: inventory.py -10.10.1.3
Delete a host by id: inventory.py -node1'''
print(help_text)
def print_config(self):
self.config.write(sys.stdout)
def print_ips(self):
ips = []
for host, opts in self.config.items('all'):
ips.append(self.get_ip_from_opts(opts))
print(' '.join(ips))
def main(argv=None):
if not argv: