Skip to content

Commit

Permalink
[sonic-installer] Create Envvars File for Incoming Image (#1011)
Browse files Browse the repository at this point in the history
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 <tamer.ahmed@microsoft.com>
  • Loading branch information
tahmed-dev authored Aug 5, 2020
1 parent 092ebd2 commit d1cf75f
Show file tree
Hide file tree
Showing 5 changed files with 80 additions and 1 deletion.
1 change: 1 addition & 0 deletions setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,7 @@
],
data_files=[
('/etc/bash_completion.d', glob.glob('data/etc/bash_completion.d/*')),
('/usr/share/sonic/templates', ['sonic_installer/templates/sonic-environment.j2']),
],
entry_points={
'console_scripts': [
Expand Down
14 changes: 14 additions & 0 deletions sonic_installer/common.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@

import click

from .exception import SonicRuntimeException

HOST_PATH = '/host'
IMAGE_PREFIX = 'SONiC-OS-'
IMAGE_DIR_PREFIX = 'image-'
Expand All @@ -23,3 +25,15 @@ def run_command(command):

if proc.returncode != 0:
sys.exit(proc.returncode)

# Run bash command and return output, raise if it fails
def run_command_or_raise(argv):
click.echo(click.style("Command: ", fg='cyan') + click.style(' '.join(argv), fg='green'))

proc = subprocess.Popen(argv, stdout=subprocess.PIPE)
out, _ = proc.communicate()

if proc.returncode != 0:
raise SonicRuntimeException("Failed to run command '{0}'".format(argv))

return out.rstrip("\n")
8 changes: 8 additions & 0 deletions sonic_installer/exception.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
"""
Module sonic_installer exceptions
"""

class SonicRuntimeException(Exception):
"""SONiC Runtime Excpetion class used to report SONiC related errors
"""
pass
53 changes: 52 additions & 1 deletion sonic_installer/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,8 @@
from swsssdk import SonicV2Connector

from .bootloader import get_bootloader
from .common import run_command
from .common import run_command, run_command_or_raise
from .exception import SonicRuntimeException


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

def update_sonic_environment(click, binary_image_version):
"""Prepare sonic environment variable using incoming image template file. If incoming image template does not exist
use current image template file.
"""
def mount_next_image_fs(squashfs_path, mount_point):
run_command_or_raise(["mkdir", "-p", mount_point])
run_command_or_raise(["mount", "-t", "squashfs", squashfs_path, mount_point])

def umount_next_image_fs(mount_point):
run_command_or_raise(["umount", "-rf", mount_point])
run_command_or_raise(["rm", "-rf", mount_point])

SONIC_ENV_TEMPLATE_FILE = os.path.join("usr", "share", "sonic", "templates", "sonic-environment.j2")
SONIC_VERSION_YML_FILE = os.path.join("etc", "sonic", "sonic_version.yml")

sonic_version = re.sub("SONiC-OS-", '', binary_image_version)
new_image_dir = os.path.join('/', "host", "image-{0}".format(sonic_version))
new_image_squashfs_path = os.path.join(new_image_dir, "fs.squashfs")
new_image_mount = os.path.join('/', "tmp", "image-{0}-fs".format(sonic_version))
env_dir = os.path.join(new_image_dir, "sonic-config")
env_file = os.path.join(env_dir, "sonic-environment")

try:
mount_next_image_fs(new_image_squashfs_path, new_image_mount)

next_sonic_env_template_file = os.path.join(new_image_mount, SONIC_ENV_TEMPLATE_FILE)
next_sonic_version_yml_file = os.path.join(new_image_mount, SONIC_VERSION_YML_FILE)

sonic_env = run_command_or_raise([
"sonic-cfggen",
"-d",
"-y",
next_sonic_version_yml_file,
"-t",
next_sonic_env_template_file,
])
os.mkdir(env_dir, 0o755)
with open(env_file, "w+") as ef:
print >>ef, sonic_env
os.chmod(env_file, 0o644)
except SonicRuntimeException as ex:
click.secho("Warning: SONiC environment variables are not supported for this image: {0}".format(str(ex)),
fg="red", err=True)
if os.path.exists(env_file):
os.remove(env_file)
os.rmdir(env_dir)
finally:
umount_next_image_fs(new_image_mount)

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

update_sonic_environment(click, binary_image_version)

# Finally, sync filesystem
run_command("sync;sync;sync")
run_command("sleep 3") # wait 3 seconds after sync
Expand Down
5 changes: 5 additions & 0 deletions sonic_installer/templates/sonic-environment.j2
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
SONIC_VERSION={{ build_version }}
PLATFORM={{ DEVICE_METADATA.localhost.platform }}
HWSKU={{ DEVICE_METADATA.localhost.hwsku }}
DEVICE_TYPE={{ DEVICE_METADATA.localhost.type }}
ASIC_TYPE={{ asic_type }}

1 comment on commit d1cf75f

@lguohan
Copy link
Contributor

@lguohan lguohan commented on d1cf75f Aug 8, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i do not see additional unit test being added for this feature. We need to add additional unit test cases.

Please sign in to comment.