diff --git a/etc/ngcp-ngcpcfg/ngcpcfg.cfg b/etc/ngcp-ngcpcfg/ngcpcfg.cfg index 2a1923a4..3a6a004d 100644 --- a/etc/ngcp-ngcpcfg/ngcpcfg.cfg +++ b/etc/ngcp-ngcpcfg/ngcpcfg.cfg @@ -30,6 +30,10 @@ TEMPLATE_POOL_BASE="${NGCPCTL_MAIN}/templates" # location of service definitions SERVICES_POOL_BASE="${NGCPCTL_MAIN}/templates" +# location of sites info for templates +SITES_DIR="${NGCPCTL_MAIN}/sites" +SITES_CONFIG="${NGCPCTL_MAIN}/sites.yml" + # location of instances info for templates TEMPLATE_INSTANCES="${NGCPCTL_MAIN}/instances.yml" diff --git a/functions/init b/functions/init index 4aeba970..3f7ab958 100644 --- a/functions/init +++ b/functions/init @@ -99,6 +99,8 @@ export LC_ALL=C export CONFIG_POOL export HOST_CONFIG export LOCAL_CONFIG +export SITES_CONFIG +export SITES_DIR export NGCPCTL_CONFIG export CONSTANTS_CONFIG export MAINTENANCE_CONFIG diff --git a/helper/tt2-process b/helper/tt2-process index 3d240c6d..f383808e 100755 --- a/helper/tt2-process +++ b/helper/tt2-process @@ -26,6 +26,8 @@ $TIME_FORMAT =~ s/^\+//; my $NGCPCTL_MAIN = $ENV{NGCPCTL_MAIN}; my $TEMPLATE_POOL_BASE = $ENV{TEMPLATE_POOL_BASE}; +my $SITES_DIR = $ENV{SITES_DIR} // "$NGCPCTL_MAIN/sites"; +my $SITES_CONFIG = $ENV{SITES_CONFIG} // "$NGCPCTL_MAIN/sites.yml"; my $CONFIG_POOL = $ENV{CONFIG_POOL} // ''; my %options = ( @@ -35,6 +37,8 @@ my %options = ( chomp $options{jobs}; error("NGCPCTL_MAIN is not defined") unless $NGCPCTL_MAIN; +error("SITES_DIR is not defined") unless $SITES_DIR; +error("SITES_CONFIG is not defined") unless $SITES_CONFIG; error("TEMPLATE_POOL_BASE is not defined") unless $TEMPLATE_POOL_BASE; GetOptions(\%options, @@ -436,14 +440,64 @@ sub merge_yml { sub process { my %options = @_; my $config = {}; + my $sites = {}; my $visible_jobs = $options{jobs} || 'unlimited'; info("Building configurations with $visible_jobs concurrent jobs"); - foreach my $file (@{$options{config}}) { - $config = merge_yml($config, $file); + if (-f $SITES_CONFIG && -d $SITES_DIR && -l "$SITES_DIR/current") { + $sites = LoadFile($SITES_CONFIG); } + $sites->{sites_enable} //= 'no'; + + if ($sites->{sites_enable} eq 'yes') { + info("Loading in multi-site mode"); + + my $current_site = readlink "$SITES_DIR/current"; + if (not defined $current_site) { + error("Cannot read symlink target for $SITES_DIR/current: $!"); + } + info("Current site is '$current_site'"); + + if (not exists $sites->{sites}{$current_site}) { + error("Cannot find current site $current_site in sites definitions."); + } + + foreach my $site (sort keys %{$sites->{sites}}) { + foreach my $file (@{$options{config}}) { + my $site_file = "$SITES_DIR/$site/" . basename($file); + + $sites->{sites}{$site} = merge_yml($sites->{sites}{$site}, $site_file); + } + } + + # First fill the root config with the current site. + $config = $sites->{sites}{$current_site}; + + # Then fill the sites sub-trees. + foreach my $site (sort keys %{$sites->{sites}}) { + $config->{sites}{$site} = $sites->{sites}{$site}; + } + + # Create the 'current' reference. + $config->{sites}{current} = $config->{sites}{$current_site}; + } else { + info("Loading in single-site mode"); + + foreach my $file (@{$options{config}}) { + $sites = merge_yml($sites, $file); + } + + # First fill the root config with the current site. + $config = $sites; + + # Create the 'current' site reference for compatibility. + $config->{sites}{current} = $sites; + } + + $config->{sites_enable} = $sites->{sites_enable}; + my $tt = NGCP::Template->new(); my $rc; diff --git a/scripts/cat b/scripts/cat index ed1559ce..992e74a0 100755 --- a/scripts/cat +++ b/scripts/cat @@ -35,7 +35,7 @@ fi # shellcheck disable=SC1090 . "${FUNCTIONS}"/main -CONFIG_TYPES=(config maintenance network constants) +CONFIG_TYPES=(config maintenance sites network constants) # Get the list of config types to load. if [ "${#:-}" -eq 0 ]; then @@ -49,7 +49,7 @@ for t in "${CONFIG_TYPES[@]}"; do done while [ -n "${1:-}" ]; do case "$1" in - constants|config|network|maintenance) + constants|config|network|maintenance|sites) config_types[$1]=true shift ;; @@ -72,6 +72,9 @@ if "${config_types[config]}"; then configs_try+=("${HOST_CONFIG}") configs_try+=("${LOCAL_CONFIG}") fi +if "${config_types[sites]}"; then + configs_try+=("${SITES_CONFIG}") +fi if "${config_types[maintenance]}"; then configs_try+=("${MAINTENANCE_CONFIG}") fi diff --git a/scripts/edit b/scripts/edit index 19d33e5f..44ac2a2b 100755 --- a/scripts/edit +++ b/scripts/edit @@ -36,13 +36,25 @@ if [ "${#:-}" -ge 1 ] ; then if [ ! -r "${file}" ]; then case ${file,,} in 1|config|config.yml) - file="${NGCPCTL_MAIN}/config.yml" + if [ -e "${SITES_DIR}/current/config.yml" ]; then + file="${SITES_DIR}/current/config.yml" + else + file="${NGCPCTL_MAIN}/config.yml" + fi ;; 2|network|network.yml) - file="${NGCPCTL_MAIN}/network.yml" + if [ -e "${SITES_DIR}/current/network.yml" ]; then + file="${SITES_DIR}/current/network.yml" + else + file="${NGCPCTL_MAIN}/network.yml" + fi ;; 3|constants|constants.yml) - file="${NGCPCTL_MAIN}/constants.yml" + if [ -e "${SITES_DIR}/current/constants.yml" ]; then + file="${SITES_DIR}/current/constants.yml" + else + file="${NGCPCTL_MAIN}/constants.yml" + fi ;; *) echo "Error: Unknown choice '${file}'. Aborting." >&2 diff --git a/t/fixtures/ngcpcfg.cfg b/t/fixtures/ngcpcfg.cfg index fdd7a1ff..8efbdc4c 100644 --- a/t/fixtures/ngcpcfg.cfg +++ b/t/fixtures/ngcpcfg.cfg @@ -19,6 +19,10 @@ # location of service definitions [ -n "${SERVICES_POOL_BASE:-}" ] || SERVICES_POOL_BASE="${NGCPCTL_MAIN}/templates" +# location of sites info for templates +[ -n "${SITES_DIR:-}" ] || SITES_DIR="${NGCPCTL_MAIN}/sites" +[ -n "${SITES_CONFIG:-}" ] || SITES_CONFIG="${NGCPCTL_MAIN}/sites.yml" + # timestamp format for console output [ -n "${TIME_FORMAT:-}" ] || TIME_FORMAT="+%F %T" diff --git a/t/fixtures/ngcpcfg_carrier.cfg b/t/fixtures/ngcpcfg_carrier.cfg index c6611553..4b345f4f 100644 --- a/t/fixtures/ngcpcfg_carrier.cfg +++ b/t/fixtures/ngcpcfg_carrier.cfg @@ -21,6 +21,10 @@ # location of service definitions [ -n "${SERVICES_POOL_BASE:-}" ] || SERVICES_POOL_BASE="${NGCPCTL_MAIN}/templates" +# location of sites info for templates +[ -n "${SITES_DIR:-}" ] || SITES_DIR="${NGCPCTL_MAIN}/sites" +[ -n "${SITES_CONFIG:-}" ] || SITES_CONFIG="${NGCPCTL_MAIN}/sites.yml" + # timestamp format for console output [ -n "${TIME_FORMAT:-}" ] || TIME_FORMAT="+%F %T" diff --git a/t/fixtures/ngcpcfg_carrier_instances.cfg b/t/fixtures/ngcpcfg_carrier_instances.cfg index b02cdee6..637fd684 100644 --- a/t/fixtures/ngcpcfg_carrier_instances.cfg +++ b/t/fixtures/ngcpcfg_carrier_instances.cfg @@ -21,6 +21,10 @@ # location of service definitions [ -n "${SERVICES_POOL_BASE:-}" ] || SERVICES_POOL_BASE="${NGCPCTL_MAIN}/templates" +# location of sites info for templates +[ -n "${SITES_DIR:-}" ] || SITES_DIR="${NGCPCTL_MAIN}/sites" +[ -n "${SITES_CONFIG:-}" ] || SITES_CONFIG="${NGCPCTL_MAIN}/sites.yml" + # location of instances info for templates [ -n "${TEMPLATE_INSTANCES:-}" ] || TEMPLATE_INSTANCES="${NGCPCTL_MAIN}/instances.yml" diff --git a/t/fixtures/ngcpcfg_network_interfaces.cfg b/t/fixtures/ngcpcfg_network_interfaces.cfg index 00d64c08..fa42e77d 100644 --- a/t/fixtures/ngcpcfg_network_interfaces.cfg +++ b/t/fixtures/ngcpcfg_network_interfaces.cfg @@ -19,6 +19,10 @@ # location of service definitions [ -n "${SERVICES_POOL_BASE:-}" ] || SERVICES_POOL_BASE="${NGCPCTL_MAIN}/templates" +# location of sites info for templates +[ -n "${SITES_DIR:-}" ] || SITES_DIR="${NGCPCTL_MAIN}/sites" +[ -n "${SITES_CONFIG:-}" ] || SITES_CONFIG="${NGCPCTL_MAIN}/sites.yml" + # timestamp format for console output [ -n "${TIME_FORMAT:-}" ] || TIME_FORMAT="+%F %T" diff --git a/t/fixtures/ngcpcfg_pro.cfg b/t/fixtures/ngcpcfg_pro.cfg index 1a449455..761c2ca5 100644 --- a/t/fixtures/ngcpcfg_pro.cfg +++ b/t/fixtures/ngcpcfg_pro.cfg @@ -21,6 +21,10 @@ # location of service definitions [ -n "${SERVICES_POOL_BASE:-}" ] || SERVICES_POOL_BASE="${NGCPCTL_MAIN}/templates" +# location of sites info for templates +[ -n "${SITES_DIR:-}" ] || SITES_DIR="${NGCPCTL_MAIN}/sites" +[ -n "${SITES_CONFIG:-}" ] || SITES_CONFIG="${NGCPCTL_MAIN}/sites.yml" + # timestamp format for console output [ -n "${TIME_FORMAT:-}" ] || TIME_FORMAT="+%F %T" diff --git a/t/fixtures/ngcpcfg_pro_instances.cfg b/t/fixtures/ngcpcfg_pro_instances.cfg index 9b4eb581..3c3980dd 100644 --- a/t/fixtures/ngcpcfg_pro_instances.cfg +++ b/t/fixtures/ngcpcfg_pro_instances.cfg @@ -21,6 +21,10 @@ # location of service definitions [ -n "${SERVICES_POOL_BASE:-}" ] || SERVICES_POOL_BASE="${NGCPCTL_MAIN}/templates" +# location of sites info for templates +[ -n "${SITES_DIR:-}" ] || SITES_DIR="${NGCPCTL_MAIN}/sites" +[ -n "${SITES_CONFIG:-}" ] || SITES_CONFIG="${NGCPCTL_MAIN}/sites.yml" + # timestamp format for console output [ -n "${TIME_FORMAT:-}" ] || TIME_FORMAT="+%F %T" diff --git a/t/fixtures/programs.py b/t/fixtures/programs.py index 57811ad8..eaecad5a 100644 --- a/t/fixtures/programs.py +++ b/t/fixtures/programs.py @@ -25,6 +25,8 @@ CFG_KEYS = [ "PAIR_CONFIG", "HOST_CONFIG", "LOCAL_CONFIG", + "SITES_DIR", + "SITES_CONFIG", "CONSTANTS_CONFIG", "MAINTENANCE_CONFIG", "NETWORK_CONFIG", diff --git a/t/fixtures/read_cfg.sh b/t/fixtures/read_cfg.sh index af0e86ec..b42fa4bb 100755 --- a/t/fixtures/read_cfg.sh +++ b/t/fixtures/read_cfg.sh @@ -26,6 +26,10 @@ echo "TEMPLATE_POOL_BASE=${TEMPLATE_POOL_BASE:-}" # location of service definitions echo "SERVICES_POOL_BASE=${SERVICES_POOL_BASE:-}" +# location of sites info for templates +echo "SITES_DIR=${SITES_DIR:-}" +echo "SITES_CONFIG=${SITES_CONFIG:-}" + # location of instances info for templates echo "TEMPLATE_INSTANCES=${TEMPLATE_INSTANCES:-}"