gNOI 操作系统 (OS) 服务
使用 gNOI 操作系统 (OS) 服务升级目标网络设备上的软件。
您可以使用 gNOI OS 服务升级目标设备上的软件。原型定义文件位于 https://github.com/openconfig/gnoi/blob/master/os/os.proto。
软件安装有三个主要步骤,它们对应 OS 于服务 RPC。
- 安装
- 激活
- 验证
您可以使用 OS 服务 RPC 将软件安装包传输到设备,根据指定的软件版本验证配置,然后安装软件。您还可以将已安装的软件版本设置为下一个启动版本并验证软件版本。
您还可以使用 gNOI system 服务 SetPackage() RPC 在设备上安装软件。更多信息,请参见 gNOI系统服务。
支持的 RPC
| RPC | 描述 | 在版本中引入 |
|---|---|---|
Activate() |
设置下次重新启动时使用的软件版本。
注意:
Junos 设备不支持
注意:
在 Junos OS 演化版 25.2R1 之前, |
Junos OS 演化版 22.2R1 |
Install() |
将软件安装包传输到目标,根据软件验证配置,然后安装(暂存)软件。 如果设备上已安装指定的软件映像,请根据软件映像验证当前配置,并将经过验证的配置存储为与该软件版本关联的运行配置。
注意:
Junos 设备不支持
注意:
在 Junos OS 演化版 25.2R1 |
Junos OS 演化版 22.2R1 |
Verify() |
检查正在运行的软件版本。当目标启动时,可能会多次调用此 RPC,直到成功。
注意:
Junos 设备不支持 |
Junos OS 演化版 22.2R1 |
操作系统服务概述
gNOI OS 服务 RPC 使您能够管理运行 Junos OS Evolved 的设备上的软件。Junos OS 演化版在存储介质上存储多个版本的软件。对于每个软件版本,Junos OS Evolved 还会存储该软件版本上次运行时正在运行的配置。
表 2 概述了不同 Junos OS 演化版中的 RPC 操作。从 Junos OS 演化版 25.2R1 版开始,您可以在不立即激活的情况下安装软件,根据任何已安装的软件版本验证当前配置,以及激活任何已安装的软件版本。
| RPC |
Junos OS 演化版 24.4R1 及更早版本 |
Junos OS 演化版 25.2R1 及更高版本 |
|---|---|---|
|
|
将软件安装包传输到设备。 |
将软件安装包传输到设备。 |
| – | 根据指定的软件版本(新的或以前安装的)验证当前配置。 |
|
| – | 如果尚未安装指定的软件版本,请安装软件。 |
|
| – | 将经过验证的当前配置存储为与指定软件版本关联的运行配置。 |
|
|
|
根据指定的软件版本验证当前配置。 |
– |
| 安装软件。 |
– | |
| 将指定的软件版本设置为下一个启动版本。 |
将指定的软件版本设置为下一个启动版本。 |
|
| (选答)重新启动设备。 |
(选答)重新启动设备。 |
|
|
|
检查正在运行的软件版本。 |
检查正在运行的软件版本。 |
在 Junos OS 演化版 25.2R1 及更高版本中, Install() RPC 会将指定的软件安装包传输到目标设备上的目录, /var/tmp/ 针对软件验证配置,然后安装软件(如果设备上尚未安装该软件版本)。目标文件名是在消息字段中 TransferRequest 定义的 version 值。 Activate() RPC 将指定的软件版本设置为下一个启动版本,并可选择重新启动设备以激活软件。您可以激活任何已安装的软件版本。
如果运行 Install() 并指定现有软件版本, Install() 则根据软件验证当前配置,并将已验证的配置存储为与该软件版本关联的运行配置。如果软件版本设置为下一个启动版本, Install() 则在此过程中将其停用。因此,您可以验证特定软件版本是否适用于最近的任何配置更改。
网络设备配置
示例:安装并激活
在此示例中,客户端执行 gnoi_os_install_activate.py Python 应用程序,该应用程序执行以下操作:
-
将软件包从本地网络管理系统复制到网络设备。
-
根据软件映像验证配置。
-
在网络设备上安装软件包。
-
重新启动网络设备,从而激活新的软件映像。
应用程序使用 Install() 消息调用 InstallRequest() RPC 以传输文件。应用程序通过在每 10% 传输完成间隔发出进度消息来跟踪文件传输的进度。如果文件传输成功,系统将根据软件映像验证配置,执行存储清理,然后安装映像。然后,应用程序调用 Activate() RPC 将新映像设置为下一个启动映像,并重新启动目标。
应用程序导入grpc_channel模块以建立通道。配置 gNOI 服务中介绍了该grpc_channel模块。应用程序的参数存储在文件中args_os_install_activate.txt。应用程序和参数文件如下:
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
从 Junos OS 演化版 23.4R1 版开始,version、 Install()和 Verify() RPC 中的Activate()字段使用软件版本字符串(如 /system/state/software-version中所示),而非软件包名称。
执行应用
当客户端执行应用程序时,应用程序将包从本地设备复制到网络设备上的目录中 /var/tmp ,安装包,然后重新启动设备以完成安装。
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
变更历史表
是否支持某项功能取决于您使用的平台和版本。使用 功能资源管理器 确定您的平台是否支持某个功能。
Install() RPC 会将软件安装包复制到设备,根据指定的软件版本验证配置,然后安装软件,然后
Activate() RPC 会将指定的软件版本设置为下一个启动版本。在早期版本中,
Install() 将软件安装包复制到设备,并
Activate() 根据软件验证配置,安装软件,并将软件版本设置为下一个启动版本。
Install() RPC,以根据软件映像验证当前配置,并将经过验证的配置存储为与该软件版本关联的运行配置。
version、
Install()和
Verify() RPC 中的
Activate()字段使用软件版本字符串(如
/system/state/software-version中所示),而非软件包名称。