Ignore - Zuul check

Signed-off-by: Salman Rana <salman.rana@windriver.com>
Change-Id: I3aa1d35838ca868212ce6ffed09d1498a2b659dd
This commit is contained in:
Salman Rana 2024-05-10 21:58:19 -04:00 committed by Salman Rana
parent 4fecd581c8
commit e90cf054de
1 changed files with 154 additions and 0 deletions

View File

@ -0,0 +1,154 @@
# Copyright (c) 2024 Wind River Systems, Inc.
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
# implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
import hashlib
import os
import shutil
import tempfile
import yaml
from eventlet.green import subprocess
from oslo_config import cfg
from oslo_log import log as logging
LOG = logging.getLogger(__name__)
CONF = cfg.CONF
SUBCLOUD_ISO_PATH = '/opt/platform/iso'
class SubcloudEnrollment(object):
"""Class to encapsulate the subcloud enrollment operations"""
def __init__(self, subcloud_name):
self.name = subcloud_name
self.www_root = None
self.iso_dir_path = None
self.seed_iso_path = None
def build_seed_network_config(self, path, iso_values):
if not os.path.isdir(path):
raise Exception(f'No folder exists: {path}')
# TODO(srana): Investigate other bootstrap / install values
# that would need to be covered here.
network_cloud_config = [
{
'type': 'physical',
'name': iso_values['bootstrap_interface'],
'subnets': [
{
'type': 'static',
'address': iso_values['external_oam_floating_address'],
'netmask': iso_values['network_mask'],
'gateway': iso_values['external_oam_gateway_address'],
}
]
}
]
network_config_file = os.path.join(path, 'network-config')
with open(network_config_file, 'w') as f_out_network_config_file:
contents = {'version': 1, 'config': network_cloud_config}
f_out_network_config_file.write(yaml.dump(contents,
default_flow_style=False,
sort_keys=False))
return True
def build_seed_user_config(self, path, iso_values):
if not os.path.isdir(path):
raise Exception(f'No folder exists: {path}')
hashed_password = hashlib.sha256(
iso_values['admin_password'].encode()).hexdigest()
account_config = {
'list': [f'sysadmin:{hashed_password}'],
'expire': 'False'
}
user_data_file = os.path.join(path, 'user-data')
with open(user_data_file, 'w') as f_out_user_data_file:
contents = {'chpasswd': account_config}
f_out_user_data_file.writelines('#cloud-config\n')
f_out_user_data_file.write(yaml.dump(contents,
default_flow_style=False,
sort_keys=False))
return True
def generate_seed_iso(self, payload):
self.www_root = os.path.join(SUBCLOUD_ISO_PATH, payload['software_version'])
temp_seed_data_dir = tempfile.mkdtemp(prefix='seed_')
self.iso_dir_path = os.path.join(self.www_root, 'nodes', self.name)
self.seed_iso_path = os.path.join(self.iso_dir_path, 'seed.iso')
LOG.info('Prepare for seed iso generation')
if not os.path.isdir(self.iso_dir_path):
os.makedirs(self.iso_dir_path, 0o755, exist_ok=True)
elif os.path.exists(self.seed_iso_path):
LOG.info(f'Found preexisting seed iso for subcloud {self.name}, '
f'cleaning up')
os.remove(self.seed_iso_path)
# TODO(srana): After integration, extract required bootstrap and install
# into iso_values. For now, pass in payload.
try:
# Generate seed cloud-config files
self.build_seed_network_config(temp_seed_data_dir, payload)
self.build_seed_user_config(temp_seed_data_dir, payload)
except Exception as e:
shutil.rmtree(temp_seed_data_dir)
LOG.exception(f'Unable to generate seed config files: {e}')
return False
# Trigger generation of seed iso
gen_seed_iso_command = [
"genisoimage",
"-o", self.seed_iso_path,
"-volid", "CIDATA",
"-untranslated-filenames",
"-joliet",
"-rock",
"-iso-level", "2",
temp_seed_data_dir
]
LOG.info(f'Running gen_seed_iso_command: {gen_seed_iso_command}')
result = subprocess.run(gen_seed_iso_command,
# capture both streams in stdout:
stdout=subprocess.PIPE,
stderr=subprocess.STDOUT)
shutil.rmtree(temp_seed_data_dir)
if result.returncode == 0:
msg = f'Finished generating seed iso: {gen_seed_iso_command}'
LOG.info("%s returncode: %s, output: %s",
msg,
result.returncode,
result.stdout.decode('utf-8').replace('\n', ', '))
else:
msg = f'Failed to generate seed iso: {gen_seed_iso_command}'
LOG.error("%s returncode: %s, output: %s",
msg,
result.returncode,
result.stdout.decode('utf-8').replace('\n', ', '))
raise Exception(msg)
return True