import json
from conanbase import ConanBase, copy, os
def _add_package_dependency(name, version):
with open('package.json', 'r') as f:
pkg = json.load(f)
pkg['dependencies'][name] = version
with open('package.json', 'w') as f:
json.dump(pkg, f, indent=2)
f.write('\n')
def _add_echarts_gl_to_dev():
with open('package.json', 'r') as f:
pkg = json.load(f)
pkg.setdefault('devDependencies', {})['echarts-gl'] = '2.1.0'
pkg['devDependencies']['claygl'] = '1.3.0'
with open('package.json', 'w') as f:
json.dump(pkg, f, indent=2)
f.write('\n')
required_conan_version = ">=1.60.0"
TS_HEADER = """// Copyright (c) 2024 Huawei Technologies Co., Ltd.
// openUBMC is licensed under Mulan PSL v2.
// You can use this software according to the terms and conditions of the Mulan PSL v2.
// You may obtain a copy of Mulan PSL v2 at:
// http://license.coscl.org.cn/MulanPSL2
// THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
// EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
// MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
// See the Mulan PSL v2 for more details.
"""
DEFAULT_FEATURE_FLAGS = {
'LDAP_PAGE_ENABLED': True,
'ENERGY_PAGE_ENABLED': True,
'VTPCM_PAGE_ENABLED': False,
'WEBVNC_PAGE_ENABLED': False,
'PRODUCT_INFO_ENABLED': True,
'PROCESSOR_ENABLED': True,
'MEMORY_ENABLED': True,
'NETWORK_ADAPTER_ENABLED': True,
'THRESHOLD_SENSOR_ENABLED': True,
'DISCRETE_SENSOR_ENABLED': True,
'FRU_ENABLED': True,
'ASSEMBLY_ENABLED': True,
'OTHER_ENABLED': True,
'MONITOR_ENABLED': True,
'STORAGE_ENABLED': True,
'POWER_INFO_ENABLED': True,
'POWER_CAP_ENABLED': True,
'POWER_CONVERTER_ENABLED': True,
'POWER_CONTROL_ENABLED': True,
'POWER_SUPPLY_MODE_ENABLED': True,
'POWER_ENERGY_ENABLED': True,
'POWER_ENERGY_SAVING_ENABLED': True,
'DEEP_SLEEP_ENABLED': True,
'COMPONENT_POWER_HISTORY_ENABLED': True,
'FAN_CALC_MODEL_MANAGEMENT_ENABLED': True,
'FAN_SENSOR_ENABLED': True,
'FAN_ENABLED': True,
'THERMAL_ENABLED': True,
'BIOS_ENABLED': True,
'BIOS_CPU_ENABLED': True,
'BIOS_SETTINGS_ENABLED': True,
'BIOS_EXPORT_ENABLED': True,
'PARTITY_ENABLED': True,
'POD_ENABLED': True,
'REPORT_ENABLED': True,
'TRAP_ENABLED': True,
'VIDEO_ENABLED': True,
'SYSTEM_LOG_ENABLED': True,
'DIAGNOSTIC_METRICS_ENABLED': True,
'BMC_LOG_ENABLED': True,
'WORK_RECORD_ENABLED': True,
'ASSET_ENABLED': True,
'ASSET_CHANGE_ENABLED': True,
'TRUSTED_SUPPLY_CHAIN_ENABLED': True,
'RETIRE_ENABLED': True,
'OBSERVE_ENABLED': True,
'KVM_ENABLED': True,
'VNC_ENABLED': True,
'LOCAL_USER_ENABLED': True,
'LDAP_USER_ENABLED': True,
'TWO_FACTOR_ENABLED': True,
'ONLINE_USER_ENABLED': True,
'SECURITY_ENABLED': True,
'CER_ENABLED': True,
'TPCM_ENABLED': True,
'KERBEROS_ENABLED': True,
'PORT_ENABLED': True,
'WEB_ENABLED': True,
'VMM_ENABLED': True,
'SNMP_ENABLED': True,
'NETWORK_ENABLED': True,
'NTP_ENABLED': True,
'UPGRADE_ENABLED': True,
'UPGRADE_REPO_ENABLED': True,
'CONFIG_ENABLED': True,
'CONFIG_PARTS_RECOVERY_ENABLED': True,
'LANGUAGE_ENABLED': True,
'LICENSE_ENABLED': True,
'BMA_ENABLED': True,
'IBMA_ENABLED': True,
'SP_ENABLED': True,
'USB_ENABLED': True,
}
SERVICE_OPTION_FLAG_MAP = {
'ldap_enabled': 'LDAP_PAGE_ENABLED',
'energy_enabled': 'ENERGY_PAGE_ENABLED',
'vtpcm_enabled': 'VTPCM_PAGE_ENABLED',
'webvnc_enabled': 'WEBVNC_PAGE_ENABLED',
'trap_enabled': 'TRAP_ENABLED',
'feature_asset': 'ASSET_ENABLED',
'asset_change_enabled': 'ASSET_CHANGE_ENABLED',
'feature_trusted_supply_chain': 'TRUSTED_SUPPLY_CHAIN_ENABLED',
'feature_retire': 'RETIRE_ENABLED',
'processor_enabled': 'PROCESSOR_ENABLED',
'memory_enabled': 'MEMORY_ENABLED',
'network_adapter_enabled': 'NETWORK_ADAPTER_ENABLED',
'fru_enabled': 'FRU_ENABLED',
'assembly_enabled': 'ASSEMBLY_ENABLED',
'other_enabled': 'OTHER_ENABLED',
'bios_cpu_enabled': 'BIOS_CPU_ENABLED',
'snmp_enabled': 'SNMP_ENABLED',
'feature_energy_efficiency': (
'DEEP_SLEEP_ENABLED',
'COMPONENT_POWER_HISTORY_ENABLED',
),
'feature_diagnostic_metrics': 'DIAGNOSTIC_METRICS_ENABLED',
'feature_license': 'LICENSE_ENABLED',
'feature_usb_entry': 'USB_ENABLED',
'feature_observe': 'OBSERVE_ENABLED',
'fan_calc_model_management_enabled': 'FAN_CALC_MODEL_MANAGEMENT_ENABLED',
'fan_sensor_enabled': 'FAN_SENSOR_ENABLED',
'power_energy_enabled': 'POWER_ENERGY_ENABLED',
'power_energy_saving_enabled': 'POWER_ENERGY_SAVING_ENABLED',
'upgrade_repo_enabled': 'UPGRADE_REPO_ENABLED',
'config_parts_recovery_enabled': 'CONFIG_PARTS_RECOVERY_ENABLED',
'ibma_enabled': 'IBMA_ENABLED',
'sp_enabled': 'SP_ENABLED',
}
def named_import(name, source):
return {'type': 'named', 'name': name, 'source': source}
def default_import(name, source):
return {'type': 'default', 'name': name, 'source': source}
IMPORTS = {
'certificateRoutes': default_import(
'certificateRoutes',
'@/apps/app-bmc/router/navigate/user/certificate/certificate-router',
),
'assetChangeGuard': named_import('assetChangeGuard', '@/apps/app-bmc/guard/assetChange.guard'),
'forbidGuard': named_import('forbidGuard', '@/apps/app-bmc/guard/forbid.guard'),
'ibmaGuard': named_import('ibmaGuard', '@/apps/app-bmc/guard/ibma.guard'),
'ibmcManageMentSecondMenu': named_import('ibmcManageMentSecondMenu', '@/apps/app-bmc/store/menu-list'),
'kvmMultiGuard': named_import('kvmMultiGuard', '@/apps/app-bmc/guard/kvmMulti.guard'),
'langGuard': named_import('langGuard', '@/apps/app-bmc/guard/lang.guard'),
'licenseGuard': named_import('licenseGuard', '@/apps/app-bmc/guard/license.guard'),
'securityRoutes': default_import(
'securityRoutes',
'@/apps/app-bmc/router/navigate/user/security/security-router',
),
'snmpGuard': named_import('snmpGuard', '@/apps/app-bmc/guard/snmp.guard'),
'spGuard': named_import('spGuard', '@/apps/app-bmc/guard/sp.guard'),
'spRoutes': default_import('spRoutes', '@/apps/app-bmc/router/navigate/manager/sp/sp.router'),
'tpcmGuard': named_import('tpcmGuard', '@/apps/app-bmc/guard/tpcm.guard'),
'twoFactorGuard': named_import('twoFactorGuard', '@/apps/app-bmc/guard/twoFactor.guard'),
'twoFactorRoutes': default_import(
'twoFactorRoutes',
'@/apps/app-bmc/router/navigate/user/twofactor/twofactor-router',
),
'usbGuard': named_import('usbGuard', '@/apps/app-bmc/guard/usb.guard'),
'vmmGuard': named_import('vmmGuard', '@/apps/app-bmc/guard/vmm.guard'),
'vncGuard': named_import('vncGuard', '@/apps/app-bmc/guard/vnc.guard'),
}
def lazy(path):
return f"() => import('{path}')"
def route(flag=None, imports=(), **entries):
return {
'entries': tuple(entries.items()),
'flag': flag,
'imports': imports,
}
FEATURE_ROUTE_GROUPS = {
'appFeatureRoutes': [
route(
flag='WEBVNC_PAGE_ENABLED',
path="'/vnc_h5'",
name="'VNC'",
component=lazy('@/pages/VirtualControl/VncH5/VncH5.vue'),
),
],
'assetRoutes': [
route(
flag='RETIRE_ENABLED',
path="'/navigate/maintenance/asset-maintance/asset-retire'",
component=lazy('@/pages/Maintance/AssetMaintance/components/AssetRetire.vue'),
),
route(
flag='ASSET_ENABLED',
path="'/navigate/maintenance/asset-maintance/asset-inventory'",
component=lazy('@/pages/Maintance/AssetMaintance/components/AssetInventory.vue'),
),
route(
flag='ASSET_CHANGE_ENABLED',
imports=('assetChangeGuard',),
path="'/navigate/maintenance/asset-maintance/asset-change'",
component=lazy('@/pages/Maintance/AssetMaintance/components/AssetChange.vue'),
beforeEnter='[assetChangeGuard]',
),
route(
flag='TRUSTED_SUPPLY_CHAIN_ENABLED',
imports=('forbidGuard',),
path="'/navigate/maintenance/asset-maintance/supply-chain-config'",
component=lazy('@/pages/Maintance/AssetMaintance/components/SupplyChainConfig.vue'),
beforeEnter='[forbidGuard]',
),
],
'serviceRoutes': [
route(
flag='PORT_ENABLED',
path="'/navigate/service/port'",
component=lazy('@/pages/Service/Port/Port.vue'),
),
route(
flag='WEB_ENABLED',
path="'/navigate/service/web'",
component=lazy('@/pages/Service/Web/Web.vue'),
),
route(
imports=('kvmMultiGuard',),
path="'/navigate/service/kvm'",
component=lazy('@/pages/Service/Kvm/Kvm.vue'),
beforeEnter='[kvmMultiGuard]',
),
route(
flag='VMM_ENABLED',
imports=('vmmGuard',),
path="'/navigate/service/vmm'",
component=lazy('@/pages/Service/Vmm/Vmm.vue'),
beforeEnter='[vmmGuard]',
),
route(
flag='VNC_ENABLED',
imports=('vncGuard',),
path="'/navigate/service/vnc'",
component=lazy('@/pages/Service/Vnc/Vnc.vue'),
beforeEnter='[vncGuard]',
),
route(
flag='SNMP_ENABLED',
imports=('snmpGuard',),
path="'/navigate/service/snmp'",
component=lazy('@/pages/Service/Snmp/Snmp.vue'),
beforeEnter='[snmpGuard]',
),
route(
path="'/navigate/service/ipmi'",
component=lazy('@/pages/Service/IPMI/IPMI.vue'),
),
],
'userRoutes': [
route(
path="'/navigate/user/local-users'",
component=lazy('@/pages/User/Localuser/Localuser.vue'),
),
route(
flag='LDAP_USER_ENABLED',
imports=('twoFactorGuard',),
path="'/navigate/user/ldap'",
component=lazy('@/pages/User/Ldap/Ldap.vue'),
beforeEnter='[twoFactorGuard]',
),
route(
imports=('forbidGuard',),
path="'/navigate/user/kerberos'",
component=lazy('@/pages/User/Kerberos/Kerberos.vue'),
beforeEnter='[forbidGuard]',
),
route(
imports=('twoFactorRoutes', 'twoFactorGuard'),
path="'/navigate/user/two-factor'",
component=lazy('@/pages/User/TwoFactor/TwoFactor.vue'),
redirect="'/navigate/user/two-factor/client'",
children='twoFactorRoutes',
beforeEnter='[twoFactorGuard]',
),
route(
path="'/navigate/user/online-users'",
component=lazy('@/pages/User/OnlineUser/OnlineUser.vue'),
),
route(
imports=('securityRoutes',),
path="'/navigate/user/security'",
component=lazy('@/pages/User/Security/Security.vue'),
redirect='securityRoutes[0].path',
children='securityRoutes',
),
route(
flag='TPCM_ENABLED',
imports=('tpcmGuard',),
path="'/navigate/user/tpcm'",
component=lazy('@/pages/User/Tpcm/tpcm.vue'),
beforeEnter='[tpcmGuard]',
),
route(
imports=('certificateRoutes',),
path="'/navigate/user/certificate'",
component=lazy('@/pages/User/Certificate/Certificate.vue'),
redirect='certificateRoutes[0].path',
children='certificateRoutes',
),
],
'managerRoutes': [
route(
imports=('ibmcManageMentSecondMenu',),
path='ibmcManageMentSecondMenu[0].router',
component=lazy('@/pages/Manager/Network/Network.vue'),
),
route(
flag='NTP_ENABLED',
imports=('ibmcManageMentSecondMenu',),
path='ibmcManageMentSecondMenu[1].router',
component=lazy('@/pages/Manager/Ntp/Ntp.vue'),
),
route(
flag='UPGRADE_ENABLED',
imports=('ibmcManageMentSecondMenu',),
path='ibmcManageMentSecondMenu[2].router',
component=lazy('@/pages/Manager/Upgrade/Upgrade.vue'),
),
route(
flag='CONFIG_ENABLED',
imports=('ibmcManageMentSecondMenu',),
path='ibmcManageMentSecondMenu[3].router',
component=lazy('@/pages/Manager/ConfigUpdate/ConfigUpdate.vue'),
),
route(
flag='LANGUAGE_ENABLED',
imports=('ibmcManageMentSecondMenu', 'langGuard'),
path='ibmcManageMentSecondMenu[4].router',
component=lazy('@/pages/Manager/Language/Language.vue'),
beforeEnter='[langGuard]',
),
route(
flag='LICENSE_ENABLED',
imports=('ibmcManageMentSecondMenu', 'licenseGuard'),
path='ibmcManageMentSecondMenu[5].router',
component=lazy('@/pages/Manager/License/License.vue'),
beforeEnter='[licenseGuard]',
),
route(
flag='IBMA_ENABLED',
imports=('ibmcManageMentSecondMenu', 'ibmaGuard'),
path='ibmcManageMentSecondMenu[6].router',
component=lazy('@/pages/Manager/Ibma/Ibma.vue'),
beforeEnter='[ibmaGuard]',
),
route(
flag='SP_ENABLED',
imports=('ibmcManageMentSecondMenu', 'spGuard', 'spRoutes'),
path='ibmcManageMentSecondMenu[7].router',
component=lazy('@/pages/Manager/Sp/Sp.vue'),
redirect="'/navigate/manager/sp/sp-manage'",
children='spRoutes',
beforeEnter='[spGuard]',
),
route(
flag='USB_ENABLED',
imports=('ibmcManageMentSecondMenu', 'usbGuard'),
path='ibmcManageMentSecondMenu[8].router',
component=lazy('@/pages/Manager/Usb/Usb.vue'),
beforeEnter='[usbGuard]',
),
route(
path="''",
redirect="'/navigate/manager/network'",
),
],
}
def generate_configure_file(config_flags):
lines = [TS_HEADER]
for flag_name in sorted(config_flags.keys()):
lines.append(f"export const {flag_name} = {str(config_flags[flag_name]).lower()};")
content = "\n".join(lines) + "\n"
with open('src/model/configure.generated.ts', 'w') as fo:
fo.write(content)
def _format_route_array(routes):
if not routes:
return "[]"
return "[\n" + ",\n".join(routes) + ",\n]"
def _enabled(config_flags, flag_name):
return flag_name is None or bool(config_flags.get(flag_name, False))
def _select_routes(config_flags, route_specs):
return [route_spec for route_spec in route_specs if _enabled(config_flags, route_spec.get('flag'))]
def _render_import(import_def):
if import_def['type'] == 'default':
return f"import {import_def['name']} from '{import_def['source']}';"
return f"import {{ {import_def['name']} }} from '{import_def['source']}';"
def _render_route(route_spec):
lines = [" {"]
lines.extend(f" {key}: {value}," for key, value in route_spec['entries'])
lines.append(" }")
return "\n".join(lines)
def _collect_route_imports(routes_by_group):
imports = ["import { RouteRecordRaw } from 'vue-router';"]
seen = set()
for routes in routes_by_group.values():
for route_spec in routes:
for import_name in route_spec.get('imports', ()):
if import_name in seen:
continue
imports.append(_render_import(IMPORTS[import_name]))
seen.add(import_name)
return imports
def generate_feature_routes_file(config_flags):
routes_by_group = {
group_name: _select_routes(config_flags, route_specs)
for group_name, route_specs in FEATURE_ROUTE_GROUPS.items()
}
content = TS_HEADER
content += "\n".join(_collect_route_imports(routes_by_group))
content += "\n\n"
for group_name, routes in routes_by_group.items():
rendered_routes = [_render_route(route_spec) for route_spec in routes]
content += f"export const {group_name}: Array<RouteRecordRaw> = {_format_route_array(rendered_routes)};\n\n"
with open('src/apps/app-bmc/router/feature-routes.generated.ts', 'w') as fo:
fo.write(content.rstrip() + "\n")
def _get_bool_option(options, option_name, default):
if hasattr(options, option_name):
return bool(getattr(options, option_name))
return default
def _load_service_json_options():
try:
with open('mds/service.json', 'r') as fi:
service = json.load(fi)
options = service.get('options', {})
option_values = {}
default_values = {}
for option_name, option_def in options.items():
if not isinstance(option_def, dict):
continue
if 'option' in option_def:
option_values[option_name] = option_def['option']
if 'default' in option_def:
default_values[option_name] = option_def['default']
return option_values, default_values
except Exception:
return {}, {}
def _load_service_json_option_defaults():
return _load_service_json_options()[1]
def build_webvnc_enabled_configure():
_add_package_dependency('@novnc/novnc', '1.3.0')
def build_three_dui_enabled_configure():
_add_package_dependency('three', '0.178.0')
home_src = ""
home_path = 'src/apps/app-bmc/Navigate/Home/Home.vue'
with open(home_path, 'r') as fi:
home_src = fi.read()
home_src = home_src.replace(
"@/pages/Home/Home.vue",
"@/pages/Home/HomeReconstructed.vue",
)
with open(home_path, 'w') as fo:
fo.write(home_src)
SERVICE_JSON_OPTIONS, SERVICE_JSON_DEFAULT_OPTIONS = _load_service_json_options()
WEBUI_FALLBACK_OPTIONS = {
'ldap_enabled': [True, False],
'energy_enabled': [True, False],
'vtpcm_enabled': [True, False],
'webvnc_enabled': [True, False],
'three_dui_enabled': [True, False],
'trap_enabled': [True, False],
'feature_asset': [True, False],
'asset_change_enabled': [True, False],
'feature_trusted_supply_chain': [True, False],
'feature_retire': [True, False],
'processor_enabled': [True, False],
'memory_enabled': [True, False],
'network_adapter_enabled': [True, False],
'fru_enabled': [True, False],
'assembly_enabled': [True, False],
'other_enabled': [True, False],
'bios_cpu_enabled': [True, False],
'snmp_enabled': [True, False],
'feature_energy_efficiency': [True, False],
'feature_diagnostic_metrics': [True, False],
'feature_license': [True, False],
'feature_usb_entry': [True, False],
'feature_observe': [True, False],
'fan_calc_model_management_enabled': [True, False],
'fan_sensor_enabled': [True, False],
'power_energy_enabled': [True, False],
'power_energy_saving_enabled': [True, False],
'upgrade_repo_enabled': [True, False],
'config_parts_recovery_enabled': [True, False],
'ibma_enabled': [True, False],
'sp_enabled': [True, False],
}
WEBUI_FALLBACK_DEFAULT_OPTIONS = {
'ldap_enabled': True,
'energy_enabled': True,
'vtpcm_enabled': False,
'webvnc_enabled': False,
'three_dui_enabled': False,
'trap_enabled': True,
'feature_asset': True,
'asset_change_enabled': True,
'feature_trusted_supply_chain': True,
'feature_retire': True,
'processor_enabled': True,
'memory_enabled': True,
'network_adapter_enabled': True,
'fru_enabled': True,
'assembly_enabled': True,
'other_enabled': True,
'bios_cpu_enabled': True,
'snmp_enabled': True,
'feature_energy_efficiency': True,
'feature_diagnostic_metrics': True,
'feature_license': True,
'feature_usb_entry': True,
'feature_observe': True,
'fan_calc_model_management_enabled': True,
'fan_sensor_enabled': True,
'power_energy_enabled': True,
'power_energy_saving_enabled': True,
'upgrade_repo_enabled': True,
'config_parts_recovery_enabled': True,
'ibma_enabled': True,
'sp_enabled': True,
}
def _merge_conan_dict(*dicts):
values = {}
for dict_value in dicts:
if isinstance(dict_value, dict):
values.update(dict_value)
return values
class WebUIConan(ConanBase):
name = "webui"
license = "BSD licence"
generators = "VirtualBuildEnv"
homepage = "https://www.huawei.com/"
description = ""
chost = None
settings = "arch"
exports = "mds/service.json"
options = _merge_conan_dict(
WEBUI_FALLBACK_OPTIONS,
SERVICE_JSON_OPTIONS,
getattr(ConanBase, 'options', {}),
)
default_options = _merge_conan_dict(
WEBUI_FALLBACK_DEFAULT_OPTIONS,
SERVICE_JSON_DEFAULT_OPTIONS,
getattr(ConanBase, 'default_options', {}),
)
def build(self):
config_flags = dict(DEFAULT_FEATURE_FLAGS)
service_defaults = _load_service_json_option_defaults()
for option_name, flag_names in SERVICE_OPTION_FLAG_MAP.items():
if not isinstance(flag_names, tuple):
flag_names = (flag_names,)
for flag_name in flag_names:
default_value = service_defaults.get(option_name, config_flags[flag_name])
config_flags[flag_name] = _get_bool_option(
self.options,
option_name,
default_value,
)
generate_configure_file(config_flags)
generate_feature_routes_file(config_flags)
webvnc_enabled = _get_bool_option(self.options, 'webvnc_enabled', False)
three_dui_enabled = _get_bool_option(self.options, 'three_dui_enabled', False)
if webvnc_enabled:
build_webvnc_enabled_configure()
if three_dui_enabled:
build_three_dui_enabled_configure()
_add_echarts_gl_to_dev()
self.run(f"npm install")
self.run(f"npm run build")
def package(self):
self.run(f"rm -rf node_modules")
self.run(f"npm install --production")
if os.path.isfile("public/permissions.ini"):
copy(self, "permissions.ini", src=os.path.join(self.source_folder, "public"),
dst=self.package_folder, keep_path=True)
three_dui_enabled = self.options.three_dui_enabled
excludes = None if three_dui_enabled else (
"**/server_model.*",
"**/server_model/**",
)
copy(self, "*", src=os.path.join(self.source_folder, "dist"),
dst=os.path.join(self.package_folder, "opt/bmc/web/htdocs/"),
excludes=excludes,)
def layout(self):
pass