Skip to content

Commit

Permalink
added new module to activate upgraded packages due to install intermi…
Browse files Browse the repository at this point in the history
…ttent bug
  • Loading branch information
Adisorn Ermongkonchai committed Jun 24, 2016
1 parent f51eef0 commit 7b65643
Show file tree
Hide file tree
Showing 7 changed files with 504 additions and 23 deletions.
10 changes: 5 additions & 5 deletions local/library/iosxr_install_package
Original file line number Diff line number Diff line change
Expand Up @@ -134,10 +134,10 @@ def wait_install_response(module, oper_id):
response = list()
for inst_id in oper_id:
command = "show install log " + inst_id
response.append(execute_command(module, command))
for rmsg in response[0]:
if 'aborted' in rmsg:
module.fail_json(msg=rmsg)
rmsg = module.execute(command)
if 'aborted' in rmsg[0]:
module.fail_json(msg=rmsg[0])
response.append(rmsg[0])
return response
else:
module.fail_json(msg="timeout waiting for install to complete")
Expand Down Expand Up @@ -289,7 +289,7 @@ def main():

# make sure no other install in progress
if is_install_in_progress(module):
module.fail_json(msg="other install op in progress")
module.fail_json(msg="other install operation in progress")

install = {
'present': install_add,
Expand Down
129 changes: 129 additions & 0 deletions local/library/iosxr_upgrade_activate
Original file line number Diff line number Diff line change
@@ -0,0 +1,129 @@
#!/usr/bin/python
#------------------------------------------------------------------------------
#
# Copyright (C) 2016 Cisco Systems, Inc.
#
# This program 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.
#
# 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 General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
#------------------------------------------------------------------------------

from ansible.module_utils.basic import *
from ansible.module_utils.shell import *
from ansible.module_utils.netcfg import *
from ansible.module_utils.iosxr import *
from iosxr_common import *

DOCUMENTATION = """
---
module: iosxr_upgrade_activate
author: Adisorn Ermongkonchai
short_description: Activate packages in IOS-XR repository.
description:
- Activate IOS-XR packages in IOS-XR repository.
options:
host:
description:
- IP address or hostname (resolvable by Ansible control host) of
the target IOS-XR node.
required: true
username:
description:
- username used to login to IOS-XR
required: true
default: none
password:
description:
- password used to login to IOS-XR
required: true
default: none
pkgname:
description:
- IOS-XR software packages in the repository
NOTE: use 'show install inactive' to see packages in repository
required: true
"""

EXAMPLES = """
- iosxr_upgrade_activate:
host: '{{ ansible_ssh_host }}'
username: cisco
pkgname: 'xrv9k-mgbl-3.0.0.0-r60204I xrv9k-k9sec-2.0.0.0-r60204I'
"""

RETURN = """
stdout:
description: raw response
returned: always
stdout_lines:
description: list of response lines
returned: always
"""

# check if another install command in progress
def is_legacy_iosxr(module):
command = "show version"
response = execute_command(module, command)
return "Build Information:" not in response[0]

# check if another install command in progress
def is_install_in_progress(module):
command = "show install request"
response = execute_command(module, command)
return "No install operation in progress" not in response[0]

CLI_PROMPTS_RE.append(re.compile(r'[\r\n]?\[yes\/no]:\[\w+]\s'))

def main():
module = get_module(
argument_spec = dict(
username = dict(required=False, default=None),
password = dict(required=False, default=None),
pkgname = dict(required=True, default=None),
),
supports_check_mode = False
)
args = module.params
pkg_name = args['pkgname']

# cannot run on classic XR
if is_legacy_iosxr(module):
module.fail_json(msg='this upgrade module cannot run on 32-bit IOS-XR')

# make sure no other install in progress
if is_install_in_progress(module):
module.fail_json(msg='other install operation in progress')

# ignore timeout
module.connection.shell.shell.settimeout(None)

# run install activate command
commands = [ 'install activate ' + pkg_name ]
commands.append('yes\n')

response = execute_command(module, commands)
while True:
try:
if not is_install_in_progress(module):
break
except:
break

result = dict(changed=True)
result['stdout'] = response
result['stdout_lines'] = str(result['stdout']).split(r'\n')

module.exit_json(**result)

if __name__ == "__main__":
main()
61 changes: 47 additions & 14 deletions local/library/iosxr_upgrade_package
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,11 @@ options:
- password used to login to IOS-XR
required: true
default: none
confirm:
description:
- make sure user really want to reload
required: true
value: "yes" or other string
version:
description:
- new software version
Expand Down Expand Up @@ -75,6 +80,7 @@ EXAMPLES = """
host: '{{ ansible_ssh_host }}'
username: cisco
version: 6.1.1
confirm: yes
pkgpath: "https://secure_server_name"
"""

Expand Down Expand Up @@ -105,6 +111,7 @@ def main():
username = dict(required=False, default=None),
password = dict(required=False, default=None),
version = dict(required=True, default=None),
confirm = dict(required=True),
pkgpath = dict(required=True, default=None),
pkgname = dict(required=False, default=""),
),
Expand All @@ -115,32 +122,58 @@ def main():
pkg_path = args['pkgpath']
pkg_name = args['pkgname']

# confirm upgrade
if args['confirm'] != 'yes':
module.fail_json(msg='upgrade aborted')

# cannot run on classic XR
if is_legacy_iosxr(module):
module.fail_json(msg="install upgrade cannot run on 32-bit IOS-XR")
module.fail_json(msg='this upgrade module cannot run on 32-bit IOS-XR')

# make sure no other install in progress
if is_install_in_progress(module):
module.fail_json(msg="other install op in progress")
module.fail_json(msg='other install operation in progress')

# ignore timeout
module.connection.shell.shell.settimeout(None)

# run install upgrade command
command = ('install upgrade source ' +
pkg_path + ' version ' + version + ' ' + pkg_name + '\r')
pkg_path + ' version ' + version + ' ' + pkg_name + '\n')
module.connection.shell.shell.send(command)

try:
# collect all responses 1024 bytes at a time
prompt = re.compile(r'[\r\n]?[\w+\-\.:\/\[\]]+(?:>|#)')
response = module.connection.shell.shell.recv(1024)
while not prompt.search(response):
response = ''
prompt = re.compile(r'[\r\n]?[\w+\-\.:\/\[\]]+(?:>|#)')
ask = re.compile(r'[\r\n]?\[yes\/no]:\[\w+]\s')

# wait for either command prompt or activate prompt
while True:
try:
response += module.connection.shell.shell.recv(1024)
except:
response += '\r\nNOTE: install upgrade is running in background and can take a long time, use "show install <request|log>" command to check its status\r\n'
pass

# check result
if 'aborted' in response:
module.fail_json(msg=response)
# if activate prompt then send yes
if ask.search(response):
module.connection.shell.shell.send('yes\n')
break

# if command prompt then it probably is error response
elif prompt.search(response):
if 'aborted' in response:
module.fail_json(msg=response)
break
except:
break

# now wait till reload
while True:
try:
# install operation done
if not is_install_in_progress(module):
break
sleep(5)
# or socket exception when reload
except:
break

# show result
result = dict(changed=True)
Expand Down
13 changes: 13 additions & 0 deletions local/samples/iosxr_upgrade_activate.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
---
- hosts: 192.168.1.5
connection: local
gather_facts: no

tasks:
- name: activate packages
iosxr_upgrade_activate:
host: '{{ ansible_host }}'
username: '{{ ansible_ssh_user }}'
pkgname: 'xrv9k-mini-x-6.1.1.19I xrv9k-mgbl-3.0.0.0-r61119I xrv9k-k9sec-3.1.0.0-r61119I xrv9k-ospf-1.0.0.0-r61119I'
register: output
- debug: var=output.stdout_lines
13 changes: 9 additions & 4 deletions local/samples/iosxr_upgrade_package.yml
Original file line number Diff line number Diff line change
@@ -1,15 +1,20 @@
---
- hosts: ss-xr
- hosts: 192.168.1.5
connection: local
gather_facts: no

vars_prompt:
- name: yesno
prompt: 'Upgrade can take an hour to finish, are you sure you want to contiue (yes/no)? '

tasks:
- name: upgrade IOS-XR software version
- name: upgrade IOS-XR software version, please do not hit Ctrl-C
iosxr_upgrade_package:
host: '{{ ansible_host }}'
username: '{{ ansible_ssh_user }}'
confirm: '{{ yesno }}'
version: '6.1.1'
pkgpath: 'https://aermongk-dev'
#pkgname: 'xrv9k-mpls-2.0.0.0-r60204I.x86_64.rpm'
pkgpath: 'tftp://192.168.1.1/6.1.1'
pkgname: 'xrv9k-k9sec-3.1.0.0-r61119I.x86_64.rpm xrv9k-mgbl-3.0.0.0-r61119I.x86_64.rpm xrv9k-ospf-1.0.0.0-r61119I.x86_64.rpm'
register: output
- debug: var=output.stdout_lines
Loading

0 comments on commit 7b65643

Please sign in to comment.