Skip to content

Commit 8ea834b

Browse files
authored
[sonic_installer] Change sonic_installer check ASIC mismatch by platforms list (#1836)
What I did Handle wrong image type installation by checking platform. Before the verification was done by comparing image's ASIC and running platform's ASIC. But the running's ASIC will change if wrong image was installed. Add the same support for Aboot image verification. How I did it Add a devices list file for the same ASIC while build the image and Check by devices list instead of machine.conf How to verify it Install a bin file which differs the running platform's ASIC. For example; install sonic-broadcom.bin to mellanox ASIC platform install sonic-vs.bin to broadcom ASIC platform install sonic-aboot-barefoot.swi to broadcom ASIC platform
1 parent 9017d99 commit 8ea834b

File tree

5 files changed

+61
-36
lines changed

5 files changed

+61
-36
lines changed

sonic_installer/bootloader/aboot.py

+25-1
Original file line numberDiff line numberDiff line change
@@ -15,20 +15,24 @@
1515

1616
from M2Crypto import X509
1717

18+
from sonic_py_common import device_info
1819
from ..common import (
1920
HOST_PATH,
2021
IMAGE_DIR_PREFIX,
2122
IMAGE_PREFIX,
2223
ROOTFS_NAME,
2324
run_command,
2425
run_command_or_raise,
26+
default_sigpipe,
2527
)
2628
from .bootloader import Bootloader
2729

2830
_secureboot = None
2931
DEFAULT_SWI_IMAGE = 'sonic.swi'
3032
KERNEL_CMDLINE_NAME = 'kernel-cmdline'
3133

34+
UNZIP_MISSING_FILE = 11
35+
3236
# For the signature format, see: https://github.com/aristanetworks/swi-tools/tree/master/switools
3337
SWI_SIG_FILE_NAME = 'swi-signature'
3438
SWIX_SIG_FILE_NAME = 'swix-signature'
@@ -164,7 +168,27 @@ def get_binary_image_version(self, image_path):
164168
return IMAGE_PREFIX + version.strip()
165169

166170
def verify_image_platform(self, image_path):
167-
return os.path.isfile(image_path)
171+
if not os.path.isfile(image_path):
172+
return False
173+
174+
# Get running platform
175+
platform = device_info.get_platform()
176+
177+
# If .platforms_asic is not existed, unzip will return code 11.
178+
# Return True for backward compatibility.
179+
# Otherwise, we grep to see if current platform is inside the
180+
# supported target platforms list.
181+
with open(os.devnull, 'w') as fnull:
182+
p1 = subprocess.Popen(['/usr/bin/unzip', '-qop', image_path, '.platforms_asic'], stdout=subprocess.PIPE, stderr=fnull, preexec_fn=default_sigpipe)
183+
p2 = subprocess.Popen(['grep', '-Fxq', '-m 1', platform], stdin=p1.stdout, preexec_fn=default_sigpipe)
184+
185+
p1.wait()
186+
if p1.returncode == UNZIP_MISSING_FILE:
187+
return True
188+
189+
# Code 0 is returned by grep as a result of found
190+
p2.wait()
191+
return p2.returncode == 0
168192

169193
def verify_secureboot_image(self, image_path):
170194
try:

sonic_installer/bootloader/grub.py

+25-26
Original file line numberDiff line numberDiff line change
@@ -14,11 +14,11 @@
1414
IMAGE_DIR_PREFIX,
1515
IMAGE_PREFIX,
1616
run_command,
17+
default_sigpipe,
1718
)
1819
from .onie import OnieInstallerBootloader
19-
from .onie import default_sigpipe
2020

21-
MACHINE_CONF = "installer/machine.conf"
21+
PLATFORMS_ASIC = "installer/platforms_asic"
2222

2323
class GrubBootloader(OnieInstallerBootloader):
2424

@@ -85,35 +85,34 @@ def remove_image(self, image):
8585
run_command('grub-set-default --boot-directory=' + HOST_PATH + ' 0')
8686
click.echo('Image removed')
8787

88+
def platform_in_platforms_asic(self, platform, image_path):
89+
"""
90+
For those images that don't have devices list builtin, 'tar' will have non-zero returncode.
91+
In this case, we simply return True to make it worked compatible as before.
92+
Otherwise, we can grep to check if platform is inside the supported target platforms list.
93+
"""
94+
with open(os.devnull, 'w') as fnull:
95+
p1 = subprocess.Popen(["sed", "-e", "1,/^exit_marker$/d", image_path], stdout=subprocess.PIPE, preexec_fn=default_sigpipe)
96+
p2 = subprocess.Popen(["tar", "xf", "-", PLATFORMS_ASIC, "-O"], stdin=p1.stdout, stdout=subprocess.PIPE, stderr=fnull, preexec_fn=default_sigpipe)
97+
p3 = subprocess.Popen(["grep", "-Fxq", "-m 1", platform], stdin=p2.stdout, preexec_fn=default_sigpipe)
98+
99+
p2.wait()
100+
if p2.returncode != 0:
101+
return True
102+
103+
# Code 0 is returned by grep as a result of found
104+
p3.wait()
105+
return p3.returncode ==0
106+
88107
def verify_image_platform(self, image_path):
89108
if not os.path.isfile(image_path):
90109
return False
91110

92-
# Get running platform's ASIC
93-
try:
94-
version_info = device_info.get_sonic_version_info()
95-
if version_info:
96-
asic_type = version_info['asic_type']
97-
else:
98-
asic_type = None
99-
except (KeyError, TypeError) as e:
100-
click.echo("Caught an exception: " + str(e))
101-
102-
# Get installing image's ASIC
103-
p1 = subprocess.Popen(["sed", "-e", "1,/^exit_marker$/d", image_path], stdout=subprocess.PIPE, preexec_fn=default_sigpipe)
104-
p2 = subprocess.Popen(["tar", "xf", "-", MACHINE_CONF, "-O"], stdin=p1.stdout, stdout=subprocess.PIPE, preexec_fn=default_sigpipe)
105-
p3 = subprocess.Popen(["sed", "-n", r"s/^machine=\(.*\)/\1/p"], stdin=p2.stdout, stdout=subprocess.PIPE, preexec_fn=default_sigpipe, text=True)
106-
107-
stdout = p3.communicate()[0]
108-
image_asic = stdout.rstrip('\n')
109-
110-
# Return false if machine is not found or unexpected issue occur
111-
if not image_asic:
112-
return False
111+
# Get running platform
112+
platform = device_info.get_platform()
113113

114-
if asic_type == image_asic:
115-
return True
116-
return False
114+
# Check if platform is inside image's target platforms
115+
return self.platform_in_platforms_asic(platform, image_path)
117116

118117
@classmethod
119118
def detect(cls):

sonic_installer/bootloader/onie.py

+1-6
Original file line numberDiff line numberDiff line change
@@ -4,20 +4,15 @@
44

55
import os
66
import re
7-
import signal
87
import subprocess
98

109
from ..common import (
1110
IMAGE_DIR_PREFIX,
1211
IMAGE_PREFIX,
12+
default_sigpipe,
1313
)
1414
from .bootloader import Bootloader
1515

16-
# Needed to prevent "broken pipe" error messages when piping
17-
# output of multiple commands using subprocess.Popen()
18-
def default_sigpipe():
19-
signal.signal(signal.SIGPIPE, signal.SIG_DFL)
20-
2116
class OnieInstallerBootloader(Bootloader): # pylint: disable=abstract-method
2217

2318
DEFAULT_IMAGE_PATH = '/tmp/sonic_image'

sonic_installer/common.py

+7
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55

66
import subprocess
77
import sys
8+
import signal
89

910
import click
1011

@@ -41,3 +42,9 @@ def run_command_or_raise(argv, raise_exception=True):
4142
raise SonicRuntimeException("Failed to run command '{0}'".format(argv))
4243

4344
return out.rstrip("\n")
45+
46+
# Needed to prevent "broken pipe" error messages when piping
47+
# output of multiple commands using subprocess.Popen()
48+
def default_sigpipe():
49+
signal.signal(signal.SIGPIPE, signal.SIG_DFL)
50+

sonic_installer/main.py

+3-3
Original file line numberDiff line numberDiff line change
@@ -533,15 +533,15 @@ def install(url, force, skip_platform_check=False, skip_migration=False, skip_pa
533533
raise click.Abort()
534534
else:
535535
# Verify not installing non-secure image in a secure running image
536-
if not bootloader.verify_secureboot_image(image_path) and not force:
536+
if not force and not bootloader.verify_secureboot_image(image_path):
537537
echo_and_log("Image file '{}' is of a different type than running image.\n".format(url) +
538538
"If you are sure you want to install this image, use -f|--force|--skip-secure-check.\n" +
539539
"Aborting...", LOG_ERR)
540540
raise click.Abort()
541541

542542
# Verify that the binary image is of the same platform type as running platform
543-
if not bootloader.verify_image_platform(image_path) and not skip_platform_check:
544-
echo_and_log("Image file '{}' is of a different platform type than running platform.\n".format(url) +
543+
if not skip_platform_check and not bootloader.verify_image_platform(image_path):
544+
echo_and_log("Image file '{}' is of a different platform ASIC type than running platform's.\n".format(url) +
545545
"If you are sure you want to install this image, use --skip-platform-check.\n" +
546546
"Aborting...", LOG_ERR)
547547
raise click.Abort()

0 commit comments

Comments
 (0)