
This commit adds the --snapshot option to the deploy precheck and start commands, to enable the lvm snapshot feature that will be integrated with the USM upgrades in a future commit. The deploy-precheck script is also changed, and a placeholder message is added to it's output, to be replaced by the real health checks in a separate commit. Test Plan PASS: verify deploy [precheck|start] help shows the new option PASS: run deploy precheck with the new option (precheck support for the new option is part of another commit) PASS: run deploy start with the new option, verify the deployment is created with the new option set as True PASS: run deploy start without the new option, verify the deployment is created with the new option set as False Story: 2011357 Task: 51928 Change-Id: Id7996894601de3331853d5122b07e453d2f2fbcc Signed-off-by: Heitor Matsui <heitorvieira.matsui@windriver.com>
199 lines
5.3 KiB
Python
199 lines
5.3 KiB
Python
#
|
|
# Copyright (c) 2015-2024 Wind River Systems, Inc.
|
|
#
|
|
# SPDX-License-Identifier: Apache-2.0
|
|
#
|
|
|
|
import re
|
|
import requests
|
|
import signal
|
|
import time
|
|
|
|
from software_client.common import base
|
|
from software_client.common import utils
|
|
from software_client import constants
|
|
|
|
|
|
class Deploy(base.Resource):
|
|
def __repr__(self):
|
|
return "<address pool %s>" % self._info
|
|
|
|
|
|
class DeployManager(base.Manager):
|
|
resource_class = Deploy
|
|
|
|
def precheck(self, args):
|
|
# args.deployment is a string
|
|
deployment = args.deployment
|
|
|
|
path = "/v1/deploy/%s/precheck" % (deployment)
|
|
body = {}
|
|
if args.force:
|
|
body["force"] = "true"
|
|
if args.snapshot:
|
|
body["snapshot"] = "true"
|
|
|
|
if args.region_name:
|
|
body["region_name"] = args.region_name
|
|
|
|
res = self._post(path, body=body)
|
|
return res
|
|
|
|
def start(self, args):
|
|
# args.deployment is a string
|
|
deployment = args.deployment
|
|
|
|
# Ignore interrupts during this function
|
|
signal.signal(signal.SIGINT, signal.SIG_IGN)
|
|
|
|
# Issue deploy_start request
|
|
path = "/v1/deploy/%s/start" % (deployment)
|
|
body = {}
|
|
if args.force:
|
|
body["force"] = "true"
|
|
if args.snapshot:
|
|
body["snapshot"] = "true"
|
|
|
|
return self._post(path, body=body)
|
|
|
|
def host(self, args):
|
|
# args.deployment is a string
|
|
hostname = args.host
|
|
|
|
# Issue deploy_host request and poll for results
|
|
path = "/v1/deploy_host/%s" % hostname
|
|
|
|
if args.force:
|
|
path += "/force"
|
|
|
|
return self._create(path)
|
|
|
|
def host_rollback(self, args):
|
|
# args.deployment is a string
|
|
hostname = args.host
|
|
|
|
# Issue deploy_host request and poll for results
|
|
path = "/v1/deploy_host/%s/rollback" % hostname
|
|
|
|
if args.force:
|
|
path += "/force"
|
|
|
|
return self._create(path)
|
|
|
|
def abort(self, args):
|
|
# Ignore interrupts during this function
|
|
signal.signal(signal.SIGINT, signal.SIG_IGN)
|
|
|
|
# Issue deploy_abort request
|
|
path = "/v1/deploy/abort"
|
|
|
|
return self._create(path, body={})
|
|
|
|
def activate(self, args):
|
|
# Ignore interrupts during this function
|
|
signal.signal(signal.SIGINT, signal.SIG_IGN)
|
|
|
|
# Issue deploy_start request
|
|
path = "/v1/deploy/activate"
|
|
|
|
return self._create(path, body={})
|
|
|
|
def activate_rollback(self, args):
|
|
# Ignore interrupts during this function
|
|
signal.signal(signal.SIGINT, signal.SIG_IGN)
|
|
|
|
# Issue deploy_start request
|
|
path = "/v1/deploy/activate_rollback"
|
|
|
|
return self._create(path, body={})
|
|
|
|
def complete(self, args):
|
|
# Ignore interrupts during this function
|
|
signal.signal(signal.SIGINT, signal.SIG_IGN)
|
|
|
|
# Issue deploy_start request
|
|
path = "/v1/deploy/complete"
|
|
|
|
return self._create(path, body={})
|
|
|
|
def delete(self, args):
|
|
# Ignore interrupts during this function
|
|
signal.signal(signal.SIGINT, signal.SIG_IGN)
|
|
|
|
# Issue deploy delete request
|
|
path = "/v1/deploy"
|
|
|
|
return self._delete(path)
|
|
|
|
def host_list(self):
|
|
path = '/v1/deploy_host'
|
|
return self._list(path, "")
|
|
|
|
def show(self):
|
|
path = '/v1/deploy'
|
|
return self._list(path)
|
|
|
|
def wait_for_install_complete(self, hostname):
|
|
url = "/v1/deploy_host"
|
|
rc = 0
|
|
|
|
max_retries = 4
|
|
retriable_count = 0
|
|
|
|
while True:
|
|
# Sleep on the first pass as well, to allow time for the
|
|
# agent to respond
|
|
time.sleep(5)
|
|
|
|
try:
|
|
req, data = self._list(url)
|
|
except requests.exceptions.ConnectionError:
|
|
# The local software-controller may have restarted.
|
|
retriable_count += 1
|
|
if retriable_count > max_retries:
|
|
print("Lost communications with the software controller")
|
|
rc = 1
|
|
return rc
|
|
else:
|
|
break
|
|
|
|
if req.status_code == 200:
|
|
if not data:
|
|
print("Invalid host-list data returned:")
|
|
utils.print_result_debug(req, data)
|
|
rc = 1
|
|
|
|
host_state = None
|
|
|
|
for d in data:
|
|
if d['hostname'] == hostname:
|
|
host_state = d.get('host_state')
|
|
|
|
if host_state == constants.DEPLOYING:
|
|
print("\nDeployment started.")
|
|
rc = 0
|
|
elif host_state == constants.FAILED:
|
|
print("\nDeployment failed. Please check logs for details.")
|
|
rc = 1
|
|
elif host_state == constants.DEPLOYED:
|
|
print("\nDeployment was successful.")
|
|
rc = 0
|
|
elif host_state == constants.PENDING:
|
|
print("\nDeployment pending.")
|
|
else:
|
|
print("\nReported unknown state: %s" % host_state)
|
|
rc = 1
|
|
|
|
elif req.status_code == 500:
|
|
print("An internal error has occurred. Please check /var/log/software.log for details")
|
|
rc = 1
|
|
else:
|
|
m = re.search("(Error message:.*)", req.text, re.MULTILINE)
|
|
if m:
|
|
print(m.group(0))
|
|
else:
|
|
print(vars(req))
|
|
rc = 1
|
|
|
|
return rc
|