Skip to content

Commit d1cf75f

Browse files
authored
[sonic-installer] Create Envvars File for Incoming Image (sonic-net#1011)
Create environment files for SONiC immutable attribute. The file will reside in the incoming image dir under sonic-config dir. Incoming image will then move the file to /etc/sonic. The file will be used to avoid calls into cfggen for those attributes. signed-off-by: Tamer Ahmed <[email protected]>
1 parent 092ebd2 commit d1cf75f

File tree

5 files changed

+80
-1
lines changed

5 files changed

+80
-1
lines changed

setup.py

+1
Original file line numberDiff line numberDiff line change
@@ -112,6 +112,7 @@
112112
],
113113
data_files=[
114114
('/etc/bash_completion.d', glob.glob('data/etc/bash_completion.d/*')),
115+
('/usr/share/sonic/templates', ['sonic_installer/templates/sonic-environment.j2']),
115116
],
116117
entry_points={
117118
'console_scripts': [

sonic_installer/common.py

+14
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@
88

99
import click
1010

11+
from .exception import SonicRuntimeException
12+
1113
HOST_PATH = '/host'
1214
IMAGE_PREFIX = 'SONiC-OS-'
1315
IMAGE_DIR_PREFIX = 'image-'
@@ -23,3 +25,15 @@ def run_command(command):
2325

2426
if proc.returncode != 0:
2527
sys.exit(proc.returncode)
28+
29+
# Run bash command and return output, raise if it fails
30+
def run_command_or_raise(argv):
31+
click.echo(click.style("Command: ", fg='cyan') + click.style(' '.join(argv), fg='green'))
32+
33+
proc = subprocess.Popen(argv, stdout=subprocess.PIPE)
34+
out, _ = proc.communicate()
35+
36+
if proc.returncode != 0:
37+
raise SonicRuntimeException("Failed to run command '{0}'".format(argv))
38+
39+
return out.rstrip("\n")

sonic_installer/exception.py

+8
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
"""
2+
Module sonic_installer exceptions
3+
"""
4+
5+
class SonicRuntimeException(Exception):
6+
"""SONiC Runtime Excpetion class used to report SONiC related errors
7+
"""
8+
pass

sonic_installer/main.py

+52-1
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,8 @@
1616
from swsssdk import SonicV2Connector
1717

1818
from .bootloader import get_bootloader
19-
from .common import run_command
19+
from .common import run_command, run_command_or_raise
20+
from .exception import SonicRuntimeException
2021

2122

2223
# Global Config object
@@ -208,6 +209,54 @@ def print_deprecation_warning(deprecated_cmd_or_subcmd, new_cmd_or_subcmd):
208209
fg="red", err=True)
209210
click.secho("Please use '{}' instead".format(new_cmd_or_subcmd), fg="red", err=True)
210211

212+
def update_sonic_environment(click, binary_image_version):
213+
"""Prepare sonic environment variable using incoming image template file. If incoming image template does not exist
214+
use current image template file.
215+
"""
216+
def mount_next_image_fs(squashfs_path, mount_point):
217+
run_command_or_raise(["mkdir", "-p", mount_point])
218+
run_command_or_raise(["mount", "-t", "squashfs", squashfs_path, mount_point])
219+
220+
def umount_next_image_fs(mount_point):
221+
run_command_or_raise(["umount", "-rf", mount_point])
222+
run_command_or_raise(["rm", "-rf", mount_point])
223+
224+
SONIC_ENV_TEMPLATE_FILE = os.path.join("usr", "share", "sonic", "templates", "sonic-environment.j2")
225+
SONIC_VERSION_YML_FILE = os.path.join("etc", "sonic", "sonic_version.yml")
226+
227+
sonic_version = re.sub("SONiC-OS-", '', binary_image_version)
228+
new_image_dir = os.path.join('/', "host", "image-{0}".format(sonic_version))
229+
new_image_squashfs_path = os.path.join(new_image_dir, "fs.squashfs")
230+
new_image_mount = os.path.join('/', "tmp", "image-{0}-fs".format(sonic_version))
231+
env_dir = os.path.join(new_image_dir, "sonic-config")
232+
env_file = os.path.join(env_dir, "sonic-environment")
233+
234+
try:
235+
mount_next_image_fs(new_image_squashfs_path, new_image_mount)
236+
237+
next_sonic_env_template_file = os.path.join(new_image_mount, SONIC_ENV_TEMPLATE_FILE)
238+
next_sonic_version_yml_file = os.path.join(new_image_mount, SONIC_VERSION_YML_FILE)
239+
240+
sonic_env = run_command_or_raise([
241+
"sonic-cfggen",
242+
"-d",
243+
"-y",
244+
next_sonic_version_yml_file,
245+
"-t",
246+
next_sonic_env_template_file,
247+
])
248+
os.mkdir(env_dir, 0o755)
249+
with open(env_file, "w+") as ef:
250+
print >>ef, sonic_env
251+
os.chmod(env_file, 0o644)
252+
except SonicRuntimeException as ex:
253+
click.secho("Warning: SONiC environment variables are not supported for this image: {0}".format(str(ex)),
254+
fg="red", err=True)
255+
if os.path.exists(env_file):
256+
os.remove(env_file)
257+
os.rmdir(env_dir)
258+
finally:
259+
umount_next_image_fs(new_image_mount)
211260

212261
# Main entrypoint
213262
@click.group(cls=AliasedGroup)
@@ -274,6 +323,8 @@ def install(url, force, skip_migration=False):
274323
else:
275324
run_command('config-setup backup')
276325

326+
update_sonic_environment(click, binary_image_version)
327+
277328
# Finally, sync filesystem
278329
run_command("sync;sync;sync")
279330
run_command("sleep 3") # wait 3 seconds after sync
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
SONIC_VERSION={{ build_version }}
2+
PLATFORM={{ DEVICE_METADATA.localhost.platform }}
3+
HWSKU={{ DEVICE_METADATA.localhost.hwsku }}
4+
DEVICE_TYPE={{ DEVICE_METADATA.localhost.type }}
5+
ASIC_TYPE={{ asic_type }}

0 commit comments

Comments
 (0)