gNOI Operating System (OS) Service
Use the gNOI operating system (OS
) service to upgrade the software
on the target network device.
You can use the gNOI OS
service to upgrade software on the target
device. The proto definition file is located at https://github.com/openconfig/gnoi/blob/master/os/os.proto.
Software installation has three main steps, which correspond to the OS
service RPCs.
- Install
- Activate
- Verify
You can use the OS
service RPCs to transfer a software installation
package to the device, validate the configuration against a specified software version,
and install software. You can also set an installed software version as the next boot
version and verify the software version.
You can also use the gNOI system
service
SetPackage()
RPC to install software on a device. For more
information, see gNOI System Service.
Supported RPCs
RPC | Description | Introduced in Release |
---|---|---|
Activate() |
Set the software version that is used at the next reboot.
Note:
Junos devices do not support the Note:
Prior to Junos OS Evolved Release 25.2R1,
|
Junos OS Evolved 22.2R1 |
Install() |
Transfer a software installation package to the target, validate the configuration against the software, and install (stage) the software. If the specified software image is already installed on the device, validate the current configuration against the software image and store the validated configuration as the running configuration associated with that software version. Note:
Junos devices do not support the Note:
Prior to Junos OS Evolved Release 25.2R1,
|
Junos OS Evolved 22.2R1 |
Verify() |
Check the running software version. This RPC may be called multiple times while the target boots until successful. Note:
Junos devices do not support |
Junos OS Evolved 22.2R1 |
OS Service Overview
The gNOI OS
service RPCs enable you to manage the software on
devices running Junos OS Evolved. Junos OS Evolved stores multiple versions of
software on the storage media. For each software version, Junos OS Evolved also
stores the configuration that was running at the time the software version was
running last.
Table 2 outlines the RPC operations in the different Junos OS Evolved releases. Starting in Junos OS Evolved Release 25.2R1, you can install software without immediate activation, validate the current configuration against any installed software version, and activate any installed software version.
RPC |
Junos OS Evolved Release 24.4R1 and Earlier |
Junos OS Evolved Release 25.2R1 and Later |
---|---|---|
|
Transfer the software installation package to the device. |
Transfer the software installation package to the device. |
– |
Validate the current configuration against the specified software version (new or previously installed). |
|
– |
Install the software, if the specified software version is not already installed. |
|
– |
Store the validated current configuration as the running configuration associated with the specified software version. |
|
|
Validate the current configuration against the specified software version. |
– |
Install the software. |
– | |
Set the specified software version as the next boot version. |
Set the specified software version as the next boot version. |
|
(Optional) Reboot the device. |
(Optional) Reboot the device. |
|
|
Check the running software version. |
Check the running software version. |
In Junos OS Evolved Release 25.2R1 and later, the Install()
RPC
transfers the specified software installation package to the
/var/tmp/
directory on the target device, validates the
configuration against the software, and installs the software, if that software
version is not already installed on the device. The destination filename is the
value defined in the TransferRequest
message's
version
field. The Activate()
RPC sets the
specified software version as the next boot version and optionally reboots the
device to activate the software. You can activate any installed software
version.
If you run Install()
and specify an existing software version,
Install()
validates the current configuration against the
software and stores the validated configuration as the running configuration
associated with that software version. If the software version is set as the next
boot version, Install()
deactivates it in the process. Thus you can
verify that a specific software version will work with any recent configuration
changes.
Network Device Configuration
Before you begin:
- Configure gRPC services on the network device as described in Configure gRPC Services.
- Configure the network management system to support gNOI operations as described in Configure gNOI Services.
No additional configuration is required to use the OS
service
RPCs.
Example: Install and Activate
In this example, the client executes the gnoi_os_install_activate.py
Python application, which performs the following operations:
-
Copies the software package from the local network management system to the network device.
-
Validates the configuration against the software image.
-
Installs the package on the network device.
-
Reboots the network device, thus activating the new software image.
The application calls the Install()
RPC with the
InstallRequest()
message to transfer the file. The application
tracks the progress of the file transfer by emitting progress messages at each 10
percent transfer completion interval. If the file transfer is successful, the system
validates the configuration against the software image, performs a storage cleanup,
and installs the image. The application then calls the Activate()
RPC to set the new image as the next boot image and reboot the target.
The application imports the grpc_channel
module to establish the
channel. The grpc_channel
module is described in Configure gNOI Services. The application's
arguments are stored in the args_os_install_activate.txt
file. The
application and argument files are as follows:
gnoi_os_install_activate.py
"""gRPC gNOI OS Install, Activate utility.""" from __future__ import print_function import argparse import logging import os from functools import partial from getpass import getpass import os_pb2 import os_pb2_grpc from grpc_channel import grpc_authenticate_channel_mutual MAX_BYTES = 65536 def get_args(parser): parser.add_argument('--server', dest='server', type=str, default='localhost', help='Server IP or name. Default is localhost') parser.add_argument('--port', dest='port', nargs='?', type=int, default=32767, help='The server port. Default is 32767') parser.add_argument('--client_key', dest='client_key', type=str, default='', help='Full path of the client private key. Default ""') parser.add_argument('--client_cert', dest='client_cert', type=str, default='', help='Full path of the client certificate. Default ""') parser.add_argument('--root_ca_cert', dest='root_ca_cert', required=True, type=str, help='Full path of the Root CA certificate.') parser.add_argument('--user_id', dest='user_id', required=True, type=str, help='User ID for RPC call credentials.') parser.add_argument('--no_reboot', dest='no_reboot', type=int, default=0, help='Reboot immediately or not. Default 0 (Reboot immediately)') parser.add_argument('--source_package', dest='source_package', type=str, default='', help='Full path of the install file. Default ""') parser.add_argument('--timeout', dest='timeout', type=int, default=600, help='Timeout in seconds. Default 600') parser.add_argument('--version', dest='version', type=str, default='', help='Software version. Default is ""') args = parser.parse_args() return args def send_rpc(channel, metadata, args): print("Executing GNOI::OS::Install") stub = os_pb2_grpc.OSStub(channel) it = [] # Create file transfer request req = os_pb2.InstallRequest() req.transfer_request.version = args.version it.append(req) # Read source package and add to request source_package_bytes = os.path.getsize(args.source_package) with open(args.source_package, "rb") as file: # Read data in 64 KB chunks and calculate checksum and data messages for data in iter(partial(file.read, MAX_BYTES), b''): req = os_pb2.InstallRequest() req.transfer_content = data it.append(req) req = os_pb2.InstallRequest() req.transfer_end.SetInParent() it.append(req) next_pct = 0 transfer_percent = 0 validated = False activated = False try: responses = stub.Install( iter(it), metadata=metadata, timeout=args.timeout) print("OS Install start\n") for response in responses: rsp_type = response.WhichOneof('response') if rsp_type == 'install_error': print("%s: %s -- %s\n" % (rsp_type, response.install_error.type, response.install_error.detail)) raise Exception("Install Error") elif rsp_type == 'transfer_ready': print("%s: %s\n" % (rsp_type, response.transfer_ready)) elif rsp_type == 'transfer_progress': transfer_percent = int(float( response.transfer_progress.bytes_received) / float(source_package_bytes) * 100) if 0 == (transfer_percent % 10) and transfer_percent != next_pct: next_pct = transfer_percent print("Transfer percent complete: %s%%" % transfer_percent) logging.info('Transferring file %s%%', transfer_percent) elif rsp_type == 'validated': print("%s: %s -- %s\n" % (rsp_type, response.validated.version, response.validated.description)) logging.info('Validated: %s', response.validated.version) validated = True if transfer_percent > 0 and validated: print("Executing GNOI::OS::Activate") req = os_pb2.ActivateRequest() req.version = args.version req.no_reboot = args.no_reboot activate_response = stub.Activate( req, metadata=metadata, timeout=args.timeout) rsp_type = activate_response.WhichOneof('response') if rsp_type == 'activate_ok': activated = True except Exception as e: logging.error('Error installing package: %s', e) print(e) else: if activated: logging.info('Installation complete: %s', args.version) print('Installation complete for %s' % args.version) def main(): parser = argparse.ArgumentParser(fromfile_prefix_chars='@') args = get_args(parser) grpc_server_password = getpass("gRPC server password for executing RPCs: ") metadata = [('username', args.user_id), ('password', grpc_server_password)] try: # Establish grpc channel to network device channel = grpc_authenticate_channel_mutual( args.server, args.port, args.root_ca_cert, args.client_key, args.client_cert) response = send_rpc(channel, metadata, args) except Exception as e: logging.error('Received error: %s', e) print(e) if __name__ == '__main__': logging.basicConfig(filename='gnoi-install.log', format='%(asctime)s %(levelname)-8s %(message)s', level=logging.INFO, datefmt='%Y-%m-%d %H:%M:%S') main()
args_os_install_activate.txt
--root_ca_cert=/etc/pki/certs/serverRootCA.crt --client_key=/home/lab/certs/client.key --client_cert=/home/lab/certs/client.crt --server=10.53.52.169 --port=32767 --user_id=gnoi-user --source_package=/home/lab/images/junos-evo-install-ptx-x86-64-25.2R1.9-EVO.iso --timeout=1800 --version=25.2R1.9-EVO
Starting in Junos OS Evolved Release 23.4R1, the version
field in the Activate()
, Install()
, and
Verify()
RPCs uses the software version string (as
displayed in /system/state/software-version
) instead of the
package name.
Execute the Application
When the client executes the application, the application copies the package from
the local device to the /var/tmp
directory on the network
device, installs the package, and then reboots the device to complete the
installation.
lab@gnoi-client:~/src/gnoi/proto$ python3 gnoi_os_install_activate.py @args_os_install_activate.txt gRPC server password for executing RPCs: Creating channel Executing GNOI::OS::Install OS Install start transfer_ready: Transfer percent complete: 10% Transfer percent complete: 20% Transfer percent complete: 30% Transfer percent complete: 40% Transfer percent complete: 50% Transfer percent complete: 60% Transfer percent complete: 70% Transfer percent complete: 80% Transfer percent complete: 90% Transfer percent complete: 100% validated: 25.2R1.9-EVO -- Use Activate to set the next boot Image Executing GNOI::OS::Activate Installation complete for 25.2R1.9-EVO
Change History Table
Feature support is determined by the platform and release you are using. Use Feature Explorer to determine if a feature is supported on your platform.
Install()
RPC copies the software installation package to
the device, validates the configuration against the specified software version,
and installs the software, and the Activate()
RPC sets the
specified software version as the next boot version. In earlier releases,
Install()
copies the software installation package to the
device, and Activate()
validates the configuration against the
software, installs the software, and sets the software version as the next boot
version.Install()
RPC on an installed software image to validate
the current configuration against the software image and store the validated
configuration as the running configuration associated with that software
version.version
field in the Activate()
,
Install()
, and Verify()
RPCs uses the
software version string (as displayed in
/system/state/software-version
) instead of the package
name.