aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--.gitignore4
-rw-r--r--DPDK_VPP_VER2
-rw-r--r--GPL/traffic_profiles/trex/trex-stl-3n-ethip4-ip4src1000ip4dst1000.py165
-rw-r--r--GPL/traffic_profiles/trex/trex-stl-3n-ethip4-ip4src100ip4dst100.py165
-rw-r--r--GPL/traffic_profiles/trex/trex-stl-3n-ethip4-ip4src1ip4dst1.py95
-rw-r--r--GPL/traffic_profiles/trex/trex-stl-3n-ethip4-ip4src2ip4dst2.py165
-rw-r--r--GPL/traffic_profiles/trex/trex-stl-3n-ethip4-ip4src4ip4dst4.py165
-rw-r--r--GPL/traffic_profiles/trex/trex-stl-3n-ethip4-ip4src8ip4dst8.py165
-rw-r--r--PyPI/jumpavg/README.rst5
-rw-r--r--PyPI/jumpavg/setup.py6
-rw-r--r--VPP_DEVICE_IMAGE_UBUNTU_JAMMY1
-rw-r--r--VPP_DEVICE_IMAGE_UBUNTU_JAMMY_ARM1
-rw-r--r--VPP_STABLE_VER_UBUNTU_FOCAL2
-rw-r--r--VPP_STABLE_VER_UBUNTU_JAMMY1
-rw-r--r--csit.infra.dash/Dockerfile (renamed from resources/tools/dash/Dockerfile)0
-rw-r--r--csit.infra.dash/app/.ebextensions/cron-linux.config (renamed from resources/tools/dash/app/.ebextensions/cron-linux.config)0
-rw-r--r--csit.infra.dash/app/Procfile (renamed from resources/tools/dash/app/Procfile)0
-rw-r--r--csit.infra.dash/app/app.ini (renamed from resources/tools/dash/app/app.ini)5
-rw-r--r--csit.infra.dash/app/cdash/__init__.py (renamed from resources/tools/dash/app/pal/__init__.py)24
-rw-r--r--csit.infra.dash/app/cdash/data/__init__.py (renamed from resources/tools/dash/app/pal/data/__init__.py)0
-rw-r--r--csit.infra.dash/app/cdash/data/data.py (renamed from resources/tools/dash/app/pal/data/data.py)0
-rw-r--r--csit.infra.dash/app/cdash/data/data.yaml (renamed from resources/tools/dash/app/pal/data/data.yaml)0
-rw-r--r--csit.infra.dash/app/cdash/debug.py (renamed from resources/tools/dash/app/pal/debug.py)3
-rw-r--r--csit.infra.dash/app/cdash/news/__init__.py (renamed from resources/tools/dash/app/pal/news/__init__.py)0
-rw-r--r--csit.infra.dash/app/cdash/news/layout.py (renamed from resources/tools/dash/app/pal/news/layout.py)433
-rw-r--r--csit.infra.dash/app/cdash/news/news.py (renamed from resources/tools/dash/app/pal/news/news.py)5
-rw-r--r--csit.infra.dash/app/cdash/news/tables.py176
-rw-r--r--csit.infra.dash/app/cdash/report/__init__.py (renamed from resources/tools/dash/app/pal/report/__init__.py)0
-rw-r--r--csit.infra.dash/app/cdash/report/graphs.py (renamed from resources/tools/dash/app/pal/report/graphs.py)0
-rw-r--r--csit.infra.dash/app/cdash/report/layout.py (renamed from resources/tools/dash/app/pal/report/layout.py)748
-rw-r--r--csit.infra.dash/app/cdash/report/layout.yaml (renamed from resources/tools/dash/app/pal/report/layout.yaml)113
-rw-r--r--csit.infra.dash/app/cdash/report/report.py (renamed from resources/tools/dash/app/pal/report/report.py)5
-rw-r--r--csit.infra.dash/app/cdash/routes.py (renamed from resources/tools/dash/app/pal/routes.py)4
-rw-r--r--csit.infra.dash/app/cdash/static/dist/img/favicon.svg (renamed from resources/tools/dash/app/pal/static/dist/img/favicon.svg)0
-rw-r--r--csit.infra.dash/app/cdash/static/img/logo.svg (renamed from resources/tools/dash/app/pal/static/img/logo.svg)0
-rw-r--r--csit.infra.dash/app/cdash/static/sass/_bootswatch.scss178
-rw-r--r--csit.infra.dash/app/cdash/static/sass/_variables.scss103
-rw-r--r--csit.infra.dash/app/cdash/static/sass/bootstrap/_accordion.scss149
-rw-r--r--csit.infra.dash/app/cdash/static/sass/bootstrap/_alert.scss71
-rw-r--r--csit.infra.dash/app/cdash/static/sass/bootstrap/_badge.scss38
-rw-r--r--csit.infra.dash/app/cdash/static/sass/bootstrap/_breadcrumb.scss40
-rw-r--r--csit.infra.dash/app/cdash/static/sass/bootstrap/_button-group.scss142
-rw-r--r--csit.infra.dash/app/cdash/static/sass/bootstrap/_buttons.scss201
-rw-r--r--csit.infra.dash/app/cdash/static/sass/bootstrap/_card.scss234
-rw-r--r--csit.infra.dash/app/cdash/static/sass/bootstrap/_carousel.scss229
-rw-r--r--csit.infra.dash/app/cdash/static/sass/bootstrap/_close.scss40
-rw-r--r--csit.infra.dash/app/cdash/static/sass/bootstrap/_containers.scss41
-rw-r--r--csit.infra.dash/app/cdash/static/sass/bootstrap/_dropdown.scss249
-rw-r--r--csit.infra.dash/app/cdash/static/sass/bootstrap/_forms.scss9
-rw-r--r--csit.infra.dash/app/cdash/static/sass/bootstrap/_functions.scss302
-rw-r--r--csit.infra.dash/app/cdash/static/sass/bootstrap/_grid.scss33
-rw-r--r--csit.infra.dash/app/cdash/static/sass/bootstrap/_helpers.scss10
-rw-r--r--csit.infra.dash/app/cdash/static/sass/bootstrap/_images.scss42
-rw-r--r--csit.infra.dash/app/cdash/static/sass/bootstrap/_list-group.scss192
-rw-r--r--csit.infra.dash/app/cdash/static/sass/bootstrap/_maps.scss54
-rw-r--r--csit.infra.dash/app/cdash/static/sass/bootstrap/_mixins.scss43
-rw-r--r--csit.infra.dash/app/cdash/static/sass/bootstrap/_modal.scss237
-rw-r--r--csit.infra.dash/app/cdash/static/sass/bootstrap/_nav.scss172
-rw-r--r--csit.infra.dash/app/cdash/static/sass/bootstrap/_navbar.scss278
-rw-r--r--csit.infra.dash/app/cdash/static/sass/bootstrap/_offcanvas.scss144
-rw-r--r--csit.infra.dash/app/cdash/static/sass/bootstrap/_pagination.scss109
-rw-r--r--csit.infra.dash/app/cdash/static/sass/bootstrap/_placeholders.scss51
-rw-r--r--csit.infra.dash/app/cdash/static/sass/bootstrap/_popover.scss196
-rw-r--r--csit.infra.dash/app/cdash/static/sass/bootstrap/_progress.scss59
-rw-r--r--csit.infra.dash/app/cdash/static/sass/bootstrap/_reboot.scss610
-rw-r--r--csit.infra.dash/app/cdash/static/sass/bootstrap/_root.scss73
-rw-r--r--csit.infra.dash/app/cdash/static/sass/bootstrap/_spinners.scss85
-rw-r--r--csit.infra.dash/app/cdash/static/sass/bootstrap/_tables.scss164
-rw-r--r--csit.infra.dash/app/cdash/static/sass/bootstrap/_toasts.scss71
-rw-r--r--csit.infra.dash/app/cdash/static/sass/bootstrap/_tooltip.scss120
-rw-r--r--csit.infra.dash/app/cdash/static/sass/bootstrap/_transitions.scss27
-rw-r--r--csit.infra.dash/app/cdash/static/sass/bootstrap/_type.scss106
-rw-r--r--csit.infra.dash/app/cdash/static/sass/bootstrap/_utilities.scss647
-rw-r--r--csit.infra.dash/app/cdash/static/sass/bootstrap/_variables.scss1634
-rw-r--r--csit.infra.dash/app/cdash/static/sass/bootstrap/bootstrap-grid.scss64
-rw-r--r--csit.infra.dash/app/cdash/static/sass/bootstrap/bootstrap-reboot.scss9
-rw-r--r--csit.infra.dash/app/cdash/static/sass/bootstrap/bootstrap-utilities.scss15
-rw-r--r--csit.infra.dash/app/cdash/static/sass/bootstrap/bootstrap.scss51
-rw-r--r--csit.infra.dash/app/cdash/static/sass/bootstrap/forms/_floating-labels.scss75
-rw-r--r--csit.infra.dash/app/cdash/static/sass/bootstrap/forms/_form-check.scss175
-rw-r--r--csit.infra.dash/app/cdash/static/sass/bootstrap/forms/_form-control.scss194
-rw-r--r--csit.infra.dash/app/cdash/static/sass/bootstrap/forms/_form-range.scss91
-rw-r--r--csit.infra.dash/app/cdash/static/sass/bootstrap/forms/_form-select.scss71
-rw-r--r--csit.infra.dash/app/cdash/static/sass/bootstrap/forms/_form-text.scss11
-rw-r--r--csit.infra.dash/app/cdash/static/sass/bootstrap/forms/_input-group.scss132
-rw-r--r--csit.infra.dash/app/cdash/static/sass/bootstrap/forms/_labels.scss36
-rw-r--r--csit.infra.dash/app/cdash/static/sass/bootstrap/forms/_validation.scss12
-rw-r--r--csit.infra.dash/app/cdash/static/sass/bootstrap/helpers/_clearfix.scss3
-rw-r--r--csit.infra.dash/app/cdash/static/sass/bootstrap/helpers/_color-bg.scss10
-rw-r--r--csit.infra.dash/app/cdash/static/sass/bootstrap/helpers/_colored-links.scss12
-rw-r--r--csit.infra.dash/app/cdash/static/sass/bootstrap/helpers/_position.scss36
-rw-r--r--csit.infra.dash/app/cdash/static/sass/bootstrap/helpers/_ratio.scss26
-rw-r--r--csit.infra.dash/app/cdash/static/sass/bootstrap/helpers/_stacks.scss15
-rw-r--r--csit.infra.dash/app/cdash/static/sass/bootstrap/helpers/_stretched-link.scss15
-rw-r--r--csit.infra.dash/app/cdash/static/sass/bootstrap/helpers/_text-truncation.scss7
-rw-r--r--csit.infra.dash/app/cdash/static/sass/bootstrap/helpers/_visually-hidden.scss8
-rw-r--r--csit.infra.dash/app/cdash/static/sass/bootstrap/helpers/_vr.scss8
-rw-r--r--csit.infra.dash/app/cdash/static/sass/bootstrap/mixins/_alert.scss15
-rw-r--r--csit.infra.dash/app/cdash/static/sass/bootstrap/mixins/_backdrop.scss14
-rw-r--r--csit.infra.dash/app/cdash/static/sass/bootstrap/mixins/_banner.scss9
-rw-r--r--csit.infra.dash/app/cdash/static/sass/bootstrap/mixins/_border-radius.scss78
-rw-r--r--csit.infra.dash/app/cdash/static/sass/bootstrap/mixins/_box-shadow.scss18
-rw-r--r--csit.infra.dash/app/cdash/static/sass/bootstrap/mixins/_breakpoints.scss127
-rw-r--r--csit.infra.dash/app/cdash/static/sass/bootstrap/mixins/_buttons.scss70
-rw-r--r--csit.infra.dash/app/cdash/static/sass/bootstrap/mixins/_caret.scss64
-rw-r--r--csit.infra.dash/app/cdash/static/sass/bootstrap/mixins/_clearfix.scss9
-rw-r--r--csit.infra.dash/app/cdash/static/sass/bootstrap/mixins/_color-scheme.scss7
-rw-r--r--csit.infra.dash/app/cdash/static/sass/bootstrap/mixins/_container.scss11
-rw-r--r--csit.infra.dash/app/cdash/static/sass/bootstrap/mixins/_deprecate.scss10
-rw-r--r--csit.infra.dash/app/cdash/static/sass/bootstrap/mixins/_forms.scss152
-rw-r--r--csit.infra.dash/app/cdash/static/sass/bootstrap/mixins/_gradients.scss47
-rw-r--r--csit.infra.dash/app/cdash/static/sass/bootstrap/mixins/_grid.scss151
-rw-r--r--csit.infra.dash/app/cdash/static/sass/bootstrap/mixins/_image.scss16
-rw-r--r--csit.infra.dash/app/cdash/static/sass/bootstrap/mixins/_list-group.scss24
-rw-r--r--csit.infra.dash/app/cdash/static/sass/bootstrap/mixins/_lists.scss7
-rw-r--r--csit.infra.dash/app/cdash/static/sass/bootstrap/mixins/_pagination.scss10
-rw-r--r--csit.infra.dash/app/cdash/static/sass/bootstrap/mixins/_reset-text.scss17
-rw-r--r--csit.infra.dash/app/cdash/static/sass/bootstrap/mixins/_resize.scss6
-rw-r--r--csit.infra.dash/app/cdash/static/sass/bootstrap/mixins/_table-variants.scss24
-rw-r--r--csit.infra.dash/app/cdash/static/sass/bootstrap/mixins/_text-truncate.scss8
-rw-r--r--csit.infra.dash/app/cdash/static/sass/bootstrap/mixins/_transition.scss26
-rw-r--r--csit.infra.dash/app/cdash/static/sass/bootstrap/mixins/_utilities.scss97
-rw-r--r--csit.infra.dash/app/cdash/static/sass/bootstrap/mixins/_visually-hidden.scss29
-rw-r--r--csit.infra.dash/app/cdash/static/sass/bootstrap/utilities/_api.scss47
-rw-r--r--csit.infra.dash/app/cdash/static/sass/bootstrap/vendor/_rfs.scss354
-rw-r--r--csit.infra.dash/app/cdash/static/sass/lux.scss9
-rw-r--r--csit.infra.dash/app/cdash/stats/__init__.py (renamed from resources/tools/dash/app/pal/stats/__init__.py)0
-rw-r--r--csit.infra.dash/app/cdash/stats/graphs.py (renamed from resources/tools/dash/app/pal/stats/graphs.py)24
-rw-r--r--csit.infra.dash/app/cdash/stats/layout.py (renamed from resources/tools/dash/app/pal/stats/layout.py)249
-rw-r--r--csit.infra.dash/app/cdash/stats/layout.yaml (renamed from resources/tools/dash/app/pal/stats/layout.yaml)38
-rw-r--r--csit.infra.dash/app/cdash/stats/stats.py (renamed from resources/tools/dash/app/pal/stats/stats.py)5
-rw-r--r--csit.infra.dash/app/cdash/templates/base_layout.jinja2 (renamed from resources/tools/dash/app/pal/templates/index_layout.jinja2)12
-rw-r--r--csit.infra.dash/app/cdash/templates/dash_layout.jinja2 (renamed from resources/tools/dash/app/pal/templates/report_layout.jinja2)2
-rw-r--r--csit.infra.dash/app/cdash/templates/layout.jinja2 (renamed from resources/tools/dash/app/pal/templates/base_layout.jinja2)4
-rw-r--r--csit.infra.dash/app/cdash/trending/__init__.py (renamed from resources/tools/dash/app/pal/trending/__init__.py)0
-rw-r--r--csit.infra.dash/app/cdash/trending/graphs.py (renamed from resources/tools/dash/app/pal/trending/graphs.py)42
-rw-r--r--csit.infra.dash/app/cdash/trending/layout.py (renamed from resources/tools/dash/app/pal/trending/layout.py)698
-rw-r--r--csit.infra.dash/app/cdash/trending/layout.yaml (renamed from resources/tools/dash/app/pal/trending/layout.yaml)83
-rw-r--r--csit.infra.dash/app/cdash/trending/trending.py (renamed from resources/tools/dash/app/pal/trending/trending.py)5
-rw-r--r--csit.infra.dash/app/cdash/utils/__init__.py (renamed from resources/tools/dash/app/pal/utils/__init__.py)0
-rw-r--r--csit.infra.dash/app/cdash/utils/constants.py (renamed from resources/tools/dash/app/pal/utils/constants.py)77
-rw-r--r--csit.infra.dash/app/cdash/utils/tooltips.yaml (renamed from resources/tools/dash/app/pal/utils/tooltips.yaml)2
-rw-r--r--csit.infra.dash/app/cdash/utils/url_processing.py (renamed from resources/tools/dash/app/pal/utils/url_processing.py)0
-rw-r--r--csit.infra.dash/app/cdash/utils/utils.py (renamed from resources/tools/dash/app/pal/utils/utils.py)0
-rw-r--r--csit.infra.dash/app/config.py (renamed from resources/tools/dash/app/config.py)7
-rw-r--r--csit.infra.dash/app/requirements.txt83
-rw-r--r--csit.infra.dash/app/wsgi.py (renamed from resources/tools/dash/app/wsgi.py)2
-rw-r--r--csit.infra.dash/docker-compose.yaml (renamed from resources/tools/dash/docker-compose.yaml)2
-rw-r--r--csit.infra.etl/coverage_device_rls2210.py (renamed from csit.infra.etl/coverage_rls2206.py)53
-rw-r--r--csit.infra.etl/coverage_mrr_rls2210.py170
-rw-r--r--csit.infra.etl/coverage_ndrpdr_rls2210.py170
-rw-r--r--csit.infra.etl/coverage_soak_rls2210.py170
-rw-r--r--csit.infra.etl/iterative_mrr_rls2210.py (renamed from csit.infra.etl/iterative_rls2206.py)53
-rw-r--r--csit.infra.etl/iterative_ndrpdr_rls2210.py170
-rw-r--r--csit.infra.etl/iterative_soak_rls2210.py170
-rw-r--r--csit.infra.etl/trending_mrr.py (renamed from csit.infra.etl/trending.py)51
-rw-r--r--csit.infra.etl/trending_ndrpdr.py171
-rw-r--r--csit.infra.etl/trending_soak.py171
-rw-r--r--docs/cpta/data/index.rst119
-rw-r--r--docs/cpta/index.rst83
-rw-r--r--docs/cpta/introduction/dashboard.rst293
-rw-r--r--docs/cpta/introduction/failures.rst104
-rw-r--r--docs/cpta/introduction/introduction.rst24
-rw-r--r--docs/cpta/introduction/weekly.rst107
-rw-r--r--docs/cpta/ndrpdr_latency_trending/container_memif-2n-clx-cx556a.rst18
-rw-r--r--docs/cpta/ndrpdr_latency_trending/container_memif-2n-clx-e810cq.rst18
-rw-r--r--docs/cpta/ndrpdr_latency_trending/container_memif-2n-clx-xxv710.rst34
-rw-r--r--docs/cpta/ndrpdr_latency_trending/container_memif-2n-icx-xxv710.rst18
-rw-r--r--docs/cpta/ndrpdr_latency_trending/container_memif-2n-skx-x710.rst18
-rw-r--r--docs/cpta/ndrpdr_latency_trending/container_memif-2n-skx-xxv710.rst34
-rw-r--r--docs/cpta/ndrpdr_latency_trending/container_memif-3n-skx-x710.rst18
-rw-r--r--docs/cpta/ndrpdr_latency_trending/container_memif-3n-skx-xxv710.rst34
-rw-r--r--docs/cpta/ndrpdr_latency_trending/container_memif.rst11
-rw-r--r--docs/cpta/ndrpdr_latency_trending/ip4-2n-clx-cx556a.rst50
-rw-r--r--docs/cpta/ndrpdr_latency_trending/ip4-2n-clx-e810cq.rst66
-rw-r--r--docs/cpta/ndrpdr_latency_trending/ip4-2n-clx-x710.rst18
-rw-r--r--docs/cpta/ndrpdr_latency_trending/ip4-2n-clx-xxv710.rst98
-rw-r--r--docs/cpta/ndrpdr_latency_trending/ip4-2n-icx-xxv710.rst66
-rw-r--r--docs/cpta/ndrpdr_latency_trending/ip4-2n-skx-x710.rst18
-rw-r--r--docs/cpta/ndrpdr_latency_trending/ip4-2n-skx-xxv710.rst82
-rw-r--r--docs/cpta/ndrpdr_latency_trending/ip4-3n-icx-xxv710.rst18
-rw-r--r--docs/cpta/ndrpdr_latency_trending/ip4-3n-skx-x710.rst18
-rw-r--r--docs/cpta/ndrpdr_latency_trending/ip4-3n-skx-xxv710.rst34
-rw-r--r--docs/cpta/ndrpdr_latency_trending/ip4.rst15
-rw-r--r--docs/cpta/ndrpdr_latency_trending/ip4_tunnels-2n-icx-xxv710.rst18
-rw-r--r--docs/cpta/ndrpdr_latency_trending/ip4_tunnels-3n-icx-xxv710.rst18
-rw-r--r--docs/cpta/ndrpdr_latency_trending/ip4_tunnels-3n-skx-xxv710.rst34
-rw-r--r--docs/cpta/ndrpdr_latency_trending/ip4_tunnels.rst10
-rw-r--r--docs/cpta/ndrpdr_latency_trending/ip6-2n-clx-cx556a.rst18
-rw-r--r--docs/cpta/ndrpdr_latency_trending/ip6-2n-clx-e810cq.rst18
-rw-r--r--docs/cpta/ndrpdr_latency_trending/ip6-2n-clx-x710.rst18
-rw-r--r--docs/cpta/ndrpdr_latency_trending/ip6-2n-clx-xxv710.rst66
-rw-r--r--docs/cpta/ndrpdr_latency_trending/ip6-2n-icx-xxv710.rst50
-rw-r--r--docs/cpta/ndrpdr_latency_trending/ip6-2n-skx-xxv710.rst66
-rw-r--r--docs/cpta/ndrpdr_latency_trending/ip6-3n-icx-xxv710.rst18
-rw-r--r--docs/cpta/ndrpdr_latency_trending/ip6-3n-skx-x710.rst18
-rw-r--r--docs/cpta/ndrpdr_latency_trending/ip6-3n-skx-xxv710.rst34
-rw-r--r--docs/cpta/ndrpdr_latency_trending/ip6.rst13
-rw-r--r--docs/cpta/ndrpdr_latency_trending/l2-2n-clx-cx556a.rst34
-rw-r--r--docs/cpta/ndrpdr_latency_trending/l2-2n-clx-e810cq.rst34
-rw-r--r--docs/cpta/ndrpdr_latency_trending/l2-2n-clx-x710.rst18
-rw-r--r--docs/cpta/ndrpdr_latency_trending/l2-2n-clx-xxv710.rst50
-rw-r--r--docs/cpta/ndrpdr_latency_trending/l2-2n-icx-xxv710.rst34
-rw-r--r--docs/cpta/ndrpdr_latency_trending/l2-2n-skx-x710.rst34
-rw-r--r--docs/cpta/ndrpdr_latency_trending/l2-2n-skx-xxv710.rst66
-rw-r--r--docs/cpta/ndrpdr_latency_trending/l2-3n-icx-xxv710.rst18
-rw-r--r--docs/cpta/ndrpdr_latency_trending/l2-3n-skx-x710.rst18
-rw-r--r--docs/cpta/ndrpdr_latency_trending/l2-3n-skx-xxv710.rst50
-rw-r--r--docs/cpta/ndrpdr_latency_trending/l2.rst15
-rw-r--r--docs/cpta/ndrpdr_latency_trending/nat44-det-bidir-2n-clx-xxv710.rst18
-rw-r--r--docs/cpta/ndrpdr_latency_trending/nat44-det-bidir-2n-icx-xxv710.rst18
-rw-r--r--docs/cpta/ndrpdr_latency_trending/nat44-det-bidir-2n-skx-xxv710.rst18
-rw-r--r--docs/cpta/ndrpdr_latency_trending/nat44-det-bidir.rst8
-rw-r--r--docs/cpta/ndrpdr_latency_trending/nat44-ed-unidir-2n-clx-xxv710.rst18
-rw-r--r--docs/cpta/ndrpdr_latency_trending/nat44-ed-unidir-2n-icx-xxv710.rst18
-rw-r--r--docs/cpta/ndrpdr_latency_trending/nat44-ed-unidir-2n-skx-xxv710.rst18
-rw-r--r--docs/cpta/ndrpdr_latency_trending/nat44-ed-unidir.rst10
-rw-r--r--docs/cpta/ndrpdr_latency_trending/nat44.rst7
-rw-r--r--docs/cpta/ndrpdr_latency_trending/srv6-3n-icx-xxv710.rst18
-rw-r--r--docs/cpta/ndrpdr_latency_trending/srv6-3n-skx-xxv710.rst18
-rw-r--r--docs/cpta/ndrpdr_latency_trending/srv6.rst7
-rw-r--r--docs/cpta/ndrpdr_latency_trending/trex-2n-skx-x710.rst50
-rw-r--r--docs/cpta/ndrpdr_latency_trending/trex.rst6
-rw-r--r--docs/cpta/ndrpdr_latency_trending/vhost-2n-clx-cx556a.rst34
-rw-r--r--docs/cpta/ndrpdr_latency_trending/vhost-2n-clx-e810cq.rst18
-rw-r--r--docs/cpta/ndrpdr_latency_trending/vhost-2n-clx-xxv710.rst34
-rw-r--r--docs/cpta/ndrpdr_latency_trending/vhost-2n-icx-xxv710.rst18
-rw-r--r--docs/cpta/ndrpdr_latency_trending/vhost-2n-skx-x710.rst34
-rw-r--r--docs/cpta/ndrpdr_latency_trending/vhost-2n-skx-xxv710.rst66
-rw-r--r--docs/cpta/ndrpdr_latency_trending/vhost-3n-skx-x710.rst34
-rw-r--r--docs/cpta/ndrpdr_latency_trending/vhost-3n-skx-xxv710.rst82
-rw-r--r--docs/cpta/ndrpdr_latency_trending/vhost.rst12
-rw-r--r--docs/cpta/ndrpdr_trending/container_memif-2n-clx-cx556a.rst33
-rw-r--r--docs/cpta/ndrpdr_trending/container_memif-2n-clx-e810cq.rst33
-rw-r--r--docs/cpta/ndrpdr_trending/container_memif-2n-clx-xxv710.rst64
-rw-r--r--docs/cpta/ndrpdr_trending/container_memif-2n-icx-xxv710.rst33
-rw-r--r--docs/cpta/ndrpdr_trending/container_memif-2n-skx-x710.rst33
-rw-r--r--docs/cpta/ndrpdr_trending/container_memif-2n-skx-xxv710.rst64
-rw-r--r--docs/cpta/ndrpdr_trending/container_memif-3n-skx-x710.rst33
-rw-r--r--docs/cpta/ndrpdr_trending/container_memif-3n-skx-xxv710.rst64
-rw-r--r--docs/cpta/ndrpdr_trending/container_memif.rst11
-rw-r--r--docs/cpta/ndrpdr_trending/ip4-2n-clx-cx556a.rst95
-rw-r--r--docs/cpta/ndrpdr_trending/ip4-2n-clx-e810cq.rst130
-rw-r--r--docs/cpta/ndrpdr_trending/ip4-2n-clx-x710.rst43
-rw-r--r--docs/cpta/ndrpdr_trending/ip4-2n-clx-xxv710.rst225
-rw-r--r--docs/cpta/ndrpdr_trending/ip4-2n-icx-xxv710.rst132
-rw-r--r--docs/cpta/ndrpdr_trending/ip4-2n-skx-x710.rst43
-rw-r--r--docs/cpta/ndrpdr_trending/ip4-2n-skx-xxv710.rst192
-rw-r--r--docs/cpta/ndrpdr_trending/ip4-3n-icx-xxv710.rst33
-rw-r--r--docs/cpta/ndrpdr_trending/ip4-3n-skx-x710.rst35
-rw-r--r--docs/cpta/ndrpdr_trending/ip4-3n-skx-xxv710.rst68
-rw-r--r--docs/cpta/ndrpdr_trending/ip4.rst15
-rw-r--r--docs/cpta/ndrpdr_trending/ip4_tunnels-2n-icx-xxv710.rst33
-rw-r--r--docs/cpta/ndrpdr_trending/ip4_tunnels-3n-icx-xxv710 copy.rst33
-rw-r--r--docs/cpta/ndrpdr_trending/ip4_tunnels-3n-icx-xxv710.rst33
-rw-r--r--docs/cpta/ndrpdr_trending/ip4_tunnels-3n-skx-xxv710.rst64
-rw-r--r--docs/cpta/ndrpdr_trending/ip4_tunnels.rst9
-rw-r--r--docs/cpta/ndrpdr_trending/ip6-2n-clx-cx556a.rst35
-rw-r--r--docs/cpta/ndrpdr_trending/ip6-2n-clx-e810cq.rst39
-rw-r--r--docs/cpta/ndrpdr_trending/ip6-2n-clx-x710.rst43
-rw-r--r--docs/cpta/ndrpdr_trending/ip6-2n-clx-xxv710.rst167
-rw-r--r--docs/cpta/ndrpdr_trending/ip6-2n-icx-xxv710.rst101
-rw-r--r--docs/cpta/ndrpdr_trending/ip6-2n-skx-x710.rst43
-rw-r--r--docs/cpta/ndrpdr_trending/ip6-2n-skx-xxv710.rst134
-rw-r--r--docs/cpta/ndrpdr_trending/ip6-3n-icx-xxv710.rst33
-rw-r--r--docs/cpta/ndrpdr_trending/ip6-3n-skx-x710.rst35
-rw-r--r--docs/cpta/ndrpdr_trending/ip6-3n-skx-xxv710.rst68
-rw-r--r--docs/cpta/ndrpdr_trending/ip6.rst14
-rw-r--r--docs/cpta/ndrpdr_trending/ipsec-3n-icx-xxv710.rst333
-rw-r--r--docs/cpta/ndrpdr_trending/ipsec-3n-skx-xxv710.rst134
-rw-r--r--docs/cpta/ndrpdr_trending/ipsec.rst7
-rw-r--r--docs/cpta/ndrpdr_trending/l2-2n-clx-cx556a.rst64
-rw-r--r--docs/cpta/ndrpdr_trending/l2-2n-clx-e810cq.rst68
-rw-r--r--docs/cpta/ndrpdr_trending/l2-2n-clx-x710.rst43
-rw-r--r--docs/cpta/ndrpdr_trending/l2-2n-clx-xxv710.rst130
-rw-r--r--docs/cpta/ndrpdr_trending/l2-2n-icx-xxv710.rst66
-rw-r--r--docs/cpta/ndrpdr_trending/l2-2n-skx-x710.rst101
-rw-r--r--docs/cpta/ndrpdr_trending/l2-2n-skx-xxv710.rst159
-rw-r--r--docs/cpta/ndrpdr_trending/l2-3n-icx-xxv710.rst33
-rw-r--r--docs/cpta/ndrpdr_trending/l2-3n-skx-x710.rst35
-rw-r--r--docs/cpta/ndrpdr_trending/l2-3n-skx-xxv710.rst97
-rw-r--r--docs/cpta/ndrpdr_trending/l2.rst15
-rw-r--r--docs/cpta/ndrpdr_trending/nat44-det-bidir-2n-clx-xxv710.rst33
-rw-r--r--docs/cpta/ndrpdr_trending/nat44-det-bidir-2n-icx-xxv710.rst33
-rw-r--r--docs/cpta/ndrpdr_trending/nat44-det-bidir-2n-skx-xxv710.rst33
-rw-r--r--docs/cpta/ndrpdr_trending/nat44-det-bidir.rst8
-rw-r--r--docs/cpta/ndrpdr_trending/nat44-ed-tcp-cps-2n-clx-xxv710.rst33
-rw-r--r--docs/cpta/ndrpdr_trending/nat44-ed-tcp-cps-2n-icx-xxv710.rst33
-rw-r--r--docs/cpta/ndrpdr_trending/nat44-ed-tcp-cps-2n-skx-xxv710.rst33
-rw-r--r--docs/cpta/ndrpdr_trending/nat44-ed-tcp-cps.rst8
-rw-r--r--docs/cpta/ndrpdr_trending/nat44-ed-tcp-pps-2n-clx-xxv710.rst33
-rw-r--r--docs/cpta/ndrpdr_trending/nat44-ed-tcp-pps-2n-skx-xxv710.rst33
-rw-r--r--docs/cpta/ndrpdr_trending/nat44-ed-tcp-pps.rst7
-rw-r--r--docs/cpta/ndrpdr_trending/nat44-ed-tcp-tput-2n-clx-xxv710.rst64
-rw-r--r--docs/cpta/ndrpdr_trending/nat44-ed-tcp-tput-2n-icx-xxv710.rst64
-rw-r--r--docs/cpta/ndrpdr_trending/nat44-ed-tcp-tput-2n-skx-xxv710.rst64
-rw-r--r--docs/cpta/ndrpdr_trending/nat44-ed-tcp-tput.rst8
-rw-r--r--docs/cpta/ndrpdr_trending/nat44-ed-udp-cps-2n-clx-xxv710.rst33
-rw-r--r--docs/cpta/ndrpdr_trending/nat44-ed-udp-cps-2n-icx-xxv710.rst33
-rw-r--r--docs/cpta/ndrpdr_trending/nat44-ed-udp-cps-2n-skx-xxv710.rst33
-rw-r--r--docs/cpta/ndrpdr_trending/nat44-ed-udp-cps.rst8
-rw-r--r--docs/cpta/ndrpdr_trending/nat44-ed-udp-pps-2n-clx-xxv710.rst33
-rw-r--r--docs/cpta/ndrpdr_trending/nat44-ed-udp-pps-2n-skx-xxv710.rst33
-rw-r--r--docs/cpta/ndrpdr_trending/nat44-ed-udp-pps.rst7
-rw-r--r--docs/cpta/ndrpdr_trending/nat44-ed-udp-tput-2n-clx-xxv710.rst64
-rw-r--r--docs/cpta/ndrpdr_trending/nat44-ed-udp-tput-2n-icx-xxv710.rst64
-rw-r--r--docs/cpta/ndrpdr_trending/nat44-ed-udp-tput-2n-skx-xxv710.rst64
-rw-r--r--docs/cpta/ndrpdr_trending/nat44-ed-udp-tput.rst8
-rw-r--r--docs/cpta/ndrpdr_trending/nat44-ed-unidir-2n-clx-xxv710.rst33
-rw-r--r--docs/cpta/ndrpdr_trending/nat44-ed-unidir-2n-icx-xxv710.rst33
-rw-r--r--docs/cpta/ndrpdr_trending/nat44-ed-unidir-2n-skx-xxv710.rst33
-rw-r--r--docs/cpta/ndrpdr_trending/nat44-ed-unidir.rst10
-rw-r--r--docs/cpta/ndrpdr_trending/nat44.rst13
-rw-r--r--docs/cpta/ndrpdr_trending/srv6-3n-icx-xxv710.rst33
-rw-r--r--docs/cpta/ndrpdr_trending/srv6-3n-skx-xxv710.rst33
-rw-r--r--docs/cpta/ndrpdr_trending/srv6.rst7
-rw-r--r--docs/cpta/ndrpdr_trending/trex-2n-skx-x710.rst147
-rw-r--r--docs/cpta/ndrpdr_trending/trex.rst6
-rw-r--r--docs/cpta/ndrpdr_trending/vhost-2n-clx-cx556a.rst64
-rw-r--r--docs/cpta/ndrpdr_trending/vhost-2n-clx-e810cq.rst35
-rw-r--r--docs/cpta/ndrpdr_trending/vhost-2n-clx-xxv710.rst68
-rw-r--r--docs/cpta/ndrpdr_trending/vhost-2n-icx-xxv710.rst33
-rw-r--r--docs/cpta/ndrpdr_trending/vhost-2n-skx-x710.rst64
-rw-r--r--docs/cpta/ndrpdr_trending/vhost-2n-skx-xxv710.rst126
-rw-r--r--docs/cpta/ndrpdr_trending/vhost-3n-skx-x710.rst64
-rw-r--r--docs/cpta/ndrpdr_trending/vhost-3n-skx-xxv710.rst157
-rw-r--r--docs/cpta/ndrpdr_trending/vhost.rst12
-rw-r--r--docs/cpta/stats/dpdk_mrr.rst98
-rw-r--r--docs/cpta/stats/trex_ndrpdr.rst14
-rw-r--r--docs/cpta/stats/vpp_mrr.rst158
-rw-r--r--docs/cpta/stats/vpp_ndrpdr.rst62
-rw-r--r--docs/cpta/trending/container_memif-2n-clx-cx556a.rst47
-rw-r--r--docs/cpta/trending/container_memif-2n-clx-e810cq.rst47
-rw-r--r--docs/cpta/trending/container_memif-2n-clx-xxv710.rst92
-rw-r--r--docs/cpta/trending/container_memif-2n-icx-xxv710.rst47
-rw-r--r--docs/cpta/trending/container_memif-2n-skx-xxv710.rst92
-rw-r--r--docs/cpta/trending/container_memif-2n-zn2-cx556a.rst47
-rw-r--r--docs/cpta/trending/container_memif-2n-zn2-xxv710.rst92
-rw-r--r--docs/cpta/trending/container_memif-3n-skx-xxv710.rst92
-rw-r--r--docs/cpta/trending/container_memif-3n-tsh-x520.rst47
-rw-r--r--docs/cpta/trending/container_memif.rst14
-rw-r--r--docs/cpta/trending/dpdk-2n-clx-x710.rst54
-rw-r--r--docs/cpta/trending/dpdk-2n-clx-xxv710.rst50
-rw-r--r--docs/cpta/trending/dpdk-2n-icx-xxv710.rst50
-rw-r--r--docs/cpta/trending/dpdk-2n-skx-x710.rst54
-rw-r--r--docs/cpta/trending/dpdk-2n-skx-xxv710.rst53
-rw-r--r--docs/cpta/trending/dpdk-2n-tx2-xl710.rst50
-rw-r--r--docs/cpta/trending/dpdk-2n-zn2-x710.rst54
-rw-r--r--docs/cpta/trending/dpdk-2n-zn2-xxv710.rst53
-rw-r--r--docs/cpta/trending/dpdk-3n-icx-xxv710.rst50
-rw-r--r--docs/cpta/trending/dpdk-3n-skx-x710.rst54
-rw-r--r--docs/cpta/trending/dpdk-3n-skx-xxv710.rst54
-rw-r--r--docs/cpta/trending/dpdk-3n-tsh-x520.rst50
-rw-r--r--docs/cpta/trending/dpdk.rst17
-rw-r--r--docs/cpta/trending/ip4-2n-aws-nitro50g.rst68
-rw-r--r--docs/cpta/trending/ip4-2n-clx-cx556a.rst146
-rw-r--r--docs/cpta/trending/ip4-2n-clx-e810cq.rst192
-rw-r--r--docs/cpta/trending/ip4-2n-clx-x710.rst63
-rw-r--r--docs/cpta/trending/ip4-2n-clx-xxv710.rst233
-rw-r--r--docs/cpta/trending/ip4-2n-dnv-x553.rst47
-rw-r--r--docs/cpta/trending/ip4-2n-icx-xxv710.rst191
-rw-r--r--docs/cpta/trending/ip4-2n-skx-x710.rst63
-rw-r--r--docs/cpta/trending/ip4-2n-skx-xxv710.rst341
-rw-r--r--docs/cpta/trending/ip4-2n-tx2-xl710.rst149
-rw-r--r--docs/cpta/trending/ip4-2n-zn2-cx556a.rst146
-rw-r--r--docs/cpta/trending/ip4-2n-zn2-x710.rst63
-rw-r--r--docs/cpta/trending/ip4-2n-zn2-xxv710.rst234
-rw-r--r--docs/cpta/trending/ip4-3n-alt-xl710.rst92
-rw-r--r--docs/cpta/trending/ip4-3n-aws-nitro50g.rst68
-rw-r--r--docs/cpta/trending/ip4-3n-dnv-x553.rst50
-rw-r--r--docs/cpta/trending/ip4-3n-icx-xxv710.rst47
-rw-r--r--docs/cpta/trending/ip4-3n-skx-x710.rst51
-rw-r--r--docs/cpta/trending/ip4-3n-skx-xxv710.rst195
-rw-r--r--docs/cpta/trending/ip4-3n-tsh-x520.rst104
-rw-r--r--docs/cpta/trending/ip4.rst25
-rw-r--r--docs/cpta/trending/ip4_tunnels-2n-clx-xxv710.rst47
-rw-r--r--docs/cpta/trending/ip4_tunnels-2n-icx-xxv710.rst47
-rw-r--r--docs/cpta/trending/ip4_tunnels-2n-skx-xxv710.rst47
-rw-r--r--docs/cpta/trending/ip4_tunnels-2n-zn2-xxv710.rst47
-rw-r--r--docs/cpta/trending/ip4_tunnels-3n-alt-xl710.rst47
-rw-r--r--docs/cpta/trending/ip4_tunnels-3n-dnv-x553.rst56
-rw-r--r--docs/cpta/trending/ip4_tunnels-3n-icx-e810xxv.rst47
-rw-r--r--docs/cpta/trending/ip4_tunnels-3n-icx-xxv710.rst47
-rw-r--r--docs/cpta/trending/ip4_tunnels-3n-skx-xxv710.rst56
-rw-r--r--docs/cpta/trending/ip4_tunnels-3n-tsh-x520.rst56
-rw-r--r--docs/cpta/trending/ip4_tunnels.rst15
-rw-r--r--docs/cpta/trending/ip6-2n-aws-nitro50g.rst68
-rw-r--r--docs/cpta/trending/ip6-2n-clx-cx556a.rst50
-rw-r--r--docs/cpta/trending/ip6-2n-clx-e810cq.rst56
-rw-r--r--docs/cpta/trending/ip6-2n-clx-x710.rst62
-rw-r--r--docs/cpta/trending/ip6-2n-clx-xxv710.rst243
-rw-r--r--docs/cpta/trending/ip6-2n-dnv-x553.rst57
-rw-r--r--docs/cpta/trending/ip6-2n-icx-xxv710.rst146
-rw-r--r--docs/cpta/trending/ip6-2n-skx-x710.rst62
-rw-r--r--docs/cpta/trending/ip6-2n-skx-xxv710.rst194
-rw-r--r--docs/cpta/trending/ip6-2n-tx2-xl710.rst98
-rw-r--r--docs/cpta/trending/ip6-2n-zn2-cx556a.rst50
-rw-r--r--docs/cpta/trending/ip6-2n-zn2-x710.rst62
-rw-r--r--docs/cpta/trending/ip6-2n-zn2-xxv710.rst242
-rw-r--r--docs/cpta/trending/ip6-3n-alt-xl710.rst50
-rw-r--r--docs/cpta/trending/ip6-3n-dnv-x553.rst56
-rw-r--r--docs/cpta/trending/ip6-3n-icx-xxv710.rst47
-rw-r--r--docs/cpta/trending/ip6-3n-skx-x710.rst50
-rw-r--r--docs/cpta/trending/ip6-3n-skx-xxv710.rst98
-rw-r--r--docs/cpta/trending/ip6-3n-tsh-x520.rst57
-rw-r--r--docs/cpta/trending/ip6.rst24
-rw-r--r--docs/cpta/trending/ipsec-2n-tx2-xl710.rst292
-rw-r--r--docs/cpta/trending/ipsec-3n-alt-xl710.rst272
-rw-r--r--docs/cpta/trending/ipsec-3n-aws-nitro50g.rst99
-rw-r--r--docs/cpta/trending/ipsec-3n-dnv-x553.rst98
-rw-r--r--docs/cpta/trending/ipsec-3n-icx-xxv710.rst485
-rw-r--r--docs/cpta/trending/ipsec-3n-skx-xxv710.rst194
-rw-r--r--docs/cpta/trending/ipsec-3n-tsh-x520.rst98
-rw-r--r--docs/cpta/trending/ipsec.rst12
-rw-r--r--docs/cpta/trending/l2-2n-clx-cx556a.rst92
-rw-r--r--docs/cpta/trending/l2-2n-clx-e810cq.rst98
-rw-r--r--docs/cpta/trending/l2-2n-clx-x710.rst62
-rw-r--r--docs/cpta/trending/l2-2n-clx-xxv710.rst230
-rw-r--r--docs/cpta/trending/l2-2n-dnv-x553.rst50
-rw-r--r--docs/cpta/trending/l2-2n-icx-xxv710.rst92
-rw-r--r--docs/cpta/trending/l2-2n-skx-x710.rst146
-rw-r--r--docs/cpta/trending/l2-2n-skx-xxv710.rst186
-rw-r--r--docs/cpta/trending/l2-2n-tx2-xl710.rst191
-rw-r--r--docs/cpta/trending/l2-2n-zn2-cx556a.rst92
-rw-r--r--docs/cpta/trending/l2-2n-zn2-x710.rst62
-rw-r--r--docs/cpta/trending/l2-2n-zn2-xxv710.rst230
-rw-r--r--docs/cpta/trending/l2-3n-alt-xl710.rst95
-rw-r--r--docs/cpta/trending/l2-3n-dnv-x553.rst50
-rw-r--r--docs/cpta/trending/l2-3n-icx-xxv710.rst47
-rw-r--r--docs/cpta/trending/l2-3n-skx-x710.rst50
-rw-r--r--docs/cpta/trending/l2-3n-skx-xxv710.rst140
-rw-r--r--docs/cpta/trending/l2-3n-tsh-x520.rst149
-rw-r--r--docs/cpta/trending/l2.rst23
-rw-r--r--docs/cpta/trending/nat44-det-bidir-2n-clx-xxv710.rst47
-rw-r--r--docs/cpta/trending/nat44-det-bidir-2n-icx-xxv710.rst47
-rw-r--r--docs/cpta/trending/nat44-det-bidir-2n-skx-xxv710.rst47
-rw-r--r--docs/cpta/trending/nat44-det-bidir-2n-zn2-xxv710.rst47
-rw-r--r--docs/cpta/trending/nat44-det-bidir.rst9
-rw-r--r--docs/cpta/trending/nat44-ed-tcp-cps-2n-clx-xxv710.rst47
-rw-r--r--docs/cpta/trending/nat44-ed-tcp-cps-2n-icx-xxv710.rst47
-rw-r--r--docs/cpta/trending/nat44-ed-tcp-cps-2n-skx-xxv710.rst47
-rw-r--r--docs/cpta/trending/nat44-ed-tcp-cps.rst8
-rw-r--r--docs/cpta/trending/nat44-ed-tcp-pps-2n-clx-xxv710.rst47
-rw-r--r--docs/cpta/trending/nat44-ed-tcp-pps-2n-skx-xxv710.rst47
-rw-r--r--docs/cpta/trending/nat44-ed-tcp-pps.rst7
-rw-r--r--docs/cpta/trending/nat44-ed-tcp-tput-2n-clx-xxv710.rst92
-rw-r--r--docs/cpta/trending/nat44-ed-tcp-tput-2n-icx-xxv710.rst92
-rw-r--r--docs/cpta/trending/nat44-ed-tcp-tput-2n-skx-xxv710.rst92
-rw-r--r--docs/cpta/trending/nat44-ed-tcp-tput.rst8
-rw-r--r--docs/cpta/trending/nat44-ed-udp-cps-2n-clx-xxv710.rst47
-rw-r--r--docs/cpta/trending/nat44-ed-udp-cps-2n-icx-xxv710.rst47
-rw-r--r--docs/cpta/trending/nat44-ed-udp-cps-2n-skx-xxv710.rst47
-rw-r--r--docs/cpta/trending/nat44-ed-udp-cps.rst8
-rw-r--r--docs/cpta/trending/nat44-ed-udp-pps-2n-clx-xxv710.rst47
-rw-r--r--docs/cpta/trending/nat44-ed-udp-pps-2n-skx-xxv710.rst47
-rw-r--r--docs/cpta/trending/nat44-ed-udp-pps.rst7
-rw-r--r--docs/cpta/trending/nat44-ed-udp-tput-2n-clx-xxv710.rst92
-rw-r--r--docs/cpta/trending/nat44-ed-udp-tput-2n-icx-xxv710.rst92
-rw-r--r--docs/cpta/trending/nat44-ed-udp-tput-2n-skx-xxv710.rst92
-rw-r--r--docs/cpta/trending/nat44-ed-udp-tput.rst8
-rw-r--r--docs/cpta/trending/nat44-ed-unidir-2n-clx-xxv710.rst47
-rw-r--r--docs/cpta/trending/nat44-ed-unidir-2n-icx-xxv710.rst47
-rw-r--r--docs/cpta/trending/nat44-ed-unidir-2n-skx-xxv710.rst47
-rw-r--r--docs/cpta/trending/nat44-ed-unidir.rst10
-rw-r--r--docs/cpta/trending/nat44.rst13
-rw-r--r--docs/cpta/trending/nf_service_density.rst9
-rw-r--r--docs/cpta/trending/nf_service_density_cnfc-2n-clx-xxv710.rst44
-rw-r--r--docs/cpta/trending/nf_service_density_cnfc-2n-icx-xxv710.rst44
-rw-r--r--docs/cpta/trending/nf_service_density_cnfc-2n-skx-xxv710.rst44
-rw-r--r--docs/cpta/trending/nf_service_density_cnfc.rst8
-rw-r--r--docs/cpta/trending/nf_service_density_cnfp-2n-clx-xxv710.rst44
-rw-r--r--docs/cpta/trending/nf_service_density_cnfp-2n-icx-xxv710.rst44
-rw-r--r--docs/cpta/trending/nf_service_density_cnfp-2n-skx-xxv710.rst44
-rw-r--r--docs/cpta/trending/nf_service_density_cnfp.rst8
-rw-r--r--docs/cpta/trending/nf_service_density_vnfc-2n-clx-xxv710.rst44
-rw-r--r--docs/cpta/trending/nf_service_density_vnfc-2n-icx-xxv710.rst44
-rw-r--r--docs/cpta/trending/nf_service_density_vnfc-2n-skx-xxv710.rst44
-rw-r--r--docs/cpta/trending/nf_service_density_vnfc-vxlan-2n-clx-xxv710.rst44
-rw-r--r--docs/cpta/trending/nf_service_density_vnfc-vxlan-2n-icx-xxv710.rst44
-rw-r--r--docs/cpta/trending/nf_service_density_vnfc-vxlan-2n-skx-xxv710.rst44
-rw-r--r--docs/cpta/trending/nf_service_density_vnfc-vxlan.rst8
-rw-r--r--docs/cpta/trending/nf_service_density_vnfc.rst8
-rw-r--r--docs/cpta/trending/srv6-3n-dnv-x553.rst55
-rw-r--r--docs/cpta/trending/srv6-3n-icx-xxv710.rst47
-rw-r--r--docs/cpta/trending/srv6-3n-skx-xxv710.rst47
-rw-r--r--docs/cpta/trending/srv6-3n-tsh-x520.rst55
-rw-r--r--docs/cpta/trending/srv6.rst11
-rw-r--r--docs/cpta/trending/vhost-2n-clx-cx556a.rst92
-rw-r--r--docs/cpta/trending/vhost-2n-clx-e810cq.rst50
-rw-r--r--docs/cpta/trending/vhost-2n-clx-xxv710.rst182
-rw-r--r--docs/cpta/trending/vhost-2n-icx-xxv710.rst47
-rw-r--r--docs/cpta/trending/vhost-2n-skx-xxv710.rst182
-rw-r--r--docs/cpta/trending/vhost-2n-zn2-cx556a.rst92
-rw-r--r--docs/cpta/trending/vhost-2n-zn2-xxv710.rst182
-rw-r--r--docs/cpta/trending/vhost-3n-alt-xl710.rst47
-rw-r--r--docs/cpta/trending/vhost-3n-skx-x710.rst92
-rw-r--r--docs/cpta/trending/vhost-3n-skx-xxv710.rst229
-rw-r--r--docs/cpta/trending/vhost-3n-tsh-x520.rst92
-rw-r--r--docs/cpta/trending/vhost.rst16
l---------docs/job_specs/mlr_weekly/trex-1n-aws.md1
l---------docs/job_specs/mlr_weekly/trex-2n-skx.md1
-rw-r--r--docs/job_specs/report_coverage/1n-aws/trex-00.md44
-rw-r--r--docs/job_specs/report_coverage/2n-skx/trex-00.md46
-rw-r--r--docs/job_specs/report_coverage/3n-snr/crypto-00.md162
-rw-r--r--docs/job_specs/report_coverage/3n-snr/crypto-01.md66
-rw-r--r--docs/job_specs/report_coverage/3n-snr/crypto-02.md194
-rw-r--r--docs/job_specs/report_coverage/3n-snr/ip4-00.md128
-rw-r--r--docs/job_specs/report_coverage/3n-snr/ip4-01.md56
-rw-r--r--docs/job_specs/report_coverage/3n-snr/ip4tun-00.md38
-rw-r--r--docs/job_specs/report_coverage/3n-snr/ip6-00.md56
-rw-r--r--docs/job_specs/report_coverage/3n-snr/ip6-01.md110
-rw-r--r--docs/job_specs/report_coverage/3n-snr/l2-00.md74
-rw-r--r--docs/job_specs/report_coverage/3n-snr/l2-01.md56
-rw-r--r--docs/job_specs/report_iterative/1n-aws/trex-mlr-00.md29
-rw-r--r--docs/job_specs/report_iterative/1n-aws/trex-mrr-00.md29
-rw-r--r--docs/job_specs/report_iterative/2n-skx/trex-mlr-00.md31
-rw-r--r--docs/job_specs/report_iterative/2n-skx/trex-mrr-00.md31
-rw-r--r--docs/job_specs/report_iterative/3n-icx/hoststack-00.md18
-rw-r--r--docs/job_specs/report_iterative/3n-snr/dpdk-mlr-00.md39
-rw-r--r--docs/job_specs/report_iterative/3n-snr/dpdk-mrr-00.md14
-rw-r--r--docs/job_specs/report_iterative/3n-snr/vpp-mlr-00.md154
-rw-r--r--docs/job_specs/report_iterative/3n-snr/vpp-mrr-00.md154
-rw-r--r--docs/job_specs/vpp_device/vpp-1n-tx2.md2
-rw-r--r--docs/lab/testbed_specifications.md323
-rw-r--r--docs/lab/testbeds_sm_skx_hw_bios_cfg.md578
-rw-r--r--docs/report/csit_framework_documentation/index.rst1
-rw-r--r--docs/report/csit_framework_documentation/pal_func_diagram.svg1413
-rw-r--r--docs/report/csit_framework_documentation/pal_layers.svg441
-rw-r--r--docs/report/csit_framework_documentation/pal_lld.rst1
-rw-r--r--docs/report/detailed_test_results/dpdk_performance_results/index.rst2
-rw-r--r--docs/report/detailed_test_results/dpdk_performance_results_2n_skx/index.rst12
-rw-r--r--docs/report/detailed_test_results/dpdk_performance_results_3n_skx/index.rst12
-rw-r--r--docs/report/detailed_test_results/vpp_mrr_results/index.rst2
-rw-r--r--docs/report/detailed_test_results/vpp_mrr_results_2n_skx/index.rst12
-rw-r--r--docs/report/detailed_test_results/vpp_mrr_results_3n_skx/index.rst12
-rw-r--r--docs/report/detailed_test_results/vpp_performance_results/index.rst2
-rw-r--r--docs/report/detailed_test_results/vpp_performance_results_2n_skx/index.rst12
-rw-r--r--docs/report/detailed_test_results/vpp_performance_results_3n_skx/index.rst12
-rw-r--r--docs/report/dpdk_performance_tests/comparisons/2n-icx_vs_2n-skx_testbeds.rst31
-rw-r--r--docs/report/dpdk_performance_tests/comparisons/2n-skx_vs_2n-clx_testbeds.rst31
-rw-r--r--docs/report/dpdk_performance_tests/comparisons/3n-skx_vs_2n-skx_testbeds.rst35
-rw-r--r--docs/report/dpdk_performance_tests/comparisons/3n-skx_vs_3n-icx_testbeds.rst31
-rw-r--r--docs/report/dpdk_performance_tests/comparisons/current_vs_previous_release.rst52
-rw-r--r--docs/report/dpdk_performance_tests/comparisons/index.rst4
-rw-r--r--docs/report/dpdk_performance_tests/hdrh_packet_latency_by_percentile_graphs/2n_skx.rst3
-rw-r--r--docs/report/dpdk_performance_tests/hdrh_packet_latency_by_percentile_graphs/3n_skx.rst3
-rw-r--r--docs/report/dpdk_performance_tests/packet_latency/2n-skx-xxv710.rst78
-rw-r--r--docs/report/dpdk_performance_tests/packet_latency/3n-skx-xxv710.rst78
-rw-r--r--docs/report/dpdk_performance_tests/packet_latency/index.rst8
-rw-r--r--docs/report/dpdk_performance_tests/packet_throughput_graphs/2n-skx-x710.rst125
-rw-r--r--docs/report/dpdk_performance_tests/packet_throughput_graphs/2n-skx-xxv710.rst125
-rw-r--r--docs/report/dpdk_performance_tests/packet_throughput_graphs/3n-skx-x710.rst125
-rw-r--r--docs/report/dpdk_performance_tests/packet_throughput_graphs/3n-skx-xxv710.rst125
-rw-r--r--docs/report/dpdk_performance_tests/packet_throughput_graphs/index.rst8
-rw-r--r--docs/report/dpdk_performance_tests/test_environment.rst32
-rw-r--r--docs/report/dpdk_performance_tests/throughput_speedup_multi_core/2n-skx-x710.rst78
-rw-r--r--docs/report/dpdk_performance_tests/throughput_speedup_multi_core/2n-skx-xxv710.rst78
-rw-r--r--docs/report/dpdk_performance_tests/throughput_speedup_multi_core/3n-skx-x710.rst78
-rw-r--r--docs/report/dpdk_performance_tests/throughput_speedup_multi_core/3n-skx-xxv710.rst78
-rw-r--r--docs/report/dpdk_performance_tests/throughput_speedup_multi_core/index.rst8
-rw-r--r--docs/report/index.html.template30
-rw-r--r--docs/report/index.pdf.template6
-rw-r--r--docs/report/introduction/documentation.rst (renamed from docs/report/introduction/documentation/documentation.rst)0
-rw-r--r--docs/report/introduction/documentation/index.rst12
-rw-r--r--docs/report/introduction/environment/changes_tg.rst (renamed from docs/report/introduction/test_environment_changes_tg.rst)0
-rw-r--r--docs/report/introduction/environment/changes_vpp.rst (renamed from docs/report/introduction/test_environment_changes_vpp.rst)11
-rw-r--r--docs/report/introduction/environment/intro.rst (renamed from docs/report/introduction/test_environment_intro.rst)28
-rw-r--r--docs/report/introduction/environment/pre_test_server_calib.rst (renamed from docs/report/introduction/test_environment_pre_test_server_calib.rst)0
-rw-r--r--docs/report/introduction/environment/sut_calib_alt.rst22
-rw-r--r--docs/report/introduction/environment/sut_calib_clx.rst65
-rw-r--r--docs/report/introduction/environment/sut_calib_dnv.rst67
-rw-r--r--docs/report/introduction/environment/sut_calib_icx.rst65
-rw-r--r--docs/report/introduction/environment/sut_calib_snr.rst65
-rw-r--r--docs/report/introduction/environment/sut_calib_tsh.rst22
-rw-r--r--docs/report/introduction/environment/sut_calib_tx2.rst (renamed from docs/report/introduction/test_environment_sut_calib_tx2.rst)3
-rw-r--r--docs/report/introduction/environment/sut_calib_zn2.rst65
-rw-r--r--docs/report/introduction/environment/sut_conf_1.rst (renamed from docs/report/introduction/test_environment_sut_conf_1.rst)0
-rw-r--r--docs/report/introduction/environment/sut_meltspec_alt.rst (renamed from docs/report/introduction/test_environment_sut_meltspec_alt.rst)6
-rw-r--r--docs/report/introduction/environment/sut_meltspec_clx.rst133
-rw-r--r--docs/report/introduction/environment/sut_meltspec_dnv.rst131
-rw-r--r--docs/report/introduction/environment/sut_meltspec_icx.rst133
-rw-r--r--docs/report/introduction/environment/sut_meltspec_snr.rst131
-rw-r--r--docs/report/introduction/environment/sut_meltspec_tsh.rst96
-rw-r--r--docs/report/introduction/environment/sut_meltspec_tx2.rst (renamed from docs/report/introduction/test_environment_sut_meltspec_tx2.rst)0
-rw-r--r--docs/report/introduction/environment/sut_meltspec_zn2.rst117
-rw-r--r--docs/report/introduction/environment/tg.rst (renamed from docs/report/introduction/test_environment_tg.rst)0
-rw-r--r--docs/report/introduction/index.rst2
-rw-r--r--docs/report/introduction/introduction.rst2
-rw-r--r--docs/report/introduction/methodology.rst2
-rw-r--r--docs/report/introduction/methodology_aws/aws_terraform.rst4
-rw-r--r--docs/report/introduction/methodology_data_plane_throughput/methodology_mlrsearch_tests.rst2
-rw-r--r--docs/report/introduction/methodology_data_plane_throughput/methodology_plrsearch.rst2
-rw-r--r--docs/report/introduction/methodology_ipsec.rst2
-rw-r--r--docs/report/introduction/methodology_multi_core_speedup.rst2
-rw-r--r--docs/report/introduction/methodology_rca/index.rst6
-rw-r--r--docs/report/introduction/methodology_rca/methodology_perpatch_performance_tests.rst242
-rw-r--r--docs/report/introduction/methodology_telemetry.rst399
-rw-r--r--docs/report/introduction/methodology_trending/index.rst (renamed from docs/cpta/methodology/index.rst)0
-rw-r--r--docs/report/introduction/methodology_trending/overview.rst (renamed from docs/cpta/methodology/overview.rst)0
-rw-r--r--docs/report/introduction/methodology_trending/trend_analysis.rst (renamed from docs/cpta/methodology/trend_analysis.rst)0
-rw-r--r--docs/report/introduction/methodology_trending/trend_presentation.rst (renamed from docs/cpta/methodology/trend_presentation.rst)0
-rw-r--r--docs/report/introduction/physical_testbeds.rst153
-rw-r--r--docs/report/introduction/report_history.rst25
-rw-r--r--docs/report/introduction/test_environment_sut_calib_alt.rst25
-rw-r--r--docs/report/introduction/test_environment_sut_calib_clx.rst224
-rw-r--r--docs/report/introduction/test_environment_sut_calib_dnv.rst203
-rw-r--r--docs/report/introduction/test_environment_sut_calib_icx.rst73
-rw-r--r--docs/report/introduction/test_environment_sut_calib_skx.rst214
-rw-r--r--docs/report/introduction/test_environment_sut_calib_tsh.rst82
-rw-r--r--docs/report/introduction/test_environment_sut_calib_zn2.rst118
-rw-r--r--docs/report/introduction/test_environment_sut_meltspec_clx.rst251
-rw-r--r--docs/report/introduction/test_environment_sut_meltspec_dnv.rst347
-rw-r--r--docs/report/introduction/test_environment_sut_meltspec_icx.rst131
-rw-r--r--docs/report/introduction/test_environment_sut_meltspec_skx.rst178
-rw-r--r--docs/report/introduction/test_environment_sut_meltspec_tsh.rst452
-rw-r--r--docs/report/introduction/test_environment_sut_meltspec_zn2.rst327
-rw-r--r--docs/report/introduction/test_scenarios_overview.rst7
-rw-r--r--docs/report/introduction/testbed-2n-skx.svg1858
-rw-r--r--docs/report/introduction/testbed-3n-skx.svg2771
-rw-r--r--docs/report/introduction/testbed-3n-snr.svg1220
-rw-r--r--docs/report/stats/durations.rst68
-rw-r--r--docs/report/test_configuration/vpp_mrr_configuration/index.rst2
-rw-r--r--docs/report/test_configuration/vpp_mrr_configuration_2n_skx/index.rst12
-rw-r--r--docs/report/test_configuration/vpp_mrr_configuration_3n_skx/index.rst12
-rw-r--r--docs/report/test_configuration/vpp_performance_configuration/index.rst2
-rw-r--r--docs/report/test_configuration/vpp_performance_configuration_2n_skx/index.rst12
-rw-r--r--docs/report/test_configuration/vpp_performance_configuration_3n_skx/index.rst12
-rw-r--r--docs/report/test_operational_data/vpp_performance_operational_data/index.rst6
-rw-r--r--docs/report/test_operational_data/vpp_performance_operational_data_2n_skx/index.rst12
-rw-r--r--docs/report/test_operational_data/vpp_performance_operational_data_3n_skx/index.rst12
-rw-r--r--docs/report/trex_performance_tests/overview.rst2
-rw-r--r--docs/report/trex_performance_tests/test_environment.rst6
-rw-r--r--docs/report/vpp_device_tests/overview.rst2
-rw-r--r--docs/report/vpp_device_tests/test_environment.rst3
-rw-r--r--docs/report/vpp_performance_tests/comparisons/2n-icx_vs_2n-skx_testbeds.rst55
-rw-r--r--docs/report/vpp_performance_tests/comparisons/2n-skx_vs_2n-clx_testbeds.rst54
-rw-r--r--docs/report/vpp_performance_tests/comparisons/3n-skx_vs_2n-skx_testbeds.rst58
-rw-r--r--docs/report/vpp_performance_tests/comparisons/3n-skx_vs_3n-icx_testbeds.rst58
-rw-r--r--docs/report/vpp_performance_tests/comparisons/current_vs_previous_release.rst119
-rw-r--r--docs/report/vpp_performance_tests/comparisons/index.rst4
-rw-r--r--docs/report/vpp_performance_tests/comparisons/nic_comparison.rst172
-rw-r--r--docs/report/vpp_performance_tests/comparisons/soak_vs_ndr.rst7
-rw-r--r--docs/report/vpp_performance_tests/gso_testing/2n-clx.rst3
-rw-r--r--docs/report/vpp_performance_tests/gso_testing/2n-icx.rst3
-rw-r--r--docs/report/vpp_performance_tests/gso_testing/2n-skx.rst96
-rw-r--r--docs/report/vpp_performance_tests/gso_testing/2n-zn2.rst3
-rw-r--r--docs/report/vpp_performance_tests/gso_testing/index.rst1
-rw-r--r--docs/report/vpp_performance_tests/hdrh_packet_latency_by_percentile_graphs/2n_skx.rst3
-rw-r--r--docs/report/vpp_performance_tests/hdrh_packet_latency_by_percentile_graphs/3n_skx.rst3
-rw-r--r--docs/report/vpp_performance_tests/hoststack_testing/iperf3/tcp/index.rst3
-rw-r--r--docs/report/vpp_performance_tests/hoststack_testing/iperf3/udp/index.rst3
-rw-r--r--docs/report/vpp_performance_tests/hoststack_testing/quic/index.rst3
-rw-r--r--docs/report/vpp_performance_tests/nf_service_density/cnf_service_chains.rst208
-rw-r--r--docs/report/vpp_performance_tests/nf_service_density/cnf_service_chains_ipsec.rst611
-rw-r--r--docs/report/vpp_performance_tests/nf_service_density/cnf_service_pipelines.rst208
-rw-r--r--docs/report/vpp_performance_tests/nf_service_density/index.rst3
-rw-r--r--docs/report/vpp_performance_tests/nf_service_density/vnf_service_chains.rst208
-rw-r--r--docs/report/vpp_performance_tests/nf_service_density/vnf_service_chains_vxlan.rst212
-rw-r--r--docs/report/vpp_performance_tests/overview.rst6
-rw-r--r--docs/report/vpp_performance_tests/packet_latency/container_memif-2n-skx-xxv710.rst154
-rw-r--r--docs/report/vpp_performance_tests/packet_latency/container_memif.rst1
-rw-r--r--docs/report/vpp_performance_tests/packet_latency/index.rst4
-rw-r--r--docs/report/vpp_performance_tests/packet_latency/ip4-2n-skx-xxv710.rst483
-rw-r--r--docs/report/vpp_performance_tests/packet_latency/ip4-3n-skx-xxv710.rst74
-rw-r--r--docs/report/vpp_performance_tests/packet_latency/ip4.rst2
-rw-r--r--docs/report/vpp_performance_tests/packet_latency/ip4_tunnels-3n-skx-xxv710.rst154
-rw-r--r--docs/report/vpp_performance_tests/packet_latency/ip4_tunnels.rst1
-rw-r--r--docs/report/vpp_performance_tests/packet_latency/ip6-2n-skx-xxv710.rst318
-rw-r--r--docs/report/vpp_performance_tests/packet_latency/ip6-3n-skx-xxv710.rst74
-rw-r--r--docs/report/vpp_performance_tests/packet_latency/ip6.rst2
-rw-r--r--docs/report/vpp_performance_tests/packet_latency/ipsec-3n-skx-xxv710.rst235
-rw-r--r--docs/report/vpp_performance_tests/packet_latency/ipsec.rst1
-rw-r--r--docs/report/vpp_performance_tests/packet_latency/l2-2n-skx-xxv710.rst274
-rw-r--r--docs/report/vpp_performance_tests/packet_latency/l2-3n-skx-xxv710.rst174
-rw-r--r--docs/report/vpp_performance_tests/packet_latency/l2.rst2
-rw-r--r--docs/report/vpp_performance_tests/packet_latency/nat44-2n-skx-xxv710.rst442
-rw-r--r--docs/report/vpp_performance_tests/packet_latency/nat44.rst1
-rw-r--r--docs/report/vpp_performance_tests/packet_latency/srv6-3n-skx-xxv710.rst152
-rw-r--r--docs/report/vpp_performance_tests/packet_latency/srv6.rst1
-rw-r--r--docs/report/vpp_performance_tests/packet_latency/vm_vhost-2n-skx-xxv710.rst200
-rw-r--r--docs/report/vpp_performance_tests/packet_latency/vm_vhost.rst1
-rw-r--r--docs/report/vpp_performance_tests/packet_throughput_graphs/container_memif-2n-skx-xxv710.rst114
-rw-r--r--docs/report/vpp_performance_tests/packet_throughput_graphs/container_memif.rst1
-rw-r--r--docs/report/vpp_performance_tests/packet_throughput_graphs/index.rst4
-rw-r--r--docs/report/vpp_performance_tests/packet_throughput_graphs/ip4-2n-skx-x710.rst71
-rw-r--r--docs/report/vpp_performance_tests/packet_throughput_graphs/ip4-2n-skx-xxv710.rst200
-rw-r--r--docs/report/vpp_performance_tests/packet_throughput_graphs/ip4-3n-skx-x710.rst71
-rw-r--r--docs/report/vpp_performance_tests/packet_throughput_graphs/ip4-3n-skx-xxv710.rst71
-rw-r--r--docs/report/vpp_performance_tests/packet_throughput_graphs/ip4.rst4
-rw-r--r--docs/report/vpp_performance_tests/packet_throughput_graphs/ip4_tunnels-2n-skx-xxv710.rst71
-rw-r--r--docs/report/vpp_performance_tests/packet_throughput_graphs/ip4_tunnels-3n-skx-xxv710.rst71
-rw-r--r--docs/report/vpp_performance_tests/packet_throughput_graphs/ip4_tunnels.rst2
-rw-r--r--docs/report/vpp_performance_tests/packet_throughput_graphs/ip6-2n-skx-x710.rst71
-rw-r--r--docs/report/vpp_performance_tests/packet_throughput_graphs/ip6-2n-skx-xxv710.rst157
-rw-r--r--docs/report/vpp_performance_tests/packet_throughput_graphs/ip6-3n-skx-x710.rst71
-rw-r--r--docs/report/vpp_performance_tests/packet_throughput_graphs/ip6-3n-skx-xxv710.rst71
-rw-r--r--docs/report/vpp_performance_tests/packet_throughput_graphs/ip6.rst4
-rw-r--r--docs/report/vpp_performance_tests/packet_throughput_graphs/ipsec-3n-skx-xxv710.rst200
-rw-r--r--docs/report/vpp_performance_tests/packet_throughput_graphs/ipsec.rst1
-rw-r--r--docs/report/vpp_performance_tests/packet_throughput_graphs/l2-2n-skx-x710.rst71
-rw-r--r--docs/report/vpp_performance_tests/packet_throughput_graphs/l2-2n-skx-xxv710.rst200
-rw-r--r--docs/report/vpp_performance_tests/packet_throughput_graphs/l2-3n-skx-x710.rst71
-rw-r--r--docs/report/vpp_performance_tests/packet_throughput_graphs/l2-3n-skx-xxv710.rst71
-rw-r--r--docs/report/vpp_performance_tests/packet_throughput_graphs/l2.rst4
-rw-r--r--docs/report/vpp_performance_tests/packet_throughput_graphs/nat44-det-bidir-2n-skx.rst71
-rw-r--r--docs/report/vpp_performance_tests/packet_throughput_graphs/nat44-det-bidir.rst1
-rw-r--r--docs/report/vpp_performance_tests/packet_throughput_graphs/nat44-ed-tcp-cps-2n-skx.rst71
-rw-r--r--docs/report/vpp_performance_tests/packet_throughput_graphs/nat44-ed-tcp-cps.rst1
-rw-r--r--docs/report/vpp_performance_tests/packet_throughput_graphs/nat44-ed-tcp-tput-2n-skx.rst71
-rw-r--r--docs/report/vpp_performance_tests/packet_throughput_graphs/nat44-ed-tcp-tput.rst1
-rw-r--r--docs/report/vpp_performance_tests/packet_throughput_graphs/nat44-ed-udp-cps-2n-skx.rst71
-rw-r--r--docs/report/vpp_performance_tests/packet_throughput_graphs/nat44-ed-udp-cps.rst1
-rw-r--r--docs/report/vpp_performance_tests/packet_throughput_graphs/nat44-ed-udp-tput-2n-skx.rst71
-rw-r--r--docs/report/vpp_performance_tests/packet_throughput_graphs/nat44-ed-udp-tput.rst1
-rw-r--r--docs/report/vpp_performance_tests/packet_throughput_graphs/nat44-ed-unidir-2n-skx.rst71
-rw-r--r--docs/report/vpp_performance_tests/packet_throughput_graphs/nat44-ed-unidir.rst1
-rw-r--r--docs/report/vpp_performance_tests/packet_throughput_graphs/srv6-3n-skx-xxv710.rst111
-rw-r--r--docs/report/vpp_performance_tests/packet_throughput_graphs/srv6.rst1
-rw-r--r--docs/report/vpp_performance_tests/packet_throughput_graphs/vm_vhost-2n-skx-xxv710.rst115
-rw-r--r--docs/report/vpp_performance_tests/packet_throughput_graphs/vm_vhost.rst1
-rw-r--r--docs/report/vpp_performance_tests/reconf_tests/index.rst3
-rw-r--r--docs/report/vpp_performance_tests/reconf_tests/ipsec_reconf.rst272
-rw-r--r--docs/report/vpp_performance_tests/reconf_tests/vnf_service_chains_reconf.rst70
-rw-r--r--docs/report/vpp_performance_tests/soak_tests/index.rst44
-rw-r--r--docs/report/vpp_performance_tests/test_environment.rst34
-rw-r--r--docs/report/vpp_performance_tests/throughput_speedup_multi_core/container_memif-2n-skx-xxv710.rst114
-rw-r--r--docs/report/vpp_performance_tests/throughput_speedup_multi_core/container_memif.rst1
-rw-r--r--docs/report/vpp_performance_tests/throughput_speedup_multi_core/index.rst4
-rw-r--r--docs/report/vpp_performance_tests/throughput_speedup_multi_core/ip4-2n-skx-x710.rst71
-rw-r--r--docs/report/vpp_performance_tests/throughput_speedup_multi_core/ip4-2n-skx-xxv710.rst200
-rw-r--r--docs/report/vpp_performance_tests/throughput_speedup_multi_core/ip4-3n-skx-x710.rst71
-rw-r--r--docs/report/vpp_performance_tests/throughput_speedup_multi_core/ip4-3n-skx-xxv710.rst71
-rw-r--r--docs/report/vpp_performance_tests/throughput_speedup_multi_core/ip4.rst4
-rw-r--r--docs/report/vpp_performance_tests/throughput_speedup_multi_core/ip4_tunnels-2n-skx-xxv710.rst71
-rw-r--r--docs/report/vpp_performance_tests/throughput_speedup_multi_core/ip4_tunnels-3n-skx-xxv710.rst71
-rw-r--r--docs/report/vpp_performance_tests/throughput_speedup_multi_core/ip4_tunnels.rst2
-rw-r--r--docs/report/vpp_performance_tests/throughput_speedup_multi_core/ip6-2n-skx-x710.rst71
-rw-r--r--docs/report/vpp_performance_tests/throughput_speedup_multi_core/ip6-2n-skx-xxv710.rst157
-rw-r--r--docs/report/vpp_performance_tests/throughput_speedup_multi_core/ip6-3n-skx-x710.rst71
-rw-r--r--docs/report/vpp_performance_tests/throughput_speedup_multi_core/ip6-3n-skx-xxv710.rst71
-rw-r--r--docs/report/vpp_performance_tests/throughput_speedup_multi_core/ip6.rst4
-rw-r--r--docs/report/vpp_performance_tests/throughput_speedup_multi_core/ipsec-3n-skx-xxv710.rst157
-rw-r--r--docs/report/vpp_performance_tests/throughput_speedup_multi_core/ipsec.rst1
-rw-r--r--docs/report/vpp_performance_tests/throughput_speedup_multi_core/l2-2n-skx-x710.rst71
-rw-r--r--docs/report/vpp_performance_tests/throughput_speedup_multi_core/l2-2n-skx-xxv710.rst200
-rw-r--r--docs/report/vpp_performance_tests/throughput_speedup_multi_core/l2-3n-skx-x710.rst71
-rw-r--r--docs/report/vpp_performance_tests/throughput_speedup_multi_core/l2-3n-skx-xxv710.rst71
-rw-r--r--docs/report/vpp_performance_tests/throughput_speedup_multi_core/l2.rst4
-rw-r--r--docs/report/vpp_performance_tests/throughput_speedup_multi_core/nat44-det-bidir-2n-skx.rst71
-rw-r--r--docs/report/vpp_performance_tests/throughput_speedup_multi_core/nat44-det-bidir.rst1
-rw-r--r--docs/report/vpp_performance_tests/throughput_speedup_multi_core/nat44-ed-tcp-cps-2n-skx.rst71
-rw-r--r--docs/report/vpp_performance_tests/throughput_speedup_multi_core/nat44-ed-tcp-cps.rst1
-rw-r--r--docs/report/vpp_performance_tests/throughput_speedup_multi_core/nat44-ed-tcp-tput-2n-skx.rst71
-rw-r--r--docs/report/vpp_performance_tests/throughput_speedup_multi_core/nat44-ed-tcp-tput.rst1
-rw-r--r--docs/report/vpp_performance_tests/throughput_speedup_multi_core/nat44-ed-udp-cps-2n-skx.rst71
-rw-r--r--docs/report/vpp_performance_tests/throughput_speedup_multi_core/nat44-ed-udp-cps.rst1
-rw-r--r--docs/report/vpp_performance_tests/throughput_speedup_multi_core/nat44-ed-udp-tput-2n-skx.rst71
-rw-r--r--docs/report/vpp_performance_tests/throughput_speedup_multi_core/nat44-ed-udp-tput.rst1
-rw-r--r--docs/report/vpp_performance_tests/throughput_speedup_multi_core/nat44-ed-unidir-2n-skx.rst71
-rw-r--r--docs/report/vpp_performance_tests/throughput_speedup_multi_core/nat44-ed-unidir.rst1
-rw-r--r--docs/report/vpp_performance_tests/throughput_speedup_multi_core/srv6-3n-skx-xxv710.rst71
-rw-r--r--docs/report/vpp_performance_tests/throughput_speedup_multi_core/srv6.rst1
-rw-r--r--docs/report/vpp_performance_tests/throughput_speedup_multi_core/vm_vhost-2n-skx-xxv710.rst114
-rw-r--r--docs/report/vpp_performance_tests/throughput_speedup_multi_core/vm_vhost.rst1
-rw-r--r--fdio.infra.ansible/inventories/lf_inventory/host_vars/10.30.51.16.yaml2
-rw-r--r--fdio.infra.ansible/inventories/lf_inventory/host_vars/10.30.51.17.yaml2
-rw-r--r--fdio.infra.ansible/inventories/lf_inventory/host_vars/10.30.51.18.yaml2
-rw-r--r--fdio.infra.ansible/inventories/lf_inventory/host_vars/10.30.51.19.yaml2
-rw-r--r--fdio.infra.ansible/inventories/lf_inventory/host_vars/10.30.51.22.yaml2
-rw-r--r--fdio.infra.ansible/inventories/lf_inventory/host_vars/10.30.51.23.yaml2
-rw-r--r--fdio.infra.ansible/inventories/lf_inventory/host_vars/10.30.51.24.yaml2
-rw-r--r--fdio.infra.ansible/inventories/lf_inventory/host_vars/10.30.51.25.yaml2
-rw-r--r--fdio.infra.ansible/inventories/lf_inventory/host_vars/10.30.51.26.yaml2
-rw-r--r--fdio.infra.ansible/inventories/lf_inventory/host_vars/10.30.51.36.yaml2
-rw-r--r--fdio.infra.ansible/inventories/lf_inventory/host_vars/10.30.51.37.yaml2
-rw-r--r--fdio.infra.ansible/inventories/lf_inventory/host_vars/10.30.51.49.yaml2
-rw-r--r--fdio.infra.ansible/inventories/lf_inventory/host_vars/10.30.51.69.yaml2
-rw-r--r--fdio.infra.ansible/inventories/lf_inventory/host_vars/10.30.51.70.yaml20
-rw-r--r--fdio.infra.ansible/inventories/lf_inventory/host_vars/10.30.51.71.yaml20
-rw-r--r--fdio.infra.ansible/inventories/lf_inventory/host_vars/10.30.51.72.yaml2
-rw-r--r--fdio.infra.ansible/inventories/lf_inventory/host_vars/10.30.51.73.yaml2
-rw-r--r--fdio.infra.ansible/inventories/lf_inventory/host_vars/10.30.51.74.yaml4
-rw-r--r--fdio.infra.ansible/inventories/lf_inventory/host_vars/10.30.51.75.yaml4
-rw-r--r--fdio.infra.ansible/inventories/lf_inventory/host_vars/10.30.51.76.yaml4
-rw-r--r--fdio.infra.ansible/inventories/lf_inventory/host_vars/10.30.51.77.yaml4
-rw-r--r--fdio.infra.ansible/inventories/lf_inventory/host_vars/10.30.51.78.yaml4
-rw-r--r--fdio.infra.ansible/inventories/lf_inventory/host_vars/10.30.51.79.yaml4
-rw-r--r--fdio.infra.ansible/inventories/lf_inventory/host_vars/10.30.51.80.yaml4
-rw-r--r--fdio.infra.ansible/inventories/lf_inventory/host_vars/10.30.51.81.yaml4
-rw-r--r--fdio.infra.ansible/inventories/lf_inventory/host_vars/10.30.51.82.yaml4
-rw-r--r--fdio.infra.ansible/inventories/lf_inventory/host_vars/10.30.51.83.yaml4
-rw-r--r--fdio.infra.ansible/inventories/lf_inventory/host_vars/10.30.51.84.yaml4
-rw-r--r--fdio.infra.ansible/inventories/lf_inventory/host_vars/10.30.51.85.yaml4
-rw-r--r--fdio.infra.ansible/inventories/lf_inventory/host_vars/10.30.51.86.yaml4
-rw-r--r--fdio.infra.ansible/inventories/lf_inventory/host_vars/10.30.51.87.yaml4
-rw-r--r--fdio.infra.ansible/inventories/lf_inventory/host_vars/10.30.51.88.yaml4
-rw-r--r--fdio.infra.ansible/inventories/lf_inventory/host_vars/10.30.51.89.yaml4
-rw-r--r--fdio.infra.ansible/inventories/lf_inventory/host_vars/10.30.51.93.yaml3
-rw-r--r--fdio.infra.ansible/inventories/lf_inventory/host_vars/10.30.51.94.yaml3
-rw-r--r--fdio.infra.ansible/inventories/lf_inventory/host_vars/10.32.8.18.yaml6
-rw-r--r--fdio.infra.ansible/inventories/lf_inventory/host_vars/10.32.8.19.yaml6
-rw-r--r--fdio.infra.ansible/inventories/lf_inventory/host_vars/10.32.8.20.yaml6
-rw-r--r--fdio.infra.ansible/inventories/lf_inventory/host_vars/10.32.8.21.yaml6
-rw-r--r--fdio.infra.ansible/inventories/lf_inventory/host_vars/10.32.8.22.yaml6
-rw-r--r--fdio.infra.ansible/inventories/lf_inventory/host_vars/10.32.8.23.yaml6
-rw-r--r--fdio.infra.ansible/inventories/lf_inventory/host_vars/10.32.8.24.yaml6
-rw-r--r--fdio.infra.ansible/inventories/lf_inventory/host_vars/10.32.8.25.yaml6
-rw-r--r--fdio.infra.ansible/inventories/lf_inventory/hosts39
-rw-r--r--fdio.infra.ansible/roles/ab/tasks/main.yaml4
-rw-r--r--fdio.infra.ansible/roles/aws/tasks/main.yaml49
-rw-r--r--fdio.infra.ansible/roles/aws/tasks/ubuntu_focal.yaml10
-rw-r--r--fdio.infra.ansible/roles/aws/tasks/ubuntu_jammy.yaml4
-rw-r--r--fdio.infra.ansible/roles/calibration/defaults/main.yaml4
-rw-r--r--fdio.infra.ansible/roles/calibration/tasks/main.yaml18
-rw-r--r--fdio.infra.ansible/roles/calibration/tasks/x86_64.yaml10
-rw-r--r--fdio.infra.ansible/roles/cleanup/tasks/clean_images.yaml4
-rw-r--r--fdio.infra.ansible/roles/cleanup/tasks/kill_containers.yaml10
-rw-r--r--fdio.infra.ansible/roles/cleanup/tasks/kill_process.yaml6
-rw-r--r--fdio.infra.ansible/roles/cleanup/tasks/remove_package.yaml4
-rw-r--r--fdio.infra.ansible/roles/cleanup/tasks/sut.yaml8
-rw-r--r--fdio.infra.ansible/roles/cleanup/tasks/vpp_device.yaml2
-rw-r--r--fdio.infra.ansible/roles/common/defaults/main.yaml25
-rw-r--r--fdio.infra.ansible/roles/common/handlers/main.yaml2
-rw-r--r--fdio.infra.ansible/roles/common/tasks/main.yaml14
-rw-r--r--fdio.infra.ansible/roles/csit_sut_image/files/Dockerfile111
-rw-r--r--fdio.infra.ansible/roles/csit_sut_image/tasks/main.yaml19
-rw-r--r--fdio.infra.ansible/roles/docker/tasks/focal.yaml30
-rw-r--r--fdio.infra.ansible/roles/dpdk/defaults/main.yaml2
-rw-r--r--fdio.infra.ansible/roles/dpdk/meta/main.yaml6
-rw-r--r--fdio.infra.ansible/roles/dpdk/tasks/deploy_block.yaml43
-rw-r--r--fdio.infra.ansible/roles/dpdk/tasks/main.yaml50
-rw-r--r--fdio.infra.ansible/roles/intel/defaults/main.yaml26
-rw-r--r--fdio.infra.ansible/roles/intel/tasks/i40e.yaml8
-rw-r--r--fdio.infra.ansible/roles/intel/tasks/iavf.yaml6
-rw-r--r--fdio.infra.ansible/roles/intel/tasks/ice.yaml36
-rw-r--r--fdio.infra.ansible/roles/intel/tasks/main.yaml12
-rw-r--r--fdio.infra.ansible/roles/iperf/tasks/main.yaml14
-rw-r--r--fdio.infra.ansible/roles/kernel/defaults/main.yaml14
-rw-r--r--fdio.infra.ansible/roles/kernel/handlers/main.yaml2
-rw-r--r--fdio.infra.ansible/roles/kernel/tasks/ubuntu_focal.yaml62
-rw-r--r--fdio.infra.ansible/roles/kernel/tasks/ubuntu_jammy.yaml18
-rw-r--r--fdio.infra.ansible/roles/kernel_vm/tasks/main.yaml22
-rw-r--r--fdio.infra.ansible/roles/kubernetes/defaults/main.yaml15
-rw-r--r--fdio.infra.ansible/roles/kubernetes/tasks/main.yaml14
-rw-r--r--fdio.infra.ansible/roles/kubernetes/tasks/ubuntu_jammy.yaml37
-rw-r--r--fdio.infra.ansible/roles/mellanox/defaults/main.yaml6
-rw-r--r--fdio.infra.ansible/roles/mellanox/tasks/main.yaml2
-rw-r--r--fdio.infra.ansible/roles/mellanox/tasks/ofed.yaml12
-rw-r--r--fdio.infra.ansible/roles/performance_tuning/handlers/main.yaml4
-rw-r--r--fdio.infra.ansible/roles/performance_tuning/tasks/main.yaml39
-rw-r--r--fdio.infra.ansible/roles/python_env/defaults/main.yaml11
-rw-r--r--fdio.infra.ansible/roles/python_env/tasks/main.yaml96
-rwxr-xr-xfdio.infra.ansible/roles/tg/files/csit-initialize-docker-tg.sh2
-rw-r--r--fdio.infra.ansible/roles/tg/handlers/main.yaml2
-rw-r--r--fdio.infra.ansible/roles/tg/tasks/main.yaml4
-rw-r--r--fdio.infra.ansible/roles/topology/tasks/main.yaml6
-rw-r--r--fdio.infra.ansible/roles/trex/defaults/main.yaml15
-rw-r--r--fdio.infra.ansible/roles/trex/tasks/deploy_block.yaml56
-rw-r--r--fdio.infra.ansible/roles/trex/tasks/main.yaml10
-rw-r--r--fdio.infra.ansible/roles/vpp/defaults/main.yaml14
-rw-r--r--fdio.infra.ansible/roles/vpp/tasks/main.yaml6
-rw-r--r--fdio.infra.ansible/roles/vpp_device/tasks/main.yaml11
-rw-r--r--fdio.infra.ansible/roles/vpp_device/tasks/thunderx2.yaml23
-rw-r--r--fdio.infra.packer/aws_c5n/ubuntu_jammy.pkr.hcl128
-rw-r--r--fdio.infra.pxe/docker-dnsmasq/Dockerfile33
-rw-r--r--fdio.infra.pxe/docker-dnsmasq/tftpboot/grub/grub.cfg-00:42:68:6f:68:ee2
-rw-r--r--fdio.infra.pxe/docker-dnsmasq/tftpboot/grub/grub.cfg-00:42:68:6f:6f:c02
-rw-r--r--fdio.infra.pxe/docker-dnsmasq/tftpboot/grub/grub.cfg-00:f2:8b:7c:fb:122
-rw-r--r--fdio.infra.pxe/docker-dnsmasq/tftpboot/grub/grub.cfg-00:f2:8b:7c:fb:4a2
-rw-r--r--fdio.infra.pxe/docker-dnsmasq/tftpboot/grub/grub.cfg-00:fe:c8:58:1e:f62
-rw-r--r--fdio.infra.pxe/docker-dnsmasq/tftpboot/grub/grub.cfg-00:fe:c8:e5:68:324
-rw-r--r--fdio.infra.pxe/docker-dnsmasq/tftpboot/grub/grub.cfg-00:fe:c8:e5:68:c22
-rw-r--r--fdio.infra.pxe/docker-dnsmasq/tftpboot/grub/grub.cfg-00:fe:c8:e5:68:e04
-rw-r--r--fdio.infra.pxe/docker-dnsmasq/tftpboot/grub/grub.cfg-00:fe:c8:e5:6a:724
-rw-r--r--fdio.infra.pxe/docker-dnsmasq/tftpboot/grub/grub.cfg-00:fe:c8:e5:6c:764
-rw-r--r--fdio.infra.pxe/docker-dnsmasq/tftpboot/grub/grub.cfg-0c:c4:7a:fc:c9:584
-rw-r--r--fdio.infra.pxe/docker-dnsmasq/tftpboot/grub/grub.cfg-0c:c4:7a:fc:ca:904
-rw-r--r--fdio.infra.pxe/docker-dnsmasq/tftpboot/grub/grub.cfg-0c:c4:7a:fc:ca:cc4
-rw-r--r--fdio.infra.pxe/docker-dnsmasq/tftpboot/grub/grub.cfg-38:0e:4d:9c:4b:0c4
-rw-r--r--fdio.infra.pxe/docker-dnsmasq/tftpboot/grub/grub.cfg-38:0e:4d:9c:85:7a4
-rw-r--r--fdio.infra.pxe/docker-dnsmasq/tftpboot/grub/grub.cfg-3c:ec:ef:43:a3:ba4
-rw-r--r--fdio.infra.pxe/docker-dnsmasq/tftpboot/grub/grub.cfg-3c:ec:ef:46:34:e84
-rw-r--r--fdio.infra.pxe/docker-dnsmasq/tftpboot/grub/grub.cfg-3c:ec:ef:b9:7f:124
-rw-r--r--fdio.infra.pxe/docker-dnsmasq/tftpboot/grub/grub.cfg-3c:ec:ef:b9:a6:804
-rw-r--r--fdio.infra.pxe/docker-dnsmasq/tftpboot/grub/grub.cfg-3c:ec:ef:b9:a6:924
-rw-r--r--fdio.infra.pxe/docker-dnsmasq/tftpboot/grub/grub.cfg-3c:ec:ef:b9:a6:ba4
-rw-r--r--fdio.infra.pxe/docker-dnsmasq/tftpboot/grub/grub.cfg-3c:ec:ef:b9:a6:c64
-rw-r--r--fdio.infra.pxe/docker-dnsmasq/tftpboot/grub/grub.cfg-3c:ec:ef:b9:a6:ca4
-rw-r--r--fdio.infra.pxe/docker-dnsmasq/tftpboot/grub/grub.cfg-3c:ec:ef:b9:cc:444
-rw-r--r--fdio.infra.pxe/docker-dnsmasq/tftpboot/grub/grub.cfg-3c:ec:ef:b9:cc:564
-rw-r--r--fdio.infra.pxe/docker-dnsmasq/tftpboot/grub/grub.cfg-3c:ec:ef:bc:92:264
-rw-r--r--fdio.infra.pxe/docker-dnsmasq/tftpboot/grub/grub.cfg-3c:ec:ef:bc:92:b24
-rw-r--r--fdio.infra.pxe/docker-dnsmasq/tftpboot/grub/grub.cfg-3c:ec:ef:bc:92:e44
-rw-r--r--fdio.infra.pxe/docker-dnsmasq/tftpboot/grub/grub.cfg-3c:ec:ef:bc:92:e84
-rw-r--r--fdio.infra.pxe/docker-dnsmasq/tftpboot/grub/grub.cfg-3c:ec:ef:bc:a0:d44
-rw-r--r--fdio.infra.pxe/docker-dnsmasq/tftpboot/grub/grub.cfg-3c:ec:ef:bc:a0:ec4
-rw-r--r--fdio.infra.pxe/docker-dnsmasq/tftpboot/grub/grub.cfg-3c:ec:ef:bc:a1:ac4
-rw-r--r--fdio.infra.pxe/docker-dnsmasq/tftpboot/grub/grub.cfg-3c:ec:ef:bc:a1:ea4
-rw-r--r--fdio.infra.pxe/docker-dnsmasq/tftpboot/grub/grub.cfg-40:8d:5c:e7:b2:6e4
-rw-r--r--fdio.infra.pxe/docker-dnsmasq/tftpboot/grub/grub.cfg-4c:00:82:ae:5a:f84
-rw-r--r--fdio.infra.pxe/docker-dnsmasq/tftpboot/grub/grub.cfg-58:ac:78:5c:90:782
-rw-r--r--fdio.infra.pxe/docker-dnsmasq/tftpboot/grub/grub.cfg-6c:41:6a:1f:39:264
-rw-r--r--fdio.infra.pxe/docker-dnsmasq/tftpboot/grub/grub.cfg-90:e2:ba:49:db:b44
-rw-r--r--fdio.infra.pxe/docker-dnsmasq/tftpboot/grub/grub.cfg-90:e2:ba:55:be:324
-rw-r--r--fdio.infra.pxe/docker-dnsmasq/tftpboot/grub/grub.cfg-a0:a3:3b:c1:12:fa4
-rw-r--r--fdio.infra.pxe/docker-dnsmasq/tftpboot/grub/grub.cfg-a0:a3:3b:c1:14:284
-rw-r--r--fdio.infra.pxe/docker-dnsmasq/tftpboot/grub/grub.cfg-a4:bf:01:55:ac:394
-rw-r--r--fdio.infra.pxe/docker-dnsmasq/tftpboot/grub/grub.cfg-a4:bf:01:55:af:5e4
-rw-r--r--fdio.infra.pxe/docker-dnsmasq/tftpboot/grub/grub.cfg-ac:1f:6b:5a:6a:b42
-rw-r--r--fdio.infra.pxe/docker-dnsmasq/tftpboot/grub/grub.cfg-ac:1f:6b:5a:6a:d42
-rw-r--r--fdio.infra.pxe/docker-dnsmasq/tftpboot/grub/grub.cfg-ac:1f:6b:5a:6b:082
-rw-r--r--fdio.infra.pxe/docker-dnsmasq/tftpboot/grub/grub.cfg-ac:1f:6b:8a:8c:764
-rw-r--r--fdio.infra.pxe/docker-dnsmasq/tftpboot/grub/grub.cfg-ac:1f:6b:8a:8d:0a4
-rw-r--r--fdio.infra.pxe/docker-dnsmasq/tftpboot/grub/grub.cfg-ac:1f:6b:8a:8d:944
-rw-r--r--fdio.infra.pxe/docker-dnsmasq/tftpboot/grub/grub.cfg-ac:1f:6b:8a:8d:b64
-rw-r--r--fdio.infra.pxe/docker-dnsmasq/tftpboot/grub/grub.cfg-ac:1f:6b:8b:53:604
-rw-r--r--fdio.infra.pxe/docker-dnsmasq/tftpboot/grub/grub.cfg-ac:1f:6b:8b:53:644
-rw-r--r--fdio.infra.pxe/docker-dnsmasq/tftpboot/grub/grub.cfg-ac:1f:6b:8b:53:964
-rw-r--r--fdio.infra.pxe/docker-dnsmasq/tftpboot/grub/grub.cfg-ac:1f:6b:8b:54:c44
-rw-r--r--fdio.infra.pxe/docker-dnsmasq/tftpboot/grub/grub.cfg-ac:1f:6b:8b:54:c84
-rw-r--r--fdio.infra.pxe/docker-dnsmasq/tftpboot/grub/grub.cfg-ac:1f:6b:8b:55:784
-rw-r--r--fdio.infra.pxe/docker-dnsmasq/tftpboot/grub/grub.cfg-ac:1f:6b:8b:55:ae4
-rw-r--r--fdio.infra.pxe/docker-dnsmasq/tftpboot/grub/grub.cfg-ac:1f:6b:8b:55:d84
-rw-r--r--fdio.infra.pxe/docker-dnsmasq/tftpboot/grub/grub.cfg-ac:1f:6b:8b:56:8c4
-rw-r--r--fdio.infra.pxe/docker-dnsmasq/tftpboot/grub/grub.cfg-ac:1f:6b:8b:56:b64
-rw-r--r--fdio.infra.pxe/docker-dnsmasq/tftpboot/grub/grub.cfg-ac:1f:6b:8b:56:e24
-rw-r--r--fdio.infra.pxe/docker-dnsmasq/tftpboot/grub/grub.cfg-ac:1f:6b:ab:d7:4a4
-rw-r--r--fdio.infra.pxe/docker-dnsmasq/tftpboot/grub/grub.cfg-ac:1f:6b:ab:d7:924
-rw-r--r--fdio.infra.pxe/docker-dnsmasq/tftpboot/grub/grub.cfg-ac:1f:6b:ab:d9:ae4
-rw-r--r--fdio.infra.pxe/docker-dnsmasq/tftpboot/grub/grub.cfg-ac:1f:6b:ac:d7:564
-rw-r--r--fdio.infra.pxe/docker-dnsmasq/tftpboot/grub/grub.cfg-ac:1f:6b:ac:d7:764
-rw-r--r--fdio.infra.pxe/docker-dnsmasq/tftpboot/grub/grub.cfg-ac:1f:6b:ac:d7:8c4
-rw-r--r--fdio.infra.pxe/docker-dnsmasq/tftpboot/grub/grub.cfg-ac:1f:6b:ac:d7:ba4
-rw-r--r--fdio.infra.pxe/docker-dnsmasq/tftpboot/grub/grub.cfg-ac:1f:6b:ac:d7:c04
-rw-r--r--fdio.infra.pxe/docker-dnsmasq/tftpboot/grub/grub.cfg-ac:1f:6b:ac:d7:d64
-rw-r--r--fdio.infra.pxe/docker-dnsmasq/tftpboot/grub/grub.cfg-ac:1f:6b:ac:d9:2e2
-rw-r--r--fdio.infra.pxe/docker-dnsmasq/tftpboot/grub/grub.cfg-b4:2e:99:ab:1d:dc4
-rw-r--r--fdio.infra.pxe/docker-dnsmasq/tftpboot/grub/grub.cfg-b4:2e:99:ab:1d:e84
-rw-r--r--fdio.infra.pxe/docker-dnsmasq/tftpboot/grub/grub.cfg-cc:46:d6:17:e0:584
-rw-r--r--fdio.infra.pxe/docker-dnsmasq/tftpboot/grub/grub.cfg-d8:5e:d3:02:b1:9f2
-rw-r--r--fdio.infra.pxe/docker-dnsmasq/tftpboot/grub/grub.cfg-d8:5e:d3:02:b1:bb2
-rw-r--r--fdio.infra.pxe/docker-dnsmasq/tftpboot/grub/grub.cfg-e0:d5:5e:ae:70:264
-rw-r--r--fdio.infra.pxe/docker-nginx/Dockerfile24
-rw-r--r--fdio.infra.pxe/docker-nginx/html/ubuntu_focal_amd64/00:42:68:6f:68:ee/user-data83
-rw-r--r--fdio.infra.pxe/docker-nginx/html/ubuntu_focal_amd64/00:42:68:6f:6f:c0/user-data83
-rw-r--r--fdio.infra.pxe/docker-nginx/html/ubuntu_focal_amd64/00:f2:8b:7c:fb:12/user-data83
-rw-r--r--fdio.infra.pxe/docker-nginx/html/ubuntu_focal_amd64/00:f2:8b:7c:fb:4a/user-data83
-rw-r--r--fdio.infra.pxe/docker-nginx/html/ubuntu_focal_amd64/00:fe:c8:58:1e:f6/user-data83
-rw-r--r--fdio.infra.pxe/docker-nginx/html/ubuntu_focal_amd64/00:fe:c8:e5:68:32/user-data83
-rw-r--r--fdio.infra.pxe/docker-nginx/html/ubuntu_focal_amd64/00:fe:c8:e5:68:c2/user-data83
-rw-r--r--fdio.infra.pxe/docker-nginx/html/ubuntu_focal_amd64/00:fe:c8:e5:68:e0/user-data83
-rw-r--r--fdio.infra.pxe/docker-nginx/html/ubuntu_focal_amd64/00:fe:c8:e5:6a:72/user-data83
-rw-r--r--fdio.infra.pxe/docker-nginx/html/ubuntu_focal_amd64/00:fe:c8:e5:6c:76/user-data83
-rw-r--r--fdio.infra.pxe/docker-nginx/html/ubuntu_focal_amd64/38:0e:4d:9c:4b:0c/user-data83
-rw-r--r--fdio.infra.pxe/docker-nginx/html/ubuntu_focal_amd64/38:0e:4d:9c:85:7a/user-data83
-rw-r--r--fdio.infra.pxe/docker-nginx/html/ubuntu_focal_amd64/4c:00:82:ae:5a:f8/user-data120
-rw-r--r--fdio.infra.pxe/docker-nginx/html/ubuntu_focal_amd64/58:ac:78:5c:90:78/user-data83
-rw-r--r--fdio.infra.pxe/docker-nginx/html/ubuntu_focal_amd64/6c:41:6a:1f:39:26/user-data120
-rw-r--r--fdio.infra.pxe/docker-nginx/html/ubuntu_focal_amd64/ac:1f:6b:ab:d9:ae/meta-data0
-rw-r--r--fdio.infra.pxe/docker-nginx/html/ubuntu_focal_amd64/ac:1f:6b:ac:d7:56/meta-data0
-rw-r--r--fdio.infra.pxe/docker-nginx/html/ubuntu_focal_amd64/ac:1f:6b:ac:d7:76/meta-data0
-rw-r--r--fdio.infra.pxe/docker-nginx/html/ubuntu_focal_amd64/ac:1f:6b:ac:d7:8c/meta-data0
-rw-r--r--fdio.infra.pxe/docker-nginx/html/ubuntu_focal_amd64/ac:1f:6b:ac:d7:ba/meta-data0
-rw-r--r--fdio.infra.pxe/docker-nginx/html/ubuntu_focal_amd64/ac:1f:6b:ac:d7:c0/meta-data0
-rw-r--r--fdio.infra.pxe/docker-nginx/html/ubuntu_focal_amd64/ac:1f:6b:ac:d7:d6/meta-data0
-rw-r--r--fdio.infra.pxe/docker-nginx/html/ubuntu_focal_amd64/cc:46:d6:17:e0:58/meta-data0
-rw-r--r--fdio.infra.pxe/docker-nginx/html/ubuntu_focal_amd64/cc:46:d6:17:e0:58/user-data83
-rw-r--r--fdio.infra.pxe/docker-nginx/html/ubuntu_focal_arm64/40:8d:5c:e7:b2:6e/meta-data0
-rw-r--r--fdio.infra.pxe/docker-nginx/html/ubuntu_focal_arm64/90:e2:ba:49:db:b4/meta-data0
-rw-r--r--fdio.infra.pxe/docker-nginx/html/ubuntu_focal_arm64/90:e2:ba:55:be:32/meta-data0
-rw-r--r--fdio.infra.pxe/docker-nginx/html/ubuntu_focal_arm64/a0:a3:3b:c1:12:fa/meta-data0
-rw-r--r--fdio.infra.pxe/docker-nginx/html/ubuntu_focal_arm64/a0:a3:3b:c1:14:28/meta-data0
-rw-r--r--fdio.infra.pxe/docker-nginx/html/ubuntu_focal_arm64/b4:2e:99:ab:1d:dc/meta-data0
-rw-r--r--fdio.infra.pxe/docker-nginx/html/ubuntu_focal_arm64/b4:2e:99:ab:1d:e8/meta-data0
-rw-r--r--fdio.infra.pxe/docker-nginx/html/ubuntu_focal_arm64/e0:d5:5e:ae:70:26/meta-data0
-rw-r--r--fdio.infra.pxe/docker-nginx/html/ubuntu_jammy_amd64/0c:c4:7a:fc:c9:58/meta-data (renamed from fdio.infra.pxe/docker-nginx/html/ubuntu_focal_amd64/00:42:68:6f:68:ee/meta-data)0
-rw-r--r--fdio.infra.pxe/docker-nginx/html/ubuntu_jammy_amd64/0c:c4:7a:fc:c9:58/user-data (renamed from fdio.infra.pxe/docker-nginx/html/ubuntu_focal_amd64/0c:c4:7a:fc:c9:58/user-data)0
-rw-r--r--fdio.infra.pxe/docker-nginx/html/ubuntu_jammy_amd64/0c:c4:7a:fc:ca:90/meta-data (renamed from fdio.infra.pxe/docker-nginx/html/ubuntu_focal_amd64/00:42:68:6f:6f:c0/meta-data)0
-rw-r--r--fdio.infra.pxe/docker-nginx/html/ubuntu_jammy_amd64/0c:c4:7a:fc:ca:90/user-data (renamed from fdio.infra.pxe/docker-nginx/html/ubuntu_focal_amd64/0c:c4:7a:fc:ca:90/user-data)0
-rw-r--r--fdio.infra.pxe/docker-nginx/html/ubuntu_jammy_amd64/0c:c4:7a:fc:ca:cc/meta-data (renamed from fdio.infra.pxe/docker-nginx/html/ubuntu_focal_amd64/00:f2:8b:7c:fb:12/meta-data)0
-rw-r--r--fdio.infra.pxe/docker-nginx/html/ubuntu_jammy_amd64/0c:c4:7a:fc:ca:cc/user-data (renamed from fdio.infra.pxe/docker-nginx/html/ubuntu_focal_amd64/0c:c4:7a:fc:ca:cc/user-data)0
-rw-r--r--fdio.infra.pxe/docker-nginx/html/ubuntu_jammy_amd64/3c:ec:ef:43:a3:ba/meta-data (renamed from fdio.infra.pxe/docker-nginx/html/ubuntu_focal_amd64/00:f2:8b:7c:fb:4a/meta-data)0
-rw-r--r--fdio.infra.pxe/docker-nginx/html/ubuntu_jammy_amd64/3c:ec:ef:43:a3:ba/user-data (renamed from fdio.infra.pxe/docker-nginx/html/ubuntu_focal_amd64/3c:ec:ef:43:a3:ba/user-data)0
-rw-r--r--fdio.infra.pxe/docker-nginx/html/ubuntu_jammy_amd64/3c:ec:ef:46:34:e8/meta-data (renamed from fdio.infra.pxe/docker-nginx/html/ubuntu_focal_amd64/00:fe:c8:58:1e:f6/meta-data)0
-rw-r--r--fdio.infra.pxe/docker-nginx/html/ubuntu_jammy_amd64/3c:ec:ef:46:34:e8/user-data (renamed from fdio.infra.pxe/docker-nginx/html/ubuntu_focal_amd64/3c:ec:ef:46:34:e8/user-data)0
-rw-r--r--fdio.infra.pxe/docker-nginx/html/ubuntu_jammy_amd64/3c:ec:ef:b9:7f:12/meta-data (renamed from fdio.infra.pxe/docker-nginx/html/ubuntu_focal_amd64/00:fe:c8:e5:68:32/meta-data)0
-rw-r--r--fdio.infra.pxe/docker-nginx/html/ubuntu_jammy_amd64/3c:ec:ef:b9:7f:12/user-data (renamed from fdio.infra.pxe/docker-nginx/html/ubuntu_focal_amd64/3c:ec:ef:b9:7f:12/user-data)0
-rw-r--r--fdio.infra.pxe/docker-nginx/html/ubuntu_jammy_amd64/3c:ec:ef:b9:a6:80/meta-data (renamed from fdio.infra.pxe/docker-nginx/html/ubuntu_focal_amd64/00:fe:c8:e5:68:c2/meta-data)0
-rw-r--r--fdio.infra.pxe/docker-nginx/html/ubuntu_jammy_amd64/3c:ec:ef:b9:a6:80/user-data (renamed from fdio.infra.pxe/docker-nginx/html/ubuntu_focal_amd64/3c:ec:ef:b9:a6:80/user-data)0
-rw-r--r--fdio.infra.pxe/docker-nginx/html/ubuntu_jammy_amd64/3c:ec:ef:b9:a6:92/meta-data (renamed from fdio.infra.pxe/docker-nginx/html/ubuntu_focal_amd64/00:fe:c8:e5:68:e0/meta-data)0
-rw-r--r--fdio.infra.pxe/docker-nginx/html/ubuntu_jammy_amd64/3c:ec:ef:b9:a6:92/user-data (renamed from fdio.infra.pxe/docker-nginx/html/ubuntu_focal_amd64/3c:ec:ef:b9:a6:92/user-data)0
-rw-r--r--fdio.infra.pxe/docker-nginx/html/ubuntu_jammy_amd64/3c:ec:ef:b9:a6:ba/meta-data (renamed from fdio.infra.pxe/docker-nginx/html/ubuntu_focal_amd64/00:fe:c8:e5:6a:72/meta-data)0
-rw-r--r--fdio.infra.pxe/docker-nginx/html/ubuntu_jammy_amd64/3c:ec:ef:b9:a6:ba/user-data (renamed from fdio.infra.pxe/docker-nginx/html/ubuntu_focal_amd64/3c:ec:ef:b9:a6:ba/user-data)0
-rw-r--r--fdio.infra.pxe/docker-nginx/html/ubuntu_jammy_amd64/3c:ec:ef:b9:a6:c6/meta-data (renamed from fdio.infra.pxe/docker-nginx/html/ubuntu_focal_amd64/00:fe:c8:e5:6c:76/meta-data)0
-rw-r--r--fdio.infra.pxe/docker-nginx/html/ubuntu_jammy_amd64/3c:ec:ef:b9:a6:c6/user-data (renamed from fdio.infra.pxe/docker-nginx/html/ubuntu_focal_amd64/3c:ec:ef:b9:a6:c6/user-data)0
-rw-r--r--fdio.infra.pxe/docker-nginx/html/ubuntu_jammy_amd64/3c:ec:ef:b9:a6:ca/meta-data (renamed from fdio.infra.pxe/docker-nginx/html/ubuntu_focal_amd64/0c:c4:7a:fc:c9:58/meta-data)0
-rw-r--r--fdio.infra.pxe/docker-nginx/html/ubuntu_jammy_amd64/3c:ec:ef:b9:a6:ca/user-data (renamed from fdio.infra.pxe/docker-nginx/html/ubuntu_focal_amd64/3c:ec:ef:b9:a6:ca/user-data)0
-rw-r--r--fdio.infra.pxe/docker-nginx/html/ubuntu_jammy_amd64/3c:ec:ef:b9:cc:44/meta-data (renamed from fdio.infra.pxe/docker-nginx/html/ubuntu_focal_amd64/0c:c4:7a:fc:ca:90/meta-data)0
-rw-r--r--fdio.infra.pxe/docker-nginx/html/ubuntu_jammy_amd64/3c:ec:ef:b9:cc:44/user-data (renamed from fdio.infra.pxe/docker-nginx/html/ubuntu_focal_amd64/3c:ec:ef:b9:cc:44/user-data)0
-rw-r--r--fdio.infra.pxe/docker-nginx/html/ubuntu_jammy_amd64/3c:ec:ef:b9:cc:56/meta-data (renamed from fdio.infra.pxe/docker-nginx/html/ubuntu_focal_amd64/0c:c4:7a:fc:ca:cc/meta-data)0
-rw-r--r--fdio.infra.pxe/docker-nginx/html/ubuntu_jammy_amd64/3c:ec:ef:b9:cc:56/user-data (renamed from fdio.infra.pxe/docker-nginx/html/ubuntu_focal_amd64/3c:ec:ef:b9:cc:56/user-data)0
-rw-r--r--fdio.infra.pxe/docker-nginx/html/ubuntu_jammy_amd64/3c:ec:ef:bc:92:26/meta-data (renamed from fdio.infra.pxe/docker-nginx/html/ubuntu_focal_amd64/38:0e:4d:9c:4b:0c/meta-data)0
-rw-r--r--fdio.infra.pxe/docker-nginx/html/ubuntu_jammy_amd64/3c:ec:ef:bc:92:26/user-data (renamed from fdio.infra.pxe/docker-nginx/html/ubuntu_focal_amd64/3c:ec:ef:bc:92:26/user-data)0
-rw-r--r--fdio.infra.pxe/docker-nginx/html/ubuntu_jammy_amd64/3c:ec:ef:bc:92:b2/meta-data (renamed from fdio.infra.pxe/docker-nginx/html/ubuntu_focal_amd64/38:0e:4d:9c:85:7a/meta-data)0
-rw-r--r--fdio.infra.pxe/docker-nginx/html/ubuntu_jammy_amd64/3c:ec:ef:bc:92:b2/user-data (renamed from fdio.infra.pxe/docker-nginx/html/ubuntu_focal_amd64/3c:ec:ef:bc:92:b2/user-data)0
-rw-r--r--fdio.infra.pxe/docker-nginx/html/ubuntu_jammy_amd64/3c:ec:ef:bc:92:e4/meta-data (renamed from fdio.infra.pxe/docker-nginx/html/ubuntu_focal_amd64/3c:ec:ef:43:a3:ba/meta-data)0
-rw-r--r--fdio.infra.pxe/docker-nginx/html/ubuntu_jammy_amd64/3c:ec:ef:bc:92:e4/user-data (renamed from fdio.infra.pxe/docker-nginx/html/ubuntu_focal_amd64/3c:ec:ef:bc:92:e4/user-data)0
-rw-r--r--fdio.infra.pxe/docker-nginx/html/ubuntu_jammy_amd64/3c:ec:ef:bc:92:e8/meta-data (renamed from fdio.infra.pxe/docker-nginx/html/ubuntu_focal_amd64/3c:ec:ef:46:34:e8/meta-data)0
-rw-r--r--fdio.infra.pxe/docker-nginx/html/ubuntu_jammy_amd64/3c:ec:ef:bc:92:e8/user-data (renamed from fdio.infra.pxe/docker-nginx/html/ubuntu_focal_amd64/3c:ec:ef:bc:92:e8/user-data)0
-rw-r--r--fdio.infra.pxe/docker-nginx/html/ubuntu_jammy_amd64/3c:ec:ef:bc:a0:d4/meta-data (renamed from fdio.infra.pxe/docker-nginx/html/ubuntu_focal_amd64/3c:ec:ef:b9:7f:12/meta-data)0
-rw-r--r--fdio.infra.pxe/docker-nginx/html/ubuntu_jammy_amd64/3c:ec:ef:bc:a0:d4/user-data (renamed from fdio.infra.pxe/docker-nginx/html/ubuntu_focal_amd64/3c:ec:ef:bc:a0:d4/user-data)0
-rw-r--r--fdio.infra.pxe/docker-nginx/html/ubuntu_jammy_amd64/3c:ec:ef:bc:a0:ec/meta-data (renamed from fdio.infra.pxe/docker-nginx/html/ubuntu_focal_amd64/3c:ec:ef:b9:a6:80/meta-data)0
-rw-r--r--fdio.infra.pxe/docker-nginx/html/ubuntu_jammy_amd64/3c:ec:ef:bc:a0:ec/user-data (renamed from fdio.infra.pxe/docker-nginx/html/ubuntu_focal_amd64/3c:ec:ef:bc:a0:ec/user-data)0
-rw-r--r--fdio.infra.pxe/docker-nginx/html/ubuntu_jammy_amd64/3c:ec:ef:bc:a1:ac/meta-data (renamed from fdio.infra.pxe/docker-nginx/html/ubuntu_focal_amd64/3c:ec:ef:b9:a6:92/meta-data)0
-rw-r--r--fdio.infra.pxe/docker-nginx/html/ubuntu_jammy_amd64/3c:ec:ef:bc:a1:ac/user-data (renamed from fdio.infra.pxe/docker-nginx/html/ubuntu_focal_amd64/3c:ec:ef:bc:a1:ac/user-data)0
-rw-r--r--fdio.infra.pxe/docker-nginx/html/ubuntu_jammy_amd64/3c:ec:ef:bc:a1:ea/meta-data (renamed from fdio.infra.pxe/docker-nginx/html/ubuntu_focal_amd64/3c:ec:ef:b9:a6:ba/meta-data)0
-rw-r--r--fdio.infra.pxe/docker-nginx/html/ubuntu_jammy_amd64/3c:ec:ef:bc:a1:ea/user-data (renamed from fdio.infra.pxe/docker-nginx/html/ubuntu_focal_amd64/3c:ec:ef:bc:a1:ea/user-data)0
-rw-r--r--fdio.infra.pxe/docker-nginx/html/ubuntu_jammy_amd64/a4:bf:01:55:ac:39/meta-data (renamed from fdio.infra.pxe/docker-nginx/html/ubuntu_focal_amd64/3c:ec:ef:b9:a6:c6/meta-data)0
-rw-r--r--fdio.infra.pxe/docker-nginx/html/ubuntu_jammy_amd64/a4:bf:01:55:ac:39/user-data (renamed from fdio.infra.pxe/docker-nginx/html/ubuntu_focal_amd64/a4:bf:01:55:ac:39/user-data)0
-rw-r--r--fdio.infra.pxe/docker-nginx/html/ubuntu_jammy_amd64/a4:bf:01:55:af:5e/meta-data (renamed from fdio.infra.pxe/docker-nginx/html/ubuntu_focal_amd64/3c:ec:ef:b9:a6:ca/meta-data)0
-rw-r--r--fdio.infra.pxe/docker-nginx/html/ubuntu_jammy_amd64/a4:bf:01:55:af:5e/user-data (renamed from fdio.infra.pxe/docker-nginx/html/ubuntu_focal_amd64/a4:bf:01:55:af:5e/user-data)0
-rw-r--r--fdio.infra.pxe/docker-nginx/html/ubuntu_jammy_amd64/ac:1f:6b:8a:8c:76/meta-data (renamed from fdio.infra.pxe/docker-nginx/html/ubuntu_focal_amd64/3c:ec:ef:b9:cc:44/meta-data)0
-rw-r--r--fdio.infra.pxe/docker-nginx/html/ubuntu_jammy_amd64/ac:1f:6b:8a:8c:76/user-data (renamed from fdio.infra.pxe/docker-nginx/html/ubuntu_focal_amd64/ac:1f:6b:8a:8c:76/user-data)0
-rw-r--r--fdio.infra.pxe/docker-nginx/html/ubuntu_jammy_amd64/ac:1f:6b:8a:8d:0a/meta-data (renamed from fdio.infra.pxe/docker-nginx/html/ubuntu_focal_amd64/3c:ec:ef:b9:cc:56/meta-data)0
-rw-r--r--fdio.infra.pxe/docker-nginx/html/ubuntu_jammy_amd64/ac:1f:6b:8a:8d:0a/user-data (renamed from fdio.infra.pxe/docker-nginx/html/ubuntu_focal_amd64/ac:1f:6b:8a:8d:0a/user-data)0
-rw-r--r--fdio.infra.pxe/docker-nginx/html/ubuntu_jammy_amd64/ac:1f:6b:8a:8d:94/meta-data (renamed from fdio.infra.pxe/docker-nginx/html/ubuntu_focal_amd64/3c:ec:ef:bc:92:26/meta-data)0
-rw-r--r--fdio.infra.pxe/docker-nginx/html/ubuntu_jammy_amd64/ac:1f:6b:8a:8d:94/user-data (renamed from fdio.infra.pxe/docker-nginx/html/ubuntu_focal_amd64/ac:1f:6b:8a:8d:94/user-data)0
-rw-r--r--fdio.infra.pxe/docker-nginx/html/ubuntu_jammy_amd64/ac:1f:6b:8a:8d:b6/meta-data (renamed from fdio.infra.pxe/docker-nginx/html/ubuntu_focal_amd64/3c:ec:ef:bc:92:b2/meta-data)0
-rw-r--r--fdio.infra.pxe/docker-nginx/html/ubuntu_jammy_amd64/ac:1f:6b:8a:8d:b6/user-data (renamed from fdio.infra.pxe/docker-nginx/html/ubuntu_focal_amd64/ac:1f:6b:8a:8d:b6/user-data)0
-rw-r--r--fdio.infra.pxe/docker-nginx/html/ubuntu_jammy_amd64/ac:1f:6b:8b:53:60/meta-data (renamed from fdio.infra.pxe/docker-nginx/html/ubuntu_focal_amd64/3c:ec:ef:bc:92:e4/meta-data)0
-rw-r--r--fdio.infra.pxe/docker-nginx/html/ubuntu_jammy_amd64/ac:1f:6b:8b:53:60/user-data (renamed from fdio.infra.pxe/docker-nginx/html/ubuntu_focal_amd64/ac:1f:6b:8b:53:60/user-data)0
-rw-r--r--fdio.infra.pxe/docker-nginx/html/ubuntu_jammy_amd64/ac:1f:6b:8b:53:64/meta-data (renamed from fdio.infra.pxe/docker-nginx/html/ubuntu_focal_amd64/3c:ec:ef:bc:92:e8/meta-data)0
-rw-r--r--fdio.infra.pxe/docker-nginx/html/ubuntu_jammy_amd64/ac:1f:6b:8b:53:64/user-data (renamed from fdio.infra.pxe/docker-nginx/html/ubuntu_focal_amd64/ac:1f:6b:8b:53:64/user-data)0
-rw-r--r--fdio.infra.pxe/docker-nginx/html/ubuntu_jammy_amd64/ac:1f:6b:8b:53:96/meta-data (renamed from fdio.infra.pxe/docker-nginx/html/ubuntu_focal_amd64/3c:ec:ef:bc:a0:d4/meta-data)0
-rw-r--r--fdio.infra.pxe/docker-nginx/html/ubuntu_jammy_amd64/ac:1f:6b:8b:53:96/user-data (renamed from fdio.infra.pxe/docker-nginx/html/ubuntu_focal_amd64/ac:1f:6b:8b:53:96/user-data)0
-rw-r--r--fdio.infra.pxe/docker-nginx/html/ubuntu_jammy_amd64/ac:1f:6b:8b:54:c4/meta-data (renamed from fdio.infra.pxe/docker-nginx/html/ubuntu_focal_amd64/3c:ec:ef:bc:a0:ec/meta-data)0
-rw-r--r--fdio.infra.pxe/docker-nginx/html/ubuntu_jammy_amd64/ac:1f:6b:8b:54:c4/user-data (renamed from fdio.infra.pxe/docker-nginx/html/ubuntu_focal_amd64/ac:1f:6b:8b:54:c4/user-data)0
-rw-r--r--fdio.infra.pxe/docker-nginx/html/ubuntu_jammy_amd64/ac:1f:6b:8b:54:c8/meta-data (renamed from fdio.infra.pxe/docker-nginx/html/ubuntu_focal_amd64/3c:ec:ef:bc:a1:ac/meta-data)0
-rw-r--r--fdio.infra.pxe/docker-nginx/html/ubuntu_jammy_amd64/ac:1f:6b:8b:54:c8/user-data (renamed from fdio.infra.pxe/docker-nginx/html/ubuntu_focal_amd64/ac:1f:6b:8b:54:c8/user-data)0
-rw-r--r--fdio.infra.pxe/docker-nginx/html/ubuntu_jammy_amd64/ac:1f:6b:8b:55:78/meta-data (renamed from fdio.infra.pxe/docker-nginx/html/ubuntu_focal_amd64/3c:ec:ef:bc:a1:ea/meta-data)0
-rw-r--r--fdio.infra.pxe/docker-nginx/html/ubuntu_jammy_amd64/ac:1f:6b:8b:55:78/user-data (renamed from fdio.infra.pxe/docker-nginx/html/ubuntu_focal_amd64/ac:1f:6b:8b:55:78/user-data)0
-rw-r--r--fdio.infra.pxe/docker-nginx/html/ubuntu_jammy_amd64/ac:1f:6b:8b:55:ae/meta-data (renamed from fdio.infra.pxe/docker-nginx/html/ubuntu_focal_amd64/4c:00:82:ae:5a:f8/meta-data)0
-rw-r--r--fdio.infra.pxe/docker-nginx/html/ubuntu_jammy_amd64/ac:1f:6b:8b:55:ae/user-data (renamed from fdio.infra.pxe/docker-nginx/html/ubuntu_focal_amd64/ac:1f:6b:8b:55:ae/user-data)0
-rw-r--r--fdio.infra.pxe/docker-nginx/html/ubuntu_jammy_amd64/ac:1f:6b:8b:55:d8/meta-data (renamed from fdio.infra.pxe/docker-nginx/html/ubuntu_focal_amd64/58:ac:78:5c:90:78/meta-data)0
-rw-r--r--fdio.infra.pxe/docker-nginx/html/ubuntu_jammy_amd64/ac:1f:6b:8b:55:d8/user-data (renamed from fdio.infra.pxe/docker-nginx/html/ubuntu_focal_amd64/ac:1f:6b:8b:55:d8/user-data)0
-rw-r--r--fdio.infra.pxe/docker-nginx/html/ubuntu_jammy_amd64/ac:1f:6b:8b:56:8c/meta-data (renamed from fdio.infra.pxe/docker-nginx/html/ubuntu_focal_amd64/6c:41:6a:1f:39:26/meta-data)0
-rw-r--r--fdio.infra.pxe/docker-nginx/html/ubuntu_jammy_amd64/ac:1f:6b:8b:56:8c/user-data (renamed from fdio.infra.pxe/docker-nginx/html/ubuntu_focal_amd64/ac:1f:6b:8b:56:8c/user-data)0
-rw-r--r--fdio.infra.pxe/docker-nginx/html/ubuntu_jammy_amd64/ac:1f:6b:8b:56:b6/meta-data (renamed from fdio.infra.pxe/docker-nginx/html/ubuntu_focal_amd64/a4:bf:01:55:ac:39/meta-data)0
-rw-r--r--fdio.infra.pxe/docker-nginx/html/ubuntu_jammy_amd64/ac:1f:6b:8b:56:b6/user-data (renamed from fdio.infra.pxe/docker-nginx/html/ubuntu_focal_amd64/ac:1f:6b:8b:56:b6/user-data)0
-rw-r--r--fdio.infra.pxe/docker-nginx/html/ubuntu_jammy_amd64/ac:1f:6b:8b:56:e2/meta-data (renamed from fdio.infra.pxe/docker-nginx/html/ubuntu_focal_amd64/a4:bf:01:55:af:5e/meta-data)0
-rw-r--r--fdio.infra.pxe/docker-nginx/html/ubuntu_jammy_amd64/ac:1f:6b:8b:56:e2/user-data (renamed from fdio.infra.pxe/docker-nginx/html/ubuntu_focal_amd64/ac:1f:6b:8b:56:e2/user-data)0
-rw-r--r--fdio.infra.pxe/docker-nginx/html/ubuntu_jammy_amd64/ac:1f:6b:ab:d7:4a/meta-data (renamed from fdio.infra.pxe/docker-nginx/html/ubuntu_focal_amd64/ac:1f:6b:8a:8c:76/meta-data)0
-rw-r--r--fdio.infra.pxe/docker-nginx/html/ubuntu_jammy_amd64/ac:1f:6b:ab:d7:4a/user-data (renamed from fdio.infra.pxe/docker-nginx/html/ubuntu_focal_amd64/ac:1f:6b:ab:d7:4a/user-data)0
-rw-r--r--fdio.infra.pxe/docker-nginx/html/ubuntu_jammy_amd64/ac:1f:6b:ab:d7:92/meta-data (renamed from fdio.infra.pxe/docker-nginx/html/ubuntu_focal_amd64/ac:1f:6b:8a:8d:0a/meta-data)0
-rw-r--r--fdio.infra.pxe/docker-nginx/html/ubuntu_jammy_amd64/ac:1f:6b:ab:d7:92/user-data (renamed from fdio.infra.pxe/docker-nginx/html/ubuntu_focal_amd64/ac:1f:6b:ab:d7:92/user-data)0
-rw-r--r--fdio.infra.pxe/docker-nginx/html/ubuntu_jammy_amd64/ac:1f:6b:ab:d9:ae/meta-data (renamed from fdio.infra.pxe/docker-nginx/html/ubuntu_focal_amd64/ac:1f:6b:8a:8d:94/meta-data)0
-rw-r--r--fdio.infra.pxe/docker-nginx/html/ubuntu_jammy_amd64/ac:1f:6b:ab:d9:ae/user-data (renamed from fdio.infra.pxe/docker-nginx/html/ubuntu_focal_amd64/ac:1f:6b:ab:d9:ae/user-data)0
-rw-r--r--fdio.infra.pxe/docker-nginx/html/ubuntu_jammy_amd64/ac:1f:6b:ac:d7:56/meta-data (renamed from fdio.infra.pxe/docker-nginx/html/ubuntu_focal_amd64/ac:1f:6b:8a:8d:b6/meta-data)0
-rw-r--r--fdio.infra.pxe/docker-nginx/html/ubuntu_jammy_amd64/ac:1f:6b:ac:d7:56/user-data (renamed from fdio.infra.pxe/docker-nginx/html/ubuntu_focal_amd64/ac:1f:6b:ac:d7:56/user-data)0
-rw-r--r--fdio.infra.pxe/docker-nginx/html/ubuntu_jammy_amd64/ac:1f:6b:ac:d7:76/meta-data (renamed from fdio.infra.pxe/docker-nginx/html/ubuntu_focal_amd64/ac:1f:6b:8b:53:60/meta-data)0
-rw-r--r--fdio.infra.pxe/docker-nginx/html/ubuntu_jammy_amd64/ac:1f:6b:ac:d7:76/user-data (renamed from fdio.infra.pxe/docker-nginx/html/ubuntu_focal_amd64/ac:1f:6b:ac:d7:76/user-data)0
-rw-r--r--fdio.infra.pxe/docker-nginx/html/ubuntu_jammy_amd64/ac:1f:6b:ac:d7:8c/meta-data (renamed from fdio.infra.pxe/docker-nginx/html/ubuntu_focal_amd64/ac:1f:6b:8b:53:64/meta-data)0
-rw-r--r--fdio.infra.pxe/docker-nginx/html/ubuntu_jammy_amd64/ac:1f:6b:ac:d7:8c/user-data (renamed from fdio.infra.pxe/docker-nginx/html/ubuntu_focal_amd64/ac:1f:6b:ac:d7:8c/user-data)0
-rw-r--r--fdio.infra.pxe/docker-nginx/html/ubuntu_jammy_amd64/ac:1f:6b:ac:d7:ba/meta-data (renamed from fdio.infra.pxe/docker-nginx/html/ubuntu_focal_amd64/ac:1f:6b:8b:53:96/meta-data)0
-rw-r--r--fdio.infra.pxe/docker-nginx/html/ubuntu_jammy_amd64/ac:1f:6b:ac:d7:ba/user-data (renamed from fdio.infra.pxe/docker-nginx/html/ubuntu_focal_amd64/ac:1f:6b:ac:d7:ba/user-data)0
-rw-r--r--fdio.infra.pxe/docker-nginx/html/ubuntu_jammy_amd64/ac:1f:6b:ac:d7:c0/meta-data (renamed from fdio.infra.pxe/docker-nginx/html/ubuntu_focal_amd64/ac:1f:6b:8b:54:c4/meta-data)0
-rw-r--r--fdio.infra.pxe/docker-nginx/html/ubuntu_jammy_amd64/ac:1f:6b:ac:d7:c0/user-data (renamed from fdio.infra.pxe/docker-nginx/html/ubuntu_focal_amd64/ac:1f:6b:ac:d7:c0/user-data)4
-rw-r--r--fdio.infra.pxe/docker-nginx/html/ubuntu_jammy_amd64/ac:1f:6b:ac:d7:d6/meta-data (renamed from fdio.infra.pxe/docker-nginx/html/ubuntu_focal_amd64/ac:1f:6b:8b:54:c8/meta-data)0
-rw-r--r--fdio.infra.pxe/docker-nginx/html/ubuntu_jammy_amd64/ac:1f:6b:ac:d7:d6/user-data (renamed from fdio.infra.pxe/docker-nginx/html/ubuntu_focal_amd64/ac:1f:6b:ac:d7:d6/user-data)0
-rw-r--r--fdio.infra.pxe/docker-nginx/html/ubuntu_jammy_arm64/40:8d:5c:e7:b2:6e/meta-data (renamed from fdio.infra.pxe/docker-nginx/html/ubuntu_focal_amd64/ac:1f:6b:8b:55:78/meta-data)0
-rw-r--r--fdio.infra.pxe/docker-nginx/html/ubuntu_jammy_arm64/40:8d:5c:e7:b2:6e/user-data (renamed from fdio.infra.pxe/docker-nginx/html/ubuntu_focal_arm64/40:8d:5c:e7:b2:6e/user-data)0
-rw-r--r--fdio.infra.pxe/docker-nginx/html/ubuntu_jammy_arm64/90:e2:ba:49:db:b4/meta-data (renamed from fdio.infra.pxe/docker-nginx/html/ubuntu_focal_amd64/ac:1f:6b:8b:55:ae/meta-data)0
-rw-r--r--fdio.infra.pxe/docker-nginx/html/ubuntu_jammy_arm64/90:e2:ba:49:db:b4/user-data (renamed from fdio.infra.pxe/docker-nginx/html/ubuntu_focal_arm64/90:e2:ba:49:db:b4/user-data)0
-rw-r--r--fdio.infra.pxe/docker-nginx/html/ubuntu_jammy_arm64/90:e2:ba:55:be:32/meta-data (renamed from fdio.infra.pxe/docker-nginx/html/ubuntu_focal_amd64/ac:1f:6b:8b:55:d8/meta-data)0
-rw-r--r--fdio.infra.pxe/docker-nginx/html/ubuntu_jammy_arm64/90:e2:ba:55:be:32/user-data (renamed from fdio.infra.pxe/docker-nginx/html/ubuntu_focal_arm64/90:e2:ba:55:be:32/user-data)0
-rw-r--r--fdio.infra.pxe/docker-nginx/html/ubuntu_jammy_arm64/a0:a3:3b:c1:12:fa/meta-data (renamed from fdio.infra.pxe/docker-nginx/html/ubuntu_focal_amd64/ac:1f:6b:8b:56:8c/meta-data)0
-rw-r--r--fdio.infra.pxe/docker-nginx/html/ubuntu_jammy_arm64/a0:a3:3b:c1:12:fa/user-data (renamed from fdio.infra.pxe/docker-nginx/html/ubuntu_focal_arm64/a0:a3:3b:c1:12:fa/user-data)0
-rw-r--r--fdio.infra.pxe/docker-nginx/html/ubuntu_jammy_arm64/a0:a3:3b:c1:14:28/meta-data (renamed from fdio.infra.pxe/docker-nginx/html/ubuntu_focal_amd64/ac:1f:6b:8b:56:b6/meta-data)0
-rw-r--r--fdio.infra.pxe/docker-nginx/html/ubuntu_jammy_arm64/a0:a3:3b:c1:14:28/user-data (renamed from fdio.infra.pxe/docker-nginx/html/ubuntu_focal_arm64/a0:a3:3b:c1:14:28/user-data)0
-rw-r--r--fdio.infra.pxe/docker-nginx/html/ubuntu_jammy_arm64/b4:2e:99:ab:1d:dc/meta-data (renamed from fdio.infra.pxe/docker-nginx/html/ubuntu_focal_amd64/ac:1f:6b:8b:56:e2/meta-data)0
-rw-r--r--fdio.infra.pxe/docker-nginx/html/ubuntu_jammy_arm64/b4:2e:99:ab:1d:dc/user-data (renamed from fdio.infra.pxe/docker-nginx/html/ubuntu_focal_arm64/b4:2e:99:ab:1d:dc/user-data)0
-rw-r--r--fdio.infra.pxe/docker-nginx/html/ubuntu_jammy_arm64/b4:2e:99:ab:1d:e8/meta-data (renamed from fdio.infra.pxe/docker-nginx/html/ubuntu_focal_amd64/ac:1f:6b:ab:d7:4a/meta-data)0
-rw-r--r--fdio.infra.pxe/docker-nginx/html/ubuntu_jammy_arm64/b4:2e:99:ab:1d:e8/user-data (renamed from fdio.infra.pxe/docker-nginx/html/ubuntu_focal_arm64/b4:2e:99:ab:1d:e8/user-data)0
-rw-r--r--fdio.infra.pxe/docker-nginx/html/ubuntu_jammy_arm64/e0:d5:5e:ae:70:26/meta-data (renamed from fdio.infra.pxe/docker-nginx/html/ubuntu_focal_amd64/ac:1f:6b:ab:d7:92/meta-data)0
-rw-r--r--fdio.infra.pxe/docker-nginx/html/ubuntu_jammy_arm64/e0:d5:5e:ae:70:26/user-data (renamed from fdio.infra.pxe/docker-nginx/html/ubuntu_focal_arm64/e0:d5:5e:ae:70:26/user-data)0
-rw-r--r--fdio.infra.terraform/terraform-aws-1n-aws-c5n/main.tf2
-rw-r--r--fdio.infra.terraform/terraform-aws-1n-aws-c5n/providers.tf2
-rw-r--r--fdio.infra.terraform/terraform-aws-1n-aws-c5n/variables.tf14
-rw-r--r--fdio.infra.terraform/terraform-aws-1n-aws-c5n/versions.tf6
-rw-r--r--fdio.infra.terraform/terraform-aws-2n-aws-c5n/main.tf2
-rw-r--r--fdio.infra.terraform/terraform-aws-2n-aws-c5n/providers.tf2
-rw-r--r--fdio.infra.terraform/terraform-aws-2n-aws-c5n/variables.tf18
-rw-r--r--fdio.infra.terraform/terraform-aws-2n-aws-c5n/versions.tf6
-rw-r--r--fdio.infra.terraform/terraform-aws-3n-aws-c5n/main.tf2
-rw-r--r--fdio.infra.terraform/terraform-aws-3n-aws-c5n/providers.tf2
-rw-r--r--fdio.infra.terraform/terraform-aws-3n-aws-c5n/variables.tf15
-rw-r--r--fdio.infra.terraform/terraform-aws-3n-aws-c5n/versions.tf6
-rw-r--r--fdio.infra.terraform/terraform-nomad-loki/README.md52
-rw-r--r--fdio.infra.terraform/terraform-nomad-loki/conf/nomad/loki.hcl.tftpl261
-rw-r--r--fdio.infra.terraform/terraform-nomad-loki/main.tf40
-rw-r--r--fdio.infra.terraform/terraform-nomad-loki/variables.tf127
-rw-r--r--fdio.infra.terraform/terraform-nomad-loki/versions.tf9
-rw-r--r--fdio.infra.terraform/terraform-nomad-pyspark-etl/conf/nomad/etl.hcl.tftpl541
-rw-r--r--requirements.txt8
-rw-r--r--resources/api/vpp/supported_crcs.yaml37
-rw-r--r--resources/libraries/bash/function/common.sh29
-rw-r--r--resources/libraries/bash/function/device.sh4
-rw-r--r--resources/libraries/python/Constants.py13
-rw-r--r--resources/libraries/python/ContainerUtils.py22
-rw-r--r--resources/libraries/python/DUTSetup.py9
-rw-r--r--resources/libraries/python/FlowUtil.py2
-rw-r--r--resources/libraries/python/IPsecUtil.py30
-rw-r--r--resources/libraries/python/InterfaceUtil.py2
-rw-r--r--resources/libraries/python/PLRsearch/Integrator.py4
-rw-r--r--resources/libraries/python/PLRsearch/PLRsearch.py2
-rw-r--r--resources/libraries/python/QemuUtils.py4
-rw-r--r--resources/libraries/python/Tap.py4
-rw-r--r--resources/libraries/python/TelemetryUtil.py6
-rw-r--r--resources/libraries/python/VppConfigGenerator.py18
-rw-r--r--resources/libraries/python/WireGuardUtil.py94
-rw-r--r--resources/libraries/python/jumpavg/AvgStdevStats.py56
-rw-r--r--resources/libraries/python/jumpavg/BitCountingGroup.py134
-rw-r--r--resources/libraries/python/jumpavg/BitCountingGroupList.py128
-rw-r--r--resources/libraries/python/jumpavg/BitCountingStats.py110
-rw-r--r--resources/libraries/python/jumpavg/classify.py46
-rw-r--r--resources/libraries/robot/crypto/ipsec.robot17
-rw-r--r--resources/libraries/robot/features/acl.robot6
-rw-r--r--resources/libraries/robot/ip/ip4.robot24
-rw-r--r--resources/libraries/robot/ip/ip6.robot10
-rw-r--r--resources/libraries/robot/l2/l2_bridge_domain.robot6
-rw-r--r--resources/libraries/robot/l2/l2_xconnect.robot4
-rw-r--r--resources/libraries/robot/l2/tagging.robot16
-rw-r--r--resources/libraries/robot/overlay/srv6.robot6
-rw-r--r--resources/libraries/robot/performance/performance_actions.robot72
-rw-r--r--resources/libraries/robot/performance/performance_utils.robot26
-rw-r--r--resources/libraries/robot/shared/interfaces.robot1
-rw-r--r--resources/libraries/robot/shared/suite_setup.robot3
-rw-r--r--resources/libraries/robot/shared/suite_teardown.robot1
-rw-r--r--resources/libraries/robot/shared/test_setup.robot4
-rw-r--r--resources/libraries/robot/wireguard/wireguard.robot8
-rw-r--r--resources/templates/telemetry/bpf_runtime.yaml673
-rw-r--r--resources/templates/telemetry/perf_stat_runtime.yaml142
-rw-r--r--resources/templates/vm/init.sh1
-rw-r--r--resources/tools/dash/app/pal/news/tables.py85
-rw-r--r--resources/tools/dash/app/pal/static/dist/css/bootstrap.min.css12
-rw-r--r--resources/tools/dash/app/pal/templates/news_layout.jinja217
-rw-r--r--resources/tools/dash/app/pal/templates/stats_layout.jinja217
-rw-r--r--resources/tools/dash/app/pal/templates/trending_layout.jinja217
-rw-r--r--resources/tools/dash/app/requirements.txt39
-rw-r--r--resources/tools/presentation/generator_tables.py16
-rw-r--r--resources/tools/presentation/input_data_parser.py1187
-rw-r--r--resources/tools/presentation/pal.py100
-rw-r--r--resources/tools/presentation/requirements.txt13
-rw-r--r--resources/tools/presentation/specifications/report/data_sets.yaml1597
-rw-r--r--resources/tools/presentation/specifications/report/elements.yaml8953
-rw-r--r--resources/tools/presentation/specifications/report/environment.yaml18
-rw-r--r--resources/tools/presentation/specifications/trending/environment.yaml14
-rw-r--r--resources/tools/presentation/sphinx_conf/report/conf.py133
-rwxr-xr-xresources/tools/telemetry/__main__.py4
-rw-r--r--resources/tools/telemetry/bundle_bpf.py19
-rw-r--r--resources/tools/telemetry/bundle_perf_stat.py109
-rw-r--r--resources/tools/telemetry/constants.py5
-rw-r--r--resources/tools/telemetry/metrics.py4
-rw-r--r--resources/tools/telemetry/serializer.py2
-rw-r--r--tests/vpp/perf/__init__.robot4
-rw-r--r--tests/vpp/perf/crypto/10ge2p1x710-ethip4ipsec10000tnlhwasync-ip4base-policy-aes256gcm-ndrpdr.robot172
-rw-r--r--tests/vpp/perf/crypto/10ge2p1x710-ethip4ipsec10000tnlhwasync-ip4base-policy-fastpath-aes256gcm-ndrpdr.robot173
-rw-r--r--tests/vpp/perf/crypto/10ge2p1x710-ethip4ipsec10000tnlsw-ip4base-policy-aes256gcm-ndrpdr.robot175
-rw-r--r--tests/vpp/perf/crypto/10ge2p1x710-ethip4ipsec10000tnlsw-ip4base-policy-fastpath-aes256gcm-ndrpdr.robot176
-rw-r--r--tests/vpp/perf/crypto/10ge2p1x710-ethip4ipsec1000tnlhw-ip4base-int-aes128cbc-hmac512sha-ndrpdr.robot4
-rw-r--r--tests/vpp/perf/crypto/10ge2p1x710-ethip4ipsec1000tnlhw-ip4base-int-aes128gcm-ndrpdr.robot4
-rw-r--r--tests/vpp/perf/crypto/10ge2p1x710-ethip4ipsec1000tnlhw-ip4base-int-aes256gcm-ndrpdr.robot4
-rw-r--r--tests/vpp/perf/crypto/10ge2p1x710-ethip4ipsec1000tnlhw-ip4base-policy-aes256gcm-ndrpdr.robot2
-rw-r--r--tests/vpp/perf/crypto/10ge2p1x710-ethip4ipsec1000tnlhwasync-ip4base-int-aes128cbc-hmac512sha-ndrpdr.robot6
-rw-r--r--tests/vpp/perf/crypto/10ge2p1x710-ethip4ipsec1000tnlhwasync-ip4base-int-aes128gcm-ndrpdr.robot6
-rw-r--r--tests/vpp/perf/crypto/10ge2p1x710-ethip4ipsec1000tnlhwasync-ip4base-int-aes256gcm-ndrpdr.robot6
-rw-r--r--tests/vpp/perf/crypto/10ge2p1x710-ethip4ipsec1000tnlhwasync-ip4base-policy-aes256gcm-ndrpdr.robot2
-rw-r--r--tests/vpp/perf/crypto/10ge2p1x710-ethip4ipsec1tnlhw-ip4base-int-aes128cbc-hmac512sha-ndrpdr.robot4
-rw-r--r--tests/vpp/perf/crypto/10ge2p1x710-ethip4ipsec1tnlhw-ip4base-int-aes128gcm-ndrpdr.robot4
-rw-r--r--tests/vpp/perf/crypto/10ge2p1x710-ethip4ipsec1tnlhw-ip4base-int-aes256gcm-ndrpdr.robot4
-rw-r--r--tests/vpp/perf/crypto/10ge2p1x710-ethip4ipsec1tnlhw-ip4base-policy-aes256gcm-ndrpdr.robot2
-rw-r--r--tests/vpp/perf/crypto/10ge2p1x710-ethip4ipsec1tnlhwasync-ip4base-int-aes128cbc-hmac512sha-ndrpdr.robot6
-rw-r--r--tests/vpp/perf/crypto/10ge2p1x710-ethip4ipsec1tnlhwasync-ip4base-int-aes128gcm-ndrpdr.robot6
-rw-r--r--tests/vpp/perf/crypto/10ge2p1x710-ethip4ipsec1tnlhwasync-ip4base-int-aes256gcm-ndrpdr.robot6
-rw-r--r--tests/vpp/perf/crypto/10ge2p1x710-ethip4ipsec1tnlhwasync-ip4base-policy-aes256gcm-ndrpdr.robot2
-rw-r--r--tests/vpp/perf/crypto/10ge2p1x710-ethip4ipsec4tnlhwasync-ip4base-int-aes128cbc-hmac512sha-ndrpdr.robot6
-rw-r--r--tests/vpp/perf/crypto/10ge2p1x710-ethip4ipsec4tnlhwasync-ip4base-int-aes128gcm-ndrpdr.robot6
-rw-r--r--tests/vpp/perf/crypto/10ge2p1x710-ethip4ipsec4tnlhwasync-ip4base-int-aes256gcm-ndrpdr.robot6
-rw-r--r--tests/vpp/perf/crypto/2n1l-10ge2p1x710-ethip4ipsec1000tnlhwasync-ip4base-int-aes128cbc-hmac512sha-udir-ndrpdr.robot4
-rw-r--r--tests/vpp/perf/crypto/2n1l-10ge2p1x710-ethip4ipsec1000tnlhwasync-ip4base-int-aes128gcm-udir-ndrpdr.robot4
-rw-r--r--tests/vpp/perf/crypto/2n1l-10ge2p1x710-ethip4ipsec1000tnlhwasync-ip4base-int-aes256gcm-udir-ndrpdr.robot4
-rw-r--r--tests/vpp/perf/crypto/2n1l-10ge2p1x710-ethip4ipsec1tnlhwasync-ip4base-int-aes128cbc-hmac512sha-udir-ndrpdr.robot4
-rw-r--r--tests/vpp/perf/crypto/2n1l-10ge2p1x710-ethip4ipsec1tnlhwasync-ip4base-int-aes128gcm-udir-ndrpdr.robot4
-rw-r--r--tests/vpp/perf/crypto/2n1l-10ge2p1x710-ethip4ipsec1tnlhwasync-ip4base-int-aes256gcm-udir-ndrpdr.robot4
-rw-r--r--tests/vpp/perf/crypto/2n1l-10ge2p1x710-ethip4ipsec4tnlhwasync-ip4base-int-aes128cbc-hmac512sha-udir-ndrpdr.robot4
-rw-r--r--tests/vpp/perf/crypto/2n1l-10ge2p1x710-ethip4ipsec4tnlhwasync-ip4base-int-aes128gcm-udir-ndrpdr.robot4
-rw-r--r--tests/vpp/perf/crypto/2n1l-10ge2p1x710-ethip4ipsec4tnlhwasync-ip4base-int-aes256gcm-udir-ndrpdr.robot4
-rw-r--r--tests/vpp/perf/ip4_tunnels/10ge2p1x710-ethip4udpwireguard1000tnlhwasync-ip4base-ndrpdr.robot170
-rw-r--r--tests/vpp/perf/ip4_tunnels/10ge2p1x710-ethip4udpwireguard1000tnlsw-ip4base-ndrpdr.robot169
-rw-r--r--tests/vpp/perf/ip4_tunnels/10ge2p1x710-ethip4udpwireguard100tnlhwasync-ip4base-ndrpdr.robot170
-rw-r--r--tests/vpp/perf/ip4_tunnels/10ge2p1x710-ethip4udpwireguard100tnlsw-ip4base-ndrpdr.robot169
-rw-r--r--tests/vpp/perf/ip4_tunnels/10ge2p1x710-ethip4udpwireguard1tnlhwasync-ip4base-ndrpdr.robot170
-rw-r--r--tests/vpp/perf/ip4_tunnels/10ge2p1x710-ethip4udpwireguard1tnlsw-ip4base-ndrpdr.robot8
-rw-r--r--tests/vpp/perf/ip4_tunnels/10ge2p1x710-ethip4udpwireguard2tnlhwasync-ip4base-ndrpdr.robot170
-rw-r--r--tests/vpp/perf/ip4_tunnels/10ge2p1x710-ethip4udpwireguard2tnlsw-ip4base-ndrpdr.robot169
-rw-r--r--tests/vpp/perf/ip4_tunnels/10ge2p1x710-ethip4udpwireguard4tnlhwasync-ip4base-ndrpdr.robot170
-rw-r--r--tests/vpp/perf/ip4_tunnels/10ge2p1x710-ethip4udpwireguard4tnlsw-ip4base-ndrpdr.robot169
-rw-r--r--tests/vpp/perf/ip4_tunnels/10ge2p1x710-ethip4udpwireguard8tnlhwasync-ip4base-ndrpdr.robot170
-rw-r--r--tests/vpp/perf/ip4_tunnels/10ge2p1x710-ethip4udpwireguard8tnlsw-ip4base-ndrpdr.robot169
-rw-r--r--topologies/available/lf_2n_clx_testbed27.yaml64
-rw-r--r--topologies/available/lf_2n_clx_testbed28.yaml64
-rw-r--r--topologies/available/lf_2n_clx_testbed29.yaml64
-rw-r--r--topologies/available/lf_3n_snr_testbed39.yaml134
-rw-r--r--topologies/disabled/lf_2n_skx_testbed21.yaml (renamed from topologies/available/lf_2n_skx_testbed21.yaml)0
-rw-r--r--topologies/disabled/lf_2n_skx_testbed22.yaml (renamed from topologies/available/lf_2n_skx_testbed22.yaml)0
-rw-r--r--topologies/disabled/lf_2n_skx_testbed23.yaml (renamed from topologies/available/lf_2n_skx_testbed23.yaml)0
-rw-r--r--topologies/disabled/lf_3n_skx_testbed31.yaml (renamed from topologies/available/lf_3n_skx_testbed31.yaml)0
-rw-r--r--topologies/disabled/lf_3n_skx_testbed32.yaml (renamed from topologies/available/lf_3n_skx_testbed32.yaml)0
1218 files changed, 25699 insertions, 58434 deletions
diff --git a/.gitignore b/.gitignore
index 5df788a0b7..a659a44d85 100644
--- a/.gitignore
+++ b/.gitignore
@@ -27,4 +27,6 @@ report.html
.idea
.vscode
*.raw.json
-*.info.json \ No newline at end of file
+*.info.json
+.webassets-cache
+bootstrap.css \ No newline at end of file
diff --git a/DPDK_VPP_VER b/DPDK_VPP_VER
index 3d4b13728a..5a8851d1ae 100644
--- a/DPDK_VPP_VER
+++ b/DPDK_VPP_VER
@@ -1 +1 @@
-dpdk-22.03
+dpdk-22.07
diff --git a/GPL/traffic_profiles/trex/trex-stl-3n-ethip4-ip4src1000ip4dst1000.py b/GPL/traffic_profiles/trex/trex-stl-3n-ethip4-ip4src1000ip4dst1000.py
new file mode 100644
index 0000000000..667d4eccdc
--- /dev/null
+++ b/GPL/traffic_profiles/trex/trex-stl-3n-ethip4-ip4src1000ip4dst1000.py
@@ -0,0 +1,165 @@
+# Copyright (c) 2022 Intel and/or its affiliates.
+#
+# SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
+#
+# Licensed under the Apache License 2.0 or
+# GNU General Public License v2.0 or later; you may not use this file
+# except in compliance with one of these Licenses. You
+# may obtain a copy of the Licenses at:
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+# https://www.gnu.org/licenses/old-licenses/gpl-2.0-standalone.html
+#
+# Note: If this file is linked with Scapy, which is GPLv2+, your use of it
+# must be under GPLv2+. If at any point in the future it is no longer linked
+# with Scapy (or other GPLv2+ licensed software), you are free to choose
+# Apache 2.
+#
+# 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.
+
+"""Stream profile for T-rex traffic generator.
+
+Stream profile:
+ - Two streams sent in directions 0 --> 1 and 1 --> 0 at the same time.
+ - Packet: ETH / IP /
+ - Direction 0 --> 1:
+ - Source IP address range: 10.0.0.0 - 10.3.231.0
+ - Destination IP address range: 20.0.0.0 - 20.3.231.0
+ - Direction 1 --> 0:
+ - Source IP address range: 20.0.0.0 - 20.3.231.0
+ - Destination IP address range: 10.0.0.0 - 10.3.231.0
+"""
+
+from trex.stl.api import *
+from profile_trex_stateless_base_class import TrafficStreamsBaseClass
+
+class TrafficStreams(TrafficStreamsBaseClass):
+ """Stream profile."""
+
+ def __init__(self):
+ """Initialization and setting of streams' parameters."""
+
+ super(TrafficStreamsBaseClass, self).__init__()
+
+ # IPs used in packet headers.
+ self.p1_src_start_ip = u"10.0.0.0"
+ self.p1_src_end_ip = u"10.3.231.0"
+
+ self.p1_dst_start_ip = u"20.0.0.0"
+ self.p1_dst_end_ip = u"20.3.231.0"
+
+ self.p2_src_start_ip = u"20.0.0.0"
+ self.p2_src_end_ip = u"20.3.231.0"
+
+ self.p2_dst_start_ip = u"10.0.0.0"
+ self.p2_dst_end_ip = u"10.3.231.0"
+
+ def define_packets(self):
+ """Defines the packets to be sent from the traffic generator.
+
+ Packet definition: | ETH | IP |
+
+ :returns: Packets to be sent from the traffic generator.
+ :rtype: tuple
+ """
+
+ # Direction 0 --> 1
+ base_pkt_a = (
+ Ether() /
+ IP(
+ src=self.p1_src_start_ip,
+ dst=self.p1_dst_start_ip,
+ proto=61
+ )
+ )
+ # Direction 1 --> 0
+ base_pkt_b = (
+ Ether() /
+ IP(
+ src=self.p2_src_start_ip,
+ dst=self.p2_dst_start_ip,
+ proto=61
+ )
+ )
+
+ # Direction 0 --> 1
+ vm1 = STLScVmRaw(
+ [
+ STLVmFlowVar(
+ name=u"ip_src",
+ min_value=self.p1_src_start_ip,
+ max_value=self.p1_src_end_ip,
+ size=4,
+ step=256,
+ op=u"inc"
+ ),
+ STLVmWrFlowVar(
+ fv_name=u"ip_src",
+ pkt_offset=u"IP.src"
+ ),
+ STLVmFlowVar(
+ name=u"ip_dst",
+ min_value=self.p1_dst_start_ip,
+ max_value=self.p1_dst_end_ip,
+ size=4,
+ step=256,
+ op=u"inc"
+ ),
+ STLVmWrFlowVar(
+ fv_name=u"ip_dst",
+ pkt_offset=u"IP.dst"
+ ),
+ STLVmFixIpv4(
+ offset=u"IP"
+ )
+ ]
+ )
+ # Direction 1 --> 0
+ vm2 = STLScVmRaw(
+ [
+ STLVmFlowVar(
+ name=u"ip_src",
+ min_value=self.p2_src_start_ip,
+ max_value=self.p2_src_end_ip,
+ size=4,
+ step=256,
+ op=u"inc"
+ ),
+ STLVmWrFlowVar(
+ fv_name=u"ip_src",
+ pkt_offset=u"IP.src"
+ ),
+ STLVmFlowVar(
+ name=u"ip_dst",
+ min_value=self.p2_dst_start_ip,
+ max_value=self.p2_dst_end_ip,
+ size=4,
+ step=256,
+ op=u"inc"
+ ),
+ STLVmWrFlowVar(
+ fv_name=u"ip_dst",
+ pkt_offset=u"IP.dst"
+ ),
+ STLVmFixIpv4(
+ offset=u"IP"
+ )
+ ]
+ )
+
+ return base_pkt_a, base_pkt_b, vm1, vm2
+
+
+def register():
+ """Register this traffic profile to T-rex.
+
+ Do not change this function.
+
+ :returns: Traffic streams.
+ :rtype: Object
+ """
+ return TrafficStreams()
diff --git a/GPL/traffic_profiles/trex/trex-stl-3n-ethip4-ip4src100ip4dst100.py b/GPL/traffic_profiles/trex/trex-stl-3n-ethip4-ip4src100ip4dst100.py
new file mode 100644
index 0000000000..8d0950caed
--- /dev/null
+++ b/GPL/traffic_profiles/trex/trex-stl-3n-ethip4-ip4src100ip4dst100.py
@@ -0,0 +1,165 @@
+# Copyright (c) 2022 Intel and/or its affiliates.
+#
+# SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
+#
+# Licensed under the Apache License 2.0 or
+# GNU General Public License v2.0 or later; you may not use this file
+# except in compliance with one of these Licenses. You
+# may obtain a copy of the Licenses at:
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+# https://www.gnu.org/licenses/old-licenses/gpl-2.0-standalone.html
+#
+# Note: If this file is linked with Scapy, which is GPLv2+, your use of it
+# must be under GPLv2+. If at any point in the future it is no longer linked
+# with Scapy (or other GPLv2+ licensed software), you are free to choose
+# Apache 2.
+#
+# 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.
+
+"""Stream profile for T-rex traffic generator.
+
+Stream profile:
+ - Two streams sent in directions 0 --> 1 and 1 --> 0 at the same time.
+ - Packet: ETH / IP /
+ - Direction 0 --> 1:
+ - Source IP address range: 10.0.0.0 - 10.0.99.0
+ - Destination IP address range: 20.0.0.0 - 20.0.99.0
+ - Direction 1 --> 0:
+ - Source IP address range: 20.0.0.0 - 20.0.99.0
+ - Destination IP address range: 10.0.0.0 - 10.0.99.0
+"""
+
+from trex.stl.api import *
+from profile_trex_stateless_base_class import TrafficStreamsBaseClass
+
+class TrafficStreams(TrafficStreamsBaseClass):
+ """Stream profile."""
+
+ def __init__(self):
+ """Initialization and setting of streams' parameters."""
+
+ super(TrafficStreamsBaseClass, self).__init__()
+
+ # IPs used in packet headers.
+ self.p1_src_start_ip = u"10.0.0.0"
+ self.p1_src_end_ip = u"10.0.99.0"
+
+ self.p1_dst_start_ip = u"20.0.0.0"
+ self.p1_dst_end_ip = u"20.0.99.0"
+
+ self.p2_src_start_ip = u"20.0.0.0"
+ self.p2_src_end_ip = u"20.0.99.0"
+
+ self.p2_dst_start_ip = u"10.0.0.0"
+ self.p2_dst_end_ip = u"10.0.99.0"
+
+ def define_packets(self):
+ """Defines the packets to be sent from the traffic generator.
+
+ Packet definition: | ETH | IP |
+
+ :returns: Packets to be sent from the traffic generator.
+ :rtype: tuple
+ """
+
+ # Direction 0 --> 1
+ base_pkt_a = (
+ Ether() /
+ IP(
+ src=self.p1_src_start_ip,
+ dst=self.p1_dst_start_ip,
+ proto=61
+ )
+ )
+ # Direction 1 --> 0
+ base_pkt_b = (
+ Ether() /
+ IP(
+ src=self.p2_src_start_ip,
+ dst=self.p2_dst_start_ip,
+ proto=61
+ )
+ )
+
+ # Direction 0 --> 1
+ vm1 = STLScVmRaw(
+ [
+ STLVmFlowVar(
+ name=u"ip_src",
+ min_value=self.p1_src_start_ip,
+ max_value=self.p1_src_end_ip,
+ size=4,
+ step=256,
+ op=u"inc"
+ ),
+ STLVmWrFlowVar(
+ fv_name=u"ip_src",
+ pkt_offset=u"IP.src"
+ ),
+ STLVmFlowVar(
+ name=u"ip_dst",
+ min_value=self.p1_dst_start_ip,
+ max_value=self.p1_dst_end_ip,
+ size=4,
+ step=256,
+ op=u"inc"
+ ),
+ STLVmWrFlowVar(
+ fv_name=u"ip_dst",
+ pkt_offset=u"IP.dst"
+ ),
+ STLVmFixIpv4(
+ offset=u"IP"
+ )
+ ]
+ )
+ # Direction 1 --> 0
+ vm2 = STLScVmRaw(
+ [
+ STLVmFlowVar(
+ name=u"ip_src",
+ min_value=self.p2_src_start_ip,
+ max_value=self.p2_src_end_ip,
+ size=4,
+ step=256,
+ op=u"inc"
+ ),
+ STLVmWrFlowVar(
+ fv_name=u"ip_src",
+ pkt_offset=u"IP.src"
+ ),
+ STLVmFlowVar(
+ name=u"ip_dst",
+ min_value=self.p2_dst_start_ip,
+ max_value=self.p2_dst_end_ip,
+ size=4,
+ step=256,
+ op=u"inc"
+ ),
+ STLVmWrFlowVar(
+ fv_name=u"ip_dst",
+ pkt_offset=u"IP.dst"
+ ),
+ STLVmFixIpv4(
+ offset=u"IP"
+ )
+ ]
+ )
+
+ return base_pkt_a, base_pkt_b, vm1, vm2
+
+
+def register():
+ """Register this traffic profile to T-rex.
+
+ Do not change this function.
+
+ :returns: Traffic streams.
+ :rtype: Object
+ """
+ return TrafficStreams()
diff --git a/GPL/traffic_profiles/trex/trex-stl-3n-ethip4-ip4src1ip4dst1.py b/GPL/traffic_profiles/trex/trex-stl-3n-ethip4-ip4src1ip4dst1.py
new file mode 100644
index 0000000000..77a2f845c6
--- /dev/null
+++ b/GPL/traffic_profiles/trex/trex-stl-3n-ethip4-ip4src1ip4dst1.py
@@ -0,0 +1,95 @@
+# Copyright (c) 2022 Intel and/or its affiliates.
+#
+# SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
+#
+# Licensed under the Apache License 2.0 or
+# GNU General Public License v2.0 or later; you may not use this file
+# except in compliance with one of these Licenses. You
+# may obtain a copy of the Licenses at:
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+# https://www.gnu.org/licenses/old-licenses/gpl-2.0-standalone.html
+#
+# Note: If this file is linked with Scapy, which is GPLv2+, your use of it
+# must be under GPLv2+. If at any point in the future it is no longer linked
+# with Scapy (or other GPLv2+ licensed software), you are free to choose
+# Apache 2.
+#
+# 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.
+
+"""Stream profile for T-rex traffic generator.
+
+Stream profile:
+ - Two streams sent in directions 0 --> 1 and 1 --> 0 at the same time.
+ - Packet: ETH / IP /
+ - Direction 0 --> 1:
+ - Source IP address range: 10.0.0.0
+ - Destination IP address range: 20.0.0.0
+ - Direction 1 --> 0:
+ - Source IP address range: 20.0.0.0
+ - Destination IP address range: 10.0.0.0
+"""
+
+from trex.stl.api import *
+from profile_trex_stateless_base_class import TrafficStreamsBaseClass
+
+
+class TrafficStreams(TrafficStreamsBaseClass):
+ """Stream profile."""
+
+ def __init__(self):
+ """Initialization and setting of streams' parameters."""
+
+ super(TrafficStreamsBaseClass, self).__init__()
+
+ # IPs used in packet headers.
+ self.p1_src_ip = u"10.0.0.0"
+ self.p1_dst_ip = u"20.0.0.0"
+
+ self.p2_src_ip = u"20.0.0.0"
+ self.p2_dst_ip = u"10.0.0.0"
+
+ def define_packets(self):
+ """Defines the packets to be sent from the traffic generator.
+
+ Packet definition: | ETH | IP |
+
+ :returns: Packets to be sent from the traffic generator.
+ :rtype: tuple
+ """
+
+ # Direction 0 --> 1
+ base_pkt_a = (
+ Ether() /
+ IP(
+ src=self.p1_src_ip,
+ dst=self.p1_dst_ip,
+ proto=61
+ )
+ )
+ # Direction 1 --> 0
+ base_pkt_b = (
+ Ether() /
+ IP(
+ src=self.p2_src_ip,
+ dst=self.p2_dst_ip,
+ proto=61
+ )
+ )
+
+ return base_pkt_a, base_pkt_b, None, None
+
+
+def register():
+ """Register this traffic profile to T-rex.
+
+ Do not change this function.
+
+ :return: Traffic streams.
+ :rtype: Object
+ """
+ return TrafficStreams()
diff --git a/GPL/traffic_profiles/trex/trex-stl-3n-ethip4-ip4src2ip4dst2.py b/GPL/traffic_profiles/trex/trex-stl-3n-ethip4-ip4src2ip4dst2.py
new file mode 100644
index 0000000000..59bf2054a0
--- /dev/null
+++ b/GPL/traffic_profiles/trex/trex-stl-3n-ethip4-ip4src2ip4dst2.py
@@ -0,0 +1,165 @@
+# Copyright (c) 2022 Intel and/or its affiliates.
+#
+# SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
+#
+# Licensed under the Apache License 2.0 or
+# GNU General Public License v2.0 or later; you may not use this file
+# except in compliance with one of these Licenses. You
+# may obtain a copy of the Licenses at:
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+# https://www.gnu.org/licenses/old-licenses/gpl-2.0-standalone.html
+#
+# Note: If this file is linked with Scapy, which is GPLv2+, your use of it
+# must be under GPLv2+. If at any point in the future it is no longer linked
+# with Scapy (or other GPLv2+ licensed software), you are free to choose
+# Apache 2.
+#
+# 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.
+
+"""Stream profile for T-rex traffic generator.
+
+Stream profile:
+ - Two streams sent in directions 0 --> 1 and 1 --> 0 at the same time.
+ - Packet: ETH / IP /
+ - Direction 0 --> 1:
+ - Source IP address range: 10.0.0.0 - 10.0.1.0
+ - Destination IP address range: 20.0.0.0 - 20.0.1.0
+ - Direction 1 --> 0:
+ - Source IP address range: 20.0.0.0 - 20.0.1.0
+ - Destination IP address range: 10.0.0.0 - 10.0.1.0
+"""
+
+from trex.stl.api import *
+from profile_trex_stateless_base_class import TrafficStreamsBaseClass
+
+class TrafficStreams(TrafficStreamsBaseClass):
+ """Stream profile."""
+
+ def __init__(self):
+ """Initialization and setting of streams' parameters."""
+
+ super(TrafficStreamsBaseClass, self).__init__()
+
+ # IPs used in packet headers.
+ self.p1_src_start_ip = u"10.0.0.0"
+ self.p1_src_end_ip = u"10.0.1.0"
+
+ self.p1_dst_start_ip = u"20.0.0.0"
+ self.p1_dst_end_ip = u"20.0.1.0"
+
+ self.p2_src_start_ip = u"20.0.0.0"
+ self.p2_src_end_ip = u"20.0.1.0"
+
+ self.p2_dst_start_ip = u"10.0.0.0"
+ self.p2_dst_end_ip = u"10.0.1.0"
+
+ def define_packets(self):
+ """Defines the packets to be sent from the traffic generator.
+
+ Packet definition: | ETH | IP |
+
+ :returns: Packets to be sent from the traffic generator.
+ :rtype: tuple
+ """
+
+ # Direction 0 --> 1
+ base_pkt_a = (
+ Ether() /
+ IP(
+ src=self.p1_src_start_ip,
+ dst=self.p1_dst_start_ip,
+ proto=61
+ )
+ )
+ # Direction 1 --> 0
+ base_pkt_b = (
+ Ether() /
+ IP(
+ src=self.p2_src_start_ip,
+ dst=self.p2_dst_start_ip,
+ proto=61
+ )
+ )
+
+ # Direction 0 --> 1
+ vm1 = STLScVmRaw(
+ [
+ STLVmFlowVar(
+ name=u"ip_src",
+ min_value=self.p1_src_start_ip,
+ max_value=self.p1_src_end_ip,
+ size=4,
+ step=256,
+ op=u"inc"
+ ),
+ STLVmWrFlowVar(
+ fv_name=u"ip_src",
+ pkt_offset=u"IP.src"
+ ),
+ STLVmFlowVar(
+ name=u"ip_dst",
+ min_value=self.p1_dst_start_ip,
+ max_value=self.p1_dst_end_ip,
+ size=4,
+ step=256,
+ op=u"inc"
+ ),
+ STLVmWrFlowVar(
+ fv_name=u"ip_dst",
+ pkt_offset=u"IP.dst"
+ ),
+ STLVmFixIpv4(
+ offset=u"IP"
+ )
+ ]
+ )
+ # Direction 1 --> 0
+ vm2 = STLScVmRaw(
+ [
+ STLVmFlowVar(
+ name=u"ip_src",
+ min_value=self.p2_src_start_ip,
+ max_value=self.p2_src_end_ip,
+ size=4,
+ step=256,
+ op=u"inc"
+ ),
+ STLVmWrFlowVar(
+ fv_name=u"ip_src",
+ pkt_offset=u"IP.src"
+ ),
+ STLVmFlowVar(
+ name=u"ip_dst",
+ min_value=self.p2_dst_start_ip,
+ max_value=self.p2_dst_end_ip,
+ size=4,
+ step=256,
+ op=u"inc"
+ ),
+ STLVmWrFlowVar(
+ fv_name=u"ip_dst",
+ pkt_offset=u"IP.dst"
+ ),
+ STLVmFixIpv4(
+ offset=u"IP"
+ )
+ ]
+ )
+
+ return base_pkt_a, base_pkt_b, vm1, vm2
+
+
+def register():
+ """Register this traffic profile to T-rex.
+
+ Do not change this function.
+
+ :returns: Traffic streams.
+ :rtype: Object
+ """
+ return TrafficStreams()
diff --git a/GPL/traffic_profiles/trex/trex-stl-3n-ethip4-ip4src4ip4dst4.py b/GPL/traffic_profiles/trex/trex-stl-3n-ethip4-ip4src4ip4dst4.py
new file mode 100644
index 0000000000..7eb661d610
--- /dev/null
+++ b/GPL/traffic_profiles/trex/trex-stl-3n-ethip4-ip4src4ip4dst4.py
@@ -0,0 +1,165 @@
+# Copyright (c) 2022 Intel and/or its affiliates.
+#
+# SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
+#
+# Licensed under the Apache License 2.0 or
+# GNU General Public License v2.0 or later; you may not use this file
+# except in compliance with one of these Licenses. You
+# may obtain a copy of the Licenses at:
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+# https://www.gnu.org/licenses/old-licenses/gpl-2.0-standalone.html
+#
+# Note: If this file is linked with Scapy, which is GPLv2+, your use of it
+# must be under GPLv2+. If at any point in the future it is no longer linked
+# with Scapy (or other GPLv2+ licensed software), you are free to choose
+# Apache 2.
+#
+# 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.
+
+"""Stream profile for T-rex traffic generator.
+
+Stream profile:
+ - Two streams sent in directions 0 --> 1 and 1 --> 0 at the same time.
+ - Packet: ETH / IP /
+ - Direction 0 --> 1:
+ - Source IP address range: 10.0.0.0 - 10.0.3.0
+ - Destination IP address range: 20.0.0.0 - 20.0.3.0
+ - Direction 1 --> 0:
+ - Source IP address range: 20.0.0.0 - 20.0.3.0
+ - Destination IP address range: 10.0.0.0 - 10.0.3.0
+"""
+
+from trex.stl.api import *
+from profile_trex_stateless_base_class import TrafficStreamsBaseClass
+
+class TrafficStreams(TrafficStreamsBaseClass):
+ """Stream profile."""
+
+ def __init__(self):
+ """Initialization and setting of streams' parameters."""
+
+ super(TrafficStreamsBaseClass, self).__init__()
+
+ # IPs used in packet headers.
+ self.p1_src_start_ip = u"10.0.0.0"
+ self.p1_src_end_ip = u"10.0.3.0"
+
+ self.p1_dst_start_ip = u"20.0.0.0"
+ self.p1_dst_end_ip = u"20.0.3.0"
+
+ self.p2_src_start_ip = u"20.0.0.0"
+ self.p2_src_end_ip = u"20.0.3.0"
+
+ self.p2_dst_start_ip = u"10.0.0.0"
+ self.p2_dst_end_ip = u"10.0.3.0"
+
+ def define_packets(self):
+ """Defines the packets to be sent from the traffic generator.
+
+ Packet definition: | ETH | IP |
+
+ :returns: Packets to be sent from the traffic generator.
+ :rtype: tuple
+ """
+
+ # Direction 0 --> 1
+ base_pkt_a = (
+ Ether() /
+ IP(
+ src=self.p1_src_start_ip,
+ dst=self.p1_dst_start_ip,
+ proto=61
+ )
+ )
+ # Direction 1 --> 0
+ base_pkt_b = (
+ Ether() /
+ IP(
+ src=self.p2_src_start_ip,
+ dst=self.p2_dst_start_ip,
+ proto=61
+ )
+ )
+
+ # Direction 0 --> 1
+ vm1 = STLScVmRaw(
+ [
+ STLVmFlowVar(
+ name=u"ip_src",
+ min_value=self.p1_src_start_ip,
+ max_value=self.p1_src_end_ip,
+ size=4,
+ step=256,
+ op=u"inc"
+ ),
+ STLVmWrFlowVar(
+ fv_name=u"ip_src",
+ pkt_offset=u"IP.src"
+ ),
+ STLVmFlowVar(
+ name=u"ip_dst",
+ min_value=self.p1_dst_start_ip,
+ max_value=self.p1_dst_end_ip,
+ size=4,
+ step=256,
+ op=u"inc"
+ ),
+ STLVmWrFlowVar(
+ fv_name=u"ip_dst",
+ pkt_offset=u"IP.dst"
+ ),
+ STLVmFixIpv4(
+ offset=u"IP"
+ )
+ ]
+ )
+ # Direction 1 --> 0
+ vm2 = STLScVmRaw(
+ [
+ STLVmFlowVar(
+ name=u"ip_src",
+ min_value=self.p2_src_start_ip,
+ max_value=self.p2_src_end_ip,
+ size=4,
+ step=256,
+ op=u"inc"
+ ),
+ STLVmWrFlowVar(
+ fv_name=u"ip_src",
+ pkt_offset=u"IP.src"
+ ),
+ STLVmFlowVar(
+ name=u"ip_dst",
+ min_value=self.p2_dst_start_ip,
+ max_value=self.p2_dst_end_ip,
+ size=4,
+ step=256,
+ op=u"inc"
+ ),
+ STLVmWrFlowVar(
+ fv_name=u"ip_dst",
+ pkt_offset=u"IP.dst"
+ ),
+ STLVmFixIpv4(
+ offset=u"IP"
+ )
+ ]
+ )
+
+ return base_pkt_a, base_pkt_b, vm1, vm2
+
+
+def register():
+ """Register this traffic profile to T-rex.
+
+ Do not change this function.
+
+ :returns: Traffic streams.
+ :rtype: Object
+ """
+ return TrafficStreams()
diff --git a/GPL/traffic_profiles/trex/trex-stl-3n-ethip4-ip4src8ip4dst8.py b/GPL/traffic_profiles/trex/trex-stl-3n-ethip4-ip4src8ip4dst8.py
new file mode 100644
index 0000000000..1db7715ca8
--- /dev/null
+++ b/GPL/traffic_profiles/trex/trex-stl-3n-ethip4-ip4src8ip4dst8.py
@@ -0,0 +1,165 @@
+# Copyright (c) 2022 Intel and/or its affiliates.
+#
+# SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
+#
+# Licensed under the Apache License 2.0 or
+# GNU General Public License v2.0 or later; you may not use this file
+# except in compliance with one of these Licenses. You
+# may obtain a copy of the Licenses at:
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+# https://www.gnu.org/licenses/old-licenses/gpl-2.0-standalone.html
+#
+# Note: If this file is linked with Scapy, which is GPLv2+, your use of it
+# must be under GPLv2+. If at any point in the future it is no longer linked
+# with Scapy (or other GPLv2+ licensed software), you are free to choose
+# Apache 2.
+#
+# 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.
+
+"""Stream profile for T-rex traffic generator.
+
+Stream profile:
+ - Two streams sent in directions 0 --> 1 and 1 --> 0 at the same time.
+ - Packet: ETH / IP /
+ - Direction 0 --> 1:
+ - Source IP address range: 10.0.0.0 - 10.0.7.0
+ - Destination IP address range: 20.0.0.0 - 20.0.7.0
+ - Direction 1 --> 0:
+ - Source IP address range: 20.0.0.0 - 20.0.7.0
+ - Destination IP address range: 10.0.0.0 - 10.0.7.0
+"""
+
+from trex.stl.api import *
+from profile_trex_stateless_base_class import TrafficStreamsBaseClass
+
+class TrafficStreams(TrafficStreamsBaseClass):
+ """Stream profile."""
+
+ def __init__(self):
+ """Initialization and setting of streams' parameters."""
+
+ super(TrafficStreamsBaseClass, self).__init__()
+
+ # IPs used in packet headers.
+ self.p1_src_start_ip = u"10.0.0.0"
+ self.p1_src_end_ip = u"10.0.7.0"
+
+ self.p1_dst_start_ip = u"20.0.0.0"
+ self.p1_dst_end_ip = u"20.0.7.0"
+
+ self.p2_src_start_ip = u"20.0.0.0"
+ self.p2_src_end_ip = u"20.0.7.0"
+
+ self.p2_dst_start_ip = u"10.0.0.0"
+ self.p2_dst_end_ip = u"10.0.7.0"
+
+ def define_packets(self):
+ """Defines the packets to be sent from the traffic generator.
+
+ Packet definition: | ETH | IP |
+
+ :returns: Packets to be sent from the traffic generator.
+ :rtype: tuple
+ """
+
+ # Direction 0 --> 1
+ base_pkt_a = (
+ Ether() /
+ IP(
+ src=self.p1_src_start_ip,
+ dst=self.p1_dst_start_ip,
+ proto=61
+ )
+ )
+ # Direction 1 --> 0
+ base_pkt_b = (
+ Ether() /
+ IP(
+ src=self.p2_src_start_ip,
+ dst=self.p2_dst_start_ip,
+ proto=61
+ )
+ )
+
+ # Direction 0 --> 1
+ vm1 = STLScVmRaw(
+ [
+ STLVmFlowVar(
+ name=u"ip_src",
+ min_value=self.p1_src_start_ip,
+ max_value=self.p1_src_end_ip,
+ size=4,
+ step=256,
+ op=u"inc"
+ ),
+ STLVmWrFlowVar(
+ fv_name=u"ip_src",
+ pkt_offset=u"IP.src"
+ ),
+ STLVmFlowVar(
+ name=u"ip_dst",
+ min_value=self.p1_dst_start_ip,
+ max_value=self.p1_dst_end_ip,
+ size=4,
+ step=256,
+ op=u"inc"
+ ),
+ STLVmWrFlowVar(
+ fv_name=u"ip_dst",
+ pkt_offset=u"IP.dst"
+ ),
+ STLVmFixIpv4(
+ offset=u"IP"
+ )
+ ]
+ )
+ # Direction 1 --> 0
+ vm2 = STLScVmRaw(
+ [
+ STLVmFlowVar(
+ name=u"ip_src",
+ min_value=self.p2_src_start_ip,
+ max_value=self.p2_src_end_ip,
+ size=4,
+ step=256,
+ op=u"inc"
+ ),
+ STLVmWrFlowVar(
+ fv_name=u"ip_src",
+ pkt_offset=u"IP.src"
+ ),
+ STLVmFlowVar(
+ name=u"ip_dst",
+ min_value=self.p2_dst_start_ip,
+ max_value=self.p2_dst_end_ip,
+ size=4,
+ step=256,
+ op=u"inc"
+ ),
+ STLVmWrFlowVar(
+ fv_name=u"ip_dst",
+ pkt_offset=u"IP.dst"
+ ),
+ STLVmFixIpv4(
+ offset=u"IP"
+ )
+ ]
+ )
+
+ return base_pkt_a, base_pkt_b, vm1, vm2
+
+
+def register():
+ """Register this traffic profile to T-rex.
+
+ Do not change this function.
+
+ :returns: Traffic streams.
+ :rtype: Object
+ """
+ return TrafficStreams()
diff --git a/PyPI/jumpavg/README.rst b/PyPI/jumpavg/README.rst
index 3161988f69..f66ea9d39b 100644
--- a/PyPI/jumpavg/README.rst
+++ b/PyPI/jumpavg/README.rst
@@ -25,6 +25,11 @@ Change log
TODO: Move into separate file?
+0.3.0: Considerable speedup by avoiding unneeded copy. Dataclasses used.
+ Mostly API compatible, but repr looks different.
+
+0.2.0: API incompatible changes. Targeted to Python 3 now.
+
0.1.3: Changed stdev computation to avoid negative variance due to rounding errors.
0.1.2: First version published in PyPI.
diff --git a/PyPI/jumpavg/setup.py b/PyPI/jumpavg/setup.py
index 28ddfcf0b1..129277a26e 100644
--- a/PyPI/jumpavg/setup.py
+++ b/PyPI/jumpavg/setup.py
@@ -16,7 +16,7 @@ with open(path.join(here, u"README.rst"), encoding=u"utf-8") as f:
setup(
name=u"jumpavg",
- version=u"0.2.0", # This is currently the only place listing the version.
+ version=u"0.3.0", # This is currently the only place listing the version.
description=(
u"Library for locating changes in time series by grouping results."
),
@@ -36,12 +36,12 @@ setup(
u"License :: OSI Approved :: Apache Software License",
u"Natural Language :: English",
# TODO: Test which Python versions is the code compatible with.
- u"Programming Language :: Python :: 2.7",
+ u"Programming Language :: Python :: 3.8",
u"Topic :: Scientific/Engineering :: Information Analysis"
],
keywords=u"progression regression anomaly detection statistics bits",
packages=find_packages(exclude=[]),
- python_requires="~=3.6",
+ python_requires="~=3.8",
install_requires=[],
# TODO: Include simulator and tests.
extras_require={
diff --git a/VPP_DEVICE_IMAGE_UBUNTU_JAMMY b/VPP_DEVICE_IMAGE_UBUNTU_JAMMY
new file mode 100644
index 0000000000..0531111878
--- /dev/null
+++ b/VPP_DEVICE_IMAGE_UBUNTU_JAMMY
@@ -0,0 +1 @@
+csit_sut-ubuntu2204:local \ No newline at end of file
diff --git a/VPP_DEVICE_IMAGE_UBUNTU_JAMMY_ARM b/VPP_DEVICE_IMAGE_UBUNTU_JAMMY_ARM
new file mode 100644
index 0000000000..5ef36ca057
--- /dev/null
+++ b/VPP_DEVICE_IMAGE_UBUNTU_JAMMY_ARM
@@ -0,0 +1 @@
+csit_sut-ubuntu2204:local
diff --git a/VPP_STABLE_VER_UBUNTU_FOCAL b/VPP_STABLE_VER_UBUNTU_FOCAL
index 4351f7015e..d37026c17e 100644
--- a/VPP_STABLE_VER_UBUNTU_FOCAL
+++ b/VPP_STABLE_VER_UBUNTU_FOCAL
@@ -1 +1 @@
-22.10-rc0~88-g389aae573 \ No newline at end of file
+23.02-rc0~20-g1fb62c0bc \ No newline at end of file
diff --git a/VPP_STABLE_VER_UBUNTU_JAMMY b/VPP_STABLE_VER_UBUNTU_JAMMY
new file mode 100644
index 0000000000..d37026c17e
--- /dev/null
+++ b/VPP_STABLE_VER_UBUNTU_JAMMY
@@ -0,0 +1 @@
+23.02-rc0~20-g1fb62c0bc \ No newline at end of file
diff --git a/resources/tools/dash/Dockerfile b/csit.infra.dash/Dockerfile
index ee4ae1edd9..ee4ae1edd9 100644
--- a/resources/tools/dash/Dockerfile
+++ b/csit.infra.dash/Dockerfile
diff --git a/resources/tools/dash/app/.ebextensions/cron-linux.config b/csit.infra.dash/app/.ebextensions/cron-linux.config
index ae8c33c814..ae8c33c814 100644
--- a/resources/tools/dash/app/.ebextensions/cron-linux.config
+++ b/csit.infra.dash/app/.ebextensions/cron-linux.config
diff --git a/resources/tools/dash/app/Procfile b/csit.infra.dash/app/Procfile
index c79d502390..c79d502390 100644
--- a/resources/tools/dash/app/Procfile
+++ b/csit.infra.dash/app/Procfile
diff --git a/resources/tools/dash/app/app.ini b/csit.infra.dash/app/app.ini
index 9608f7c38d..5484b5b9fc 100644
--- a/resources/tools/dash/app/app.ini
+++ b/csit.infra.dash/app/app.ini
@@ -1,8 +1,8 @@
[uwsgi]
-ini = :pal
+ini = :cdash
py-autoreload = 0
-[pal]
+[cdash]
module = wsgi:app
master-fifo = /tmp/masterfifo
lazy = True
@@ -17,4 +17,3 @@ master = true
http-socket = :5000
socket = /tmp/app.sock
chmod-socket = 666
-
diff --git a/resources/tools/dash/app/pal/__init__.py b/csit.infra.dash/app/cdash/__init__.py
index 0eb2a4e79e..20023ec157 100644
--- a/resources/tools/dash/app/pal/__init__.py
+++ b/csit.infra.dash/app/cdash/__init__.py
@@ -17,7 +17,7 @@
import logging
from flask import Flask
-from flask_assets import Environment
+from flask_assets import Environment, Bundle
from .utils.constants import Constants as C
@@ -25,17 +25,16 @@ from .utils.constants import Constants as C
def init_app():
"""Construct core Flask application with embedded Dash app.
"""
-
logging.basicConfig(
- format=u"%(asctime)s: %(levelname)s: %(message)s",
- datefmt=u"%Y/%m/%d %H:%M:%S",
- level=logging.INFO
+ format=C.LOG_FORMAT,
+ datefmt=C.LOG_DATE_FORMAT,
+ level=C.LOG_LEVEL
)
logging.info("Application started.")
app = Flask(__name__, instance_relative_config=False)
- app.config.from_object(u"config.Config")
+ app.config.from_object("config.Config")
with app.app_context():
# Import parts of our core Flask app.
@@ -44,6 +43,19 @@ def init_app():
assets = Environment()
assets.init_app(app)
+ # Compile static assets.
+ sass_bundle = Bundle(
+ "sass/lux.scss",
+ filters="libsass",
+ output="dist/css/bootstrap.css",
+ depends="**/*.scss",
+ extra={
+ "rel": "stylesheet"
+ }
+ )
+ assets.register("sass_all", sass_bundle)
+ sass_bundle.build()
+
# Set the time period for Trending
if C.TIME_PERIOD is None or C.TIME_PERIOD > C.MAX_TIME_PERIOD:
time_period = C.MAX_TIME_PERIOD
diff --git a/resources/tools/dash/app/pal/data/__init__.py b/csit.infra.dash/app/cdash/data/__init__.py
index 5692432123..5692432123 100644
--- a/resources/tools/dash/app/pal/data/__init__.py
+++ b/csit.infra.dash/app/cdash/data/__init__.py
diff --git a/resources/tools/dash/app/pal/data/data.py b/csit.infra.dash/app/cdash/data/data.py
index 77fd113a9c..77fd113a9c 100644
--- a/resources/tools/dash/app/pal/data/data.py
+++ b/csit.infra.dash/app/cdash/data/data.py
diff --git a/resources/tools/dash/app/pal/data/data.yaml b/csit.infra.dash/app/cdash/data/data.yaml
index 396f1b1638..396f1b1638 100644
--- a/resources/tools/dash/app/pal/data/data.yaml
+++ b/csit.infra.dash/app/cdash/data/data.yaml
diff --git a/resources/tools/dash/app/pal/debug.py b/csit.infra.dash/app/cdash/debug.py
index f0543820b1..9d46d2a111 100644
--- a/resources/tools/dash/app/pal/debug.py
+++ b/csit.infra.dash/app/cdash/debug.py
@@ -11,6 +11,9 @@
# See the License for the specific language governing permissions and
# limitations under the License.
+"""Debug class. Only for internal debugging puproses.
+"""
+
import logging
from data.data import Data
diff --git a/resources/tools/dash/app/pal/news/__init__.py b/csit.infra.dash/app/cdash/news/__init__.py
index 5692432123..5692432123 100644
--- a/resources/tools/dash/app/pal/news/__init__.py
+++ b/csit.infra.dash/app/cdash/news/__init__.py
diff --git a/resources/tools/dash/app/pal/news/layout.py b/csit.infra.dash/app/cdash/news/layout.py
index 73fabdf884..dfe6eba67a 100644
--- a/resources/tools/dash/app/pal/news/layout.py
+++ b/csit.infra.dash/app/cdash/news/layout.py
@@ -22,18 +22,15 @@ from flask import Flask
from dash import dcc
from dash import html
from dash import callback_context
-from dash import Input, Output, State
+from dash import Input, Output
from yaml import load, FullLoader, YAMLError
-from copy import deepcopy
from ..data.data import Data
from ..utils.constants import Constants as C
-from ..utils.utils import classify_anomalies, show_tooltip, gen_new_url, \
- get_ttypes, get_cadences, get_test_beds, get_job, generate_options, \
- set_job_params
+from ..utils.utils import classify_anomalies, show_tooltip, gen_new_url
from ..utils.url_processing import url_decode
from ..data.data import Data
-from .tables import table_news
+from .tables import table_summary
class Layout:
@@ -77,7 +74,7 @@ class Layout:
df_tst_info = pd.concat([data_mrr, data_ndrpdr], ignore_index=True)
# Prepare information for the control panel:
- jobs = sorted(list(df_tst_info["job"].unique()))
+ self._jobs = sorted(list(df_tst_info["job"].unique()))
d_job_info = {
"job": list(),
"dut": list(),
@@ -85,7 +82,7 @@ class Layout:
"cadence": list(),
"tbed": list()
}
- for job in jobs:
+ for job in self._jobs:
lst_job = job.split("-")
d_job_info["job"].append(job)
d_job_info["dut"].append(lst_job[1])
@@ -94,8 +91,6 @@ class Layout:
d_job_info["tbed"].append("-".join(lst_job[-2:]))
self.job_info = pd.DataFrame.from_dict(d_job_info)
- self._default = set_job_params(self.job_info, C.NEWS_DEFAULT_JOB)
-
# Pre-process the data:
def _create_test_name(test: str) -> str:
@@ -118,10 +113,10 @@ class Layout:
"regressions": list(),
"progressions": list()
}
- for job in jobs:
+ for job in self._jobs:
# Create lists of failed tests:
df_job = df_tst_info.loc[(df_tst_info["job"] == job)]
- last_build = max(df_job["build"].unique())
+ last_build = str(max(pd.to_numeric(df_job["build"].unique())))
df_build = df_job.loc[(df_job["build"] == last_build)]
tst_info["job"].append(job)
tst_info["build"].append(last_build)
@@ -254,7 +249,10 @@ class Layout:
f"{self._tooltip_file}\n{err}"
)
- self._default_tab_failed = table_news(self.data, self._default["job"])
+ self._default_period = C.NEWS_SHORT
+ self._default_active = (False, True, False)
+ self._default_table = \
+ table_summary(self._data, self._jobs, self._default_period)
# Callbacks:
if self._app is not None and hasattr(self, 'callbacks'):
@@ -264,14 +262,6 @@ class Layout:
def html_layout(self) -> dict:
return self._html_layout
- @property
- def data(self) -> pd.DataFrame:
- return self._data
-
- @property
- def default(self) -> dict:
- return self._default
-
def add_content(self):
"""Top level method which generated the web page.
@@ -289,8 +279,8 @@ class Layout:
if self.html_layout:
return html.Div(
id="div-main",
+ className="small",
children=[
- dcc.Store(id="control-panel"),
dcc.Location(id="url", refresh=False),
dbc.Row(
id="row-navbar",
@@ -334,14 +324,14 @@ class Layout:
children=[
dbc.NavItem(
dbc.NavLink(
- "Continuous Performance News",
+ C.NEWS_TITLE,
disabled=True,
external_link=True,
href="#"
)
)
],
- brand="Dashboard",
+ brand=C.BRAND,
brand_href="/",
brand_external_link=True,
class_name="p-2",
@@ -354,13 +344,12 @@ class Layout:
:returns: Column with the control panel.
:rtype: dbc.Col
"""
-
- return dbc.Col(
- id="col-controls",
- children=[
- self._add_ctrl_panel(),
- ],
- )
+ return dbc.Col([
+ html.Div(
+ children=self._add_ctrl_panel(),
+ className="sticky-top"
+ )
+ ])
def _add_plotting_col(self) -> dbc.Col:
"""Add column with tables. It is placed on the right side.
@@ -372,33 +361,37 @@ class Layout:
return dbc.Col(
id="col-plotting-area",
children=[
- dbc.Row( # Failed tests
- id="row-table-failed",
- class_name="g-0 p-2",
- children=self._default_tab_failed
- ),
- dbc.Row(
- class_name="g-0 p-2",
- align="center",
- justify="start",
+ dcc.Loading(
children=[
- dbc.InputGroup(
- class_name="me-1",
+ dbc.Row( # Failed tests
+ id="row-table",
+ class_name="g-0 p-2",
+ children=self._default_table
+ ),
+ dbc.Row(
+ class_name="g-0 p-2",
+ align="center",
+ justify="start",
children=[
- dbc.InputGroupText(
- style=C.URL_STYLE,
- children=show_tooltip(
- self._tooltips,
- "help-url", "URL",
- "input-url"
- )
- ),
- dbc.Input(
- id="input-url",
- readonly=True,
- type="url",
- style=C.URL_STYLE,
- value=""
+ dbc.InputGroup(
+ class_name="me-1",
+ children=[
+ dbc.InputGroupText(
+ style=C.URL_STYLE,
+ children=show_tooltip(
+ self._tooltips,
+ "help-url", "URL",
+ "input-url"
+ )
+ ),
+ dbc.Input(
+ id="input-url",
+ readonly=True,
+ type="url",
+ style=C.URL_STYLE,
+ value=""
+ )
+ ]
)
]
)
@@ -414,165 +407,45 @@ class Layout:
:returns: Control panel.
:rtype: dbc.Row
"""
- return dbc.Row(
- id="row-ctrl-panel",
- class_name="g-0",
- children=[
- dbc.Row(
- class_name="g-0 p-2",
- children=[
- dbc.Row(
- class_name="gy-1",
- children=[
- dbc.Label(
- class_name="p-0",
- children=show_tooltip(self._tooltips,
- "help-dut", "Device under Test")
- ),
- dbc.Row(
- dbc.RadioItems(
- id="ri-duts",
- inline=True,
- value=self.default["dut"],
- options=self.default["duts"]
- )
- )
- ]
- ),
- dbc.Row(
- class_name="gy-1",
- children=[
- dbc.Label(
- class_name="p-0",
- children=show_tooltip(self._tooltips,
- "help-ttype", "Test Type"),
- ),
- dbc.RadioItems(
- id="ri-ttypes",
- inline=True,
- value=self.default["ttype"],
- options=self.default["ttypes"]
- )
- ]
- ),
- dbc.Row(
- class_name="gy-1",
- children=[
- dbc.Label(
- class_name="p-0",
- children=show_tooltip(self._tooltips,
- "help-cadence", "Cadence"),
- ),
- dbc.RadioItems(
- id="ri-cadences",
- inline=True,
- value=self.default["cadence"],
- options=self.default["cadences"]
- )
- ]
- ),
- dbc.Row(
- class_name="gy-1",
- children=[
- dbc.Label(
- class_name="p-0",
- children=show_tooltip(self._tooltips,
- "help-tbed", "Test Bed"),
- ),
- dbc.Select(
- id="dd-tbeds",
- placeholder="Select a test bed...",
- value=self.default["tbed"],
- options=self.default["tbeds"]
- )
- ]
- ),
- dbc.Row(
- class_name="gy-1",
- children=[
- dbc.Alert(
- id="al-job",
- color="info",
- children=self.default["job"]
- )
- ]
- )
- ]
- )
- ]
- )
-
- class ControlPanel:
- """A class representing the control panel.
- """
-
- def __init__(self, panel: dict, default: dict) -> None:
- """Initialisation of the control pannel by default values. If
- particular values are provided (parameter "panel") they are set
- afterwards.
-
- :param panel: Custom values to be set to the control panel.
- :param default: Default values to be set to the control panel.
- :type panel: dict
- :type defaults: dict
- """
-
- self._defaults = {
- "ri-ttypes-options": default["ttypes"],
- "ri-cadences-options": default["cadences"],
- "dd-tbeds-options": default["tbeds"],
- "ri-duts-value": default["dut"],
- "ri-ttypes-value": default["ttype"],
- "ri-cadences-value": default["cadence"],
- "dd-tbeds-value": default["tbed"],
- "al-job-children": default["job"]
- }
- self._panel = deepcopy(self._defaults)
- if panel:
- for key in self._defaults:
- self._panel[key] = panel[key]
-
- def set(self, kwargs: dict) -> None:
- """Set the values of the Control panel.
-
- :param kwargs: key - value pairs to be set.
- :type kwargs: dict
- :raises KeyError: If the key in kwargs is not present in the Control
- panel.
- """
- for key, val in kwargs.items():
- if key in self._panel:
- self._panel[key] = val
- else:
- raise KeyError(f"The key {key} is not defined.")
-
- @property
- def defaults(self) -> dict:
- return self._defaults
-
- @property
- def panel(self) -> dict:
- return self._panel
-
- def get(self, key: str) -> any:
- """Returns the value of a key from the Control panel.
-
- :param key: The key which value should be returned.
- :type key: str
- :returns: The value of the key.
- :rtype: any
- :raises KeyError: If the key in kwargs is not present in the Control
- panel.
- """
- return self._panel[key]
-
- def values(self) -> list:
- """Returns the values from the Control panel as a list.
-
- :returns: The values from the Control panel.
- :rtype: list
- """
- return list(self._panel.values())
+ return [
+ dbc.Label(
+ class_name="g-0 p-1",
+ children=show_tooltip(self._tooltips,
+ "help-summary-period", "Window")
+ ),
+ dbc.Row(
+ class_name="g-0 p-1",
+ children=[
+ dbc.ButtonGroup(
+ id="bg-time-period",
+ children=[
+ dbc.Button(
+ id="period-last",
+ children="Last Run",
+ className="me-1",
+ outline=True,
+ color="info"
+ ),
+ dbc.Button(
+ id="period-short",
+ children=f"Last {C.NEWS_SHORT} Runs",
+ className="me-1",
+ outline=True,
+ active=True,
+ color="info"
+ ),
+ dbc.Button(
+ id="period-long",
+ children="All Runs",
+ className="me-1",
+ outline=True,
+ color="info"
+ )
+ ]
+ )
+ ]
+ )
+ ]
def callbacks(self, app):
"""Callbacks for the whole application.
@@ -582,46 +455,36 @@ class Layout:
"""
@app.callback(
- Output("control-panel", "data"), # Store
- Output("row-table-failed", "children"),
+ Output("row-table", "children"),
Output("input-url", "value"),
- Output("ri-ttypes", "options"),
- Output("ri-cadences", "options"),
- Output("dd-tbeds", "options"),
- Output("ri-duts", "value"),
- Output("ri-ttypes", "value"),
- Output("ri-cadences", "value"),
- Output("dd-tbeds", "value"),
- Output("al-job", "children"),
- State("control-panel", "data"), # Store
- Input("ri-duts", "value"),
- Input("ri-ttypes", "value"),
- Input("ri-cadences", "value"),
- Input("dd-tbeds", "value"),
+ Output("period-last", "active"),
+ Output("period-short", "active"),
+ Output("period-long", "active"),
+ Input("period-last", "n_clicks"),
+ Input("period-short", "n_clicks"),
+ Input("period-long", "n_clicks"),
Input("url", "href")
)
- def _update_application(cp_data: dict, dut: str, ttype: str,
- cadence:str, tbed: str, href: str) -> tuple:
+ def _update_application(btn_last: int, btn_short: int, btn_long: int,
+ href: str) -> tuple:
"""Update the application when the event is detected.
- :param cp_data: Current status of the control panel stored in
- browser.
- :param dut: Input - DUT name.
- :param ttype: Input - Test type.
- :param cadence: Input - The cadence of the job.
- :param tbed: Input - The test bed.
- :param href: Input - The URL provided by the browser.
- :type cp_data: dict
- :type dut: str
- :type ttype: str
- :type cadence: str
- :type tbed: str
- :type href: str
:returns: New values for web page elements.
:rtype: tuple
"""
- ctrl_panel = self.ControlPanel(cp_data, self.default)
+ _, _, _ = btn_last, btn_short, btn_long
+
+ periods = {
+ "period-last": C.NEWS_LAST,
+ "period-short": C.NEWS_SHORT,
+ "period-long": C.NEWS_LONG
+ }
+ actives = {
+ "period-last": (True, False, False),
+ "period-short": (False, True, False),
+ "period-long": (False, False, True)
+ }
# Parse the url:
parsed_url = url_decode(href)
@@ -631,77 +494,15 @@ class Layout:
url_params = None
trigger_id = callback_context.triggered[0]["prop_id"].split(".")[0]
- if trigger_id == "ri-duts":
- ttype_opts = generate_options(get_ttypes(self.job_info, dut))
- ttype_val = ttype_opts[0]["value"]
- cad_opts = generate_options(
- get_cadences(self.job_info, dut, ttype_val))
- cad_val = cad_opts[0]["value"]
- tbed_opts = generate_options(get_test_beds(
- self.job_info, dut, ttype_val, cad_val))
- tbed_val = tbed_opts[0]["value"]
- ctrl_panel.set({
- "ri-duts-value": dut,
- "ri-ttypes-options": ttype_opts,
- "ri-ttypes-value": ttype_val,
- "ri-cadences-options": cad_opts,
- "ri-cadences-value": cad_val,
- "dd-tbeds-options": tbed_opts,
- "dd-tbeds-value": tbed_val
- })
- elif trigger_id == "ri-ttypes":
- cad_opts = generate_options(get_cadences(
- self.job_info, ctrl_panel.get("ri-duts-value"), ttype))
- cad_val = cad_opts[0]["value"]
- tbed_opts = generate_options(get_test_beds(
- self.job_info, ctrl_panel.get("ri-duts-value"),
- ttype, cad_val))
- tbed_val = tbed_opts[0]["value"]
- ctrl_panel.set({
- "ri-ttypes-value": ttype,
- "ri-cadences-options": cad_opts,
- "ri-cadences-value": cad_val,
- "dd-tbeds-options": tbed_opts,
- "dd-tbeds-value": tbed_val
- })
- elif trigger_id == "ri-cadences":
- tbed_opts = generate_options(get_test_beds(
- self.job_info, ctrl_panel.get("ri-duts-value"),
- ctrl_panel.get("ri-ttypes-value"), cadence))
- tbed_val = tbed_opts[0]["value"]
- ctrl_panel.set({
- "ri-cadences-value": cadence,
- "dd-tbeds-options": tbed_opts,
- "dd-tbeds-value": tbed_val
- })
- elif trigger_id == "dd-tbeds":
- ctrl_panel.set({
- "dd-tbeds-value": tbed
- })
- elif trigger_id == "url":
- # TODO: Add verification
- if url_params:
- new_job = url_params.get("job", list())[0]
- if new_job:
- job_params = set_job_params(self.job_info, new_job)
- ctrl_panel = self.ControlPanel(None, job_params)
- else:
- ctrl_panel = self.ControlPanel(cp_data, self.default)
-
- job = get_job(
- self.job_info,
- ctrl_panel.get("ri-duts-value"),
- ctrl_panel.get("ri-ttypes-value"),
- ctrl_panel.get("ri-cadences-value"),
- ctrl_panel.get("dd-tbeds-value")
- )
- ctrl_panel.set({"al-job-children": job})
- tab_failed = table_news(self.data, job)
+ if trigger_id == "url" and url_params:
+ trigger_id = url_params.get("period", list())[0]
+
+ period = periods.get(trigger_id, self._default_period)
+ active = actives.get(trigger_id, self._default_active)
ret_val = [
- ctrl_panel.panel,
- tab_failed,
- gen_new_url(parsed_url, {"job": job})
+ table_summary(self._data, self._jobs, period),
+ gen_new_url(parsed_url, {"period": trigger_id})
]
- ret_val.extend(ctrl_panel.values())
+ ret_val.extend(active)
return ret_val
diff --git a/resources/tools/dash/app/pal/news/news.py b/csit.infra.dash/app/cdash/news/news.py
index a0d05f1483..362ee13052 100644
--- a/resources/tools/dash/app/pal/news/news.py
+++ b/csit.infra.dash/app/cdash/news/news.py
@@ -31,12 +31,13 @@ def init_news(server):
dash_app = dash.Dash(
server=server,
routes_pathname_prefix=C.NEWS_ROUTES_PATHNAME_PREFIX,
- external_stylesheets=C.EXTERNAL_STYLESHEETS
+ external_stylesheets=C.EXTERNAL_STYLESHEETS,
+ title=C.NEWS_TITLE
)
layout = Layout(
app=dash_app,
- html_layout_file=C.NEWS_HTML_LAYOUT_FILE,
+ html_layout_file=C.HTML_LAYOUT_FILE,
data_spec_file=C.DATA_SPEC_FILE,
tooltip_file=C.TOOLTIP_FILE,
)
diff --git a/csit.infra.dash/app/cdash/news/tables.py b/csit.infra.dash/app/cdash/news/tables.py
new file mode 100644
index 0000000000..7c0cc66eda
--- /dev/null
+++ b/csit.infra.dash/app/cdash/news/tables.py
@@ -0,0 +1,176 @@
+# Copyright (c) 2022 Cisco and/or its affiliates.
+# 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.
+
+"""The tables with news.
+"""
+
+import pandas as pd
+import dash_bootstrap_components as dbc
+
+from datetime import datetime, timedelta
+
+
+def _table_info(job_data: pd.DataFrame) -> dbc.Table:
+ """Generates table with info about the job.
+
+ :param job_data: Dataframe with information about the job.
+ :type job_data: pandas.DataFrame
+ :returns: Table with job info.
+ :rtype: dbc.Table
+ """
+ return dbc.Table.from_dataframe(
+ pd.DataFrame.from_dict(
+ {
+ "Job": job_data["job"],
+ "Last Build": job_data["build"],
+ "Date": job_data["start"],
+ "DUT": job_data["dut_type"],
+ "DUT Version": job_data["dut_version"],
+ "Hosts": ", ".join(job_data["hosts"].to_list()[0])
+ }
+ ),
+ bordered=True,
+ striped=True,
+ hover=True,
+ size="sm",
+ color="info"
+ )
+
+
+def _table_failed(job_data: pd.DataFrame, failed: list) -> dbc.Table:
+ """Generates table with failed tests from the last run of the job.
+
+ :param job_data: Dataframe with information about the job.
+ :param failed: List of failed tests.
+ :type job_data: pandas.DataFrame
+ :type failed: list
+ :returns: Table with fialed tests.
+ :rtype: dbc.Table
+ """
+ return dbc.Table.from_dataframe(
+ pd.DataFrame.from_dict(
+ {
+ (
+ f"Last Failed Tests on "
+ f"{job_data['start'].values[0]} ({len(failed)})"
+ ): failed
+ }
+ ),
+ bordered=True,
+ striped=True,
+ hover=True,
+ size="sm",
+ color="danger"
+ )
+
+
+def _table_gressions(itms: dict, color: str) -> dbc.Table:
+ """Generates table with regressions.
+
+ :param itms: Dictionary with items (regressions or progressions) and their
+ last occurence.
+ :param color: Color of the table.
+ :type regressions: dict
+ :type color: str
+ :returns: The table with regressions.
+ :rtype: dbc.Table
+ """
+ return dbc.Table.from_dataframe(
+ pd.DataFrame.from_dict(itms),
+ bordered=True,
+ striped=True,
+ hover=True,
+ size="sm",
+ color=color
+ )
+
+
+def table_news(data: pd.DataFrame, job: str, period: int) -> list:
+ """Generates the tables with news:
+ 1. Falied tests from the last run
+ 2. Regressions and progressions calculated from the last C.NEWS_TIME_PERIOD
+ days.
+
+ :param data: Trending data with calculated annomalies to be displayed in the
+ tables.
+ :param job: The job name.
+ :param period: The time period (nr of days from now) taken into account.
+ :type data: pandas.DataFrame
+ :type job: str
+ :type period: int
+ :returns: List of tables.
+ :rtype: list
+ """
+
+ last_day = datetime.utcnow() - timedelta(days=period)
+ r_list = list()
+ job_data = data.loc[(data["job"] == job)]
+ r_list.append(_table_info(job_data))
+
+ failed = job_data["failed"].to_list()[0]
+ if failed:
+ r_list.append(_table_failed(job_data, failed))
+
+ title = f"Regressions in the last {period} days"
+ regressions = {title: list(), "Last Regression": list()}
+ for itm in job_data["regressions"].to_list()[0]:
+ if itm[1] < last_day:
+ break
+ regressions[title].append(itm[0])
+ regressions["Last Regression"].append(
+ itm[1].strftime('%Y-%m-%d %H:%M'))
+ if regressions["Last Regression"]:
+ r_list.append(_table_gressions(regressions, "warning"))
+
+ title = f"Progressions in the last {period} days"
+ progressions = {title: list(), "Last Progression": list()}
+ for itm in job_data["progressions"].to_list()[0]:
+ if itm[1] < last_day:
+ break
+ progressions[title].append(itm[0])
+ progressions["Last Progression"].append(
+ itm[1].strftime('%Y-%m-%d %H:%M'))
+ if progressions["Last Progression"]:
+ r_list.append(_table_gressions(progressions, "success"))
+
+ return r_list
+
+
+def table_summary(data: pd.DataFrame, jobs: list, period: int) -> list:
+ """Generates summary (failed tests, regressions and progressions) from the
+ last week.
+
+ :param data: Trending data with calculated annomalies to be displayed in the
+ tables.
+ :param jobs: List of jobs.
+ :params period: The time period for the summary table.
+ :type data: pandas.DataFrame
+ :type job: str
+ :type period: int
+ :returns: List of tables.
+ :rtype: list
+ """
+
+ return [
+ dbc.Accordion(
+ children=[
+ dbc.AccordionItem(
+ title=job,
+ children=table_news(data, job, period)
+ ) for job in jobs
+ ],
+ class_name="gy-2 p-0",
+ start_collapsed=True,
+ always_open=True
+ )
+ ]
diff --git a/resources/tools/dash/app/pal/report/__init__.py b/csit.infra.dash/app/cdash/report/__init__.py
index 5692432123..5692432123 100644
--- a/resources/tools/dash/app/pal/report/__init__.py
+++ b/csit.infra.dash/app/cdash/report/__init__.py
diff --git a/resources/tools/dash/app/pal/report/graphs.py b/csit.infra.dash/app/cdash/report/graphs.py
index 36f28d09e8..36f28d09e8 100644
--- a/resources/tools/dash/app/pal/report/graphs.py
+++ b/csit.infra.dash/app/cdash/report/graphs.py
diff --git a/resources/tools/dash/app/pal/report/layout.py b/csit.infra.dash/app/cdash/report/layout.py
index 978ab0de6c..ec33147744 100644
--- a/resources/tools/dash/app/pal/report/layout.py
+++ b/csit.infra.dash/app/cdash/report/layout.py
@@ -30,7 +30,7 @@ from ast import literal_eval
from ..utils.constants import Constants as C
from ..utils.utils import show_tooltip, label, sync_checklists, list_tests, \
- gen_new_url
+ gen_new_url, generate_options
from ..utils.url_processing import url_decode
from ..data.data import Data
from .graphs import graph_iterative, table_comparison, get_short_version, \
@@ -232,6 +232,7 @@ class Layout:
if self.html_layout and self.spec_tbs:
return html.Div(
id="div-main",
+ className="small",
children=[
dbc.Row(
id="row-navbar",
@@ -290,14 +291,14 @@ class Layout:
children=[
dbc.NavItem(
dbc.NavLink(
- "Iterative Test Runs",
+ C.REPORT_TITLE,
disabled=True,
external_link=True,
href="#"
)
)
],
- brand="Dashboard",
+ brand=C.BRAND,
brand_href="/",
brand_external_link=True,
class_name="p-2",
@@ -310,12 +311,12 @@ class Layout:
:returns: Column with the control panel.
:rtype: dbc.Col
"""
- return dbc.Col(
- id="col-controls",
- children=[
- self._add_ctrl_panel(),
- ],
- )
+ return dbc.Col([
+ html.Div(
+ children=self._add_ctrl_panel(),
+ className="sticky-top"
+ )
+ ])
def _add_plotting_col(self) -> dbc.Col:
"""Add column with plots and tables. It is placed on the right side.
@@ -371,324 +372,300 @@ class Layout:
:returns: Control panel.
:rtype: dbc.Row
"""
- return dbc.Row(
- id="row-ctrl-panel",
- class_name="g-0 p-2",
- children=[
- dbc.Row(
- class_name="g-0",
- children=[
- dbc.InputGroup(
- [
- dbc.InputGroupText(
- children=show_tooltip(self._tooltips,
- "help-release", "CSIT Release")
- ),
- dbc.Select(
- id="dd-ctrl-rls",
- placeholder=("Select a Release..."),
- options=sorted(
- [
- {"label": k, "value": k} \
- for k in self.spec_tbs.keys()
- ],
- key=lambda d: d["label"]
- )
- )
- ],
- class_name="mb-3",
- size="sm",
- ),
- ]
- ),
- dbc.Row(
- class_name="g-0",
- children=[
- dbc.InputGroup(
- [
- dbc.InputGroupText(
- children=show_tooltip(self._tooltips,
- "help-dut", "DUT")
- ),
- dbc.Select(
- id="dd-ctrl-dut",
- placeholder=(
- "Select a Device under Test..."
- )
- )
- ],
- class_name="mb-3",
- size="sm",
- ),
- ]
- ),
- dbc.Row(
- class_name="g-0",
- children=[
- dbc.InputGroup(
- [
- dbc.InputGroupText(
- children=show_tooltip(self._tooltips,
- "help-dut-ver", "DUT Version")
- ),
- dbc.Select(
- id="dd-ctrl-dutver",
- placeholder=(
- "Select a Version of "
- "Device under Test..."
- )
- )
- ],
- class_name="mb-3",
- size="sm",
- ),
- ]
- ),
- dbc.Row(
- class_name="g-0",
- children=[
- dbc.InputGroup(
- [
- dbc.InputGroupText(
- children=show_tooltip(self._tooltips,
- "help-infra", "Infra")
- ),
- dbc.Select(
- id="dd-ctrl-phy",
- placeholder=(
- "Select a Physical Test Bed "
- "Topology..."
- )
- )
- ],
- class_name="mb-3",
- size="sm",
- ),
- ]
- ),
- dbc.Row(
- class_name="g-0",
- children=[
- dbc.InputGroup(
- [
- dbc.InputGroupText(
- children=show_tooltip(self._tooltips,
- "help-area", "Area")
- ),
- dbc.Select(
- id="dd-ctrl-area",
- placeholder="Select an Area...",
- disabled=True,
- ),
- ],
- class_name="mb-3",
- size="sm",
- ),
- ]
- ),
- dbc.Row(
- class_name="g-0",
- children=[
- dbc.InputGroup(
- [
- dbc.InputGroupText(
- children=show_tooltip(self._tooltips,
- "help-test", "Test")
- ),
- dbc.Select(
- id="dd-ctrl-test",
- placeholder="Select a Test...",
- disabled=True,
- ),
- ],
- class_name="mb-3",
- size="sm",
- ),
- ]
- ),
- dbc.Row(
- id="row-ctrl-framesize",
- class_name="gy-1",
- children=[
- dbc.Label(
- children=show_tooltip(self._tooltips,
- "help-framesize", "Frame Size"),
- class_name="p-0"
- ),
- dbc.Col(
- children=[
- dbc.Checklist(
- id="cl-ctrl-framesize-all",
- options=C.CL_ALL_DISABLED,
- inline=True,
- switch=False
- ),
- ],
- width=3
- ),
- dbc.Col(
- children=[
- dbc.Checklist(
- id="cl-ctrl-framesize",
- inline=True,
- switch=False
- )
- ]
- )
- ]
- ),
- dbc.Row(
- id="row-ctrl-core",
- class_name="gy-1",
- children=[
- dbc.Label(
- children=show_tooltip(self._tooltips,
- "help-cores", "Number of Cores"),
- class_name="p-0"
- ),
- dbc.Col(
- children=[
- dbc.Checklist(
- id="cl-ctrl-core-all",
- options=C.CL_ALL_DISABLED,
- inline=False,
- switch=False
+ return [
+ dbc.Row(
+ class_name="g-0 p-1",
+ children=[
+ dbc.InputGroup(
+ [
+ dbc.InputGroupText(
+ children=show_tooltip(self._tooltips,
+ "help-release", "CSIT Release")
+ ),
+ dbc.Select(
+ id="dd-ctrl-rls",
+ placeholder=("Select a Release..."),
+ options=sorted(
+ [
+ {"label": k, "value": k} \
+ for k in self.spec_tbs.keys()
+ ],
+ key=lambda d: d["label"]
)
- ],
- width=3
- ),
- dbc.Col(
- children=[
- dbc.Checklist(
- id="cl-ctrl-core",
- inline=True,
- switch=False
+ )
+ ],
+ size="sm",
+ ),
+ ]
+ ),
+ dbc.Row(
+ class_name="g-0 p-1",
+ children=[
+ dbc.InputGroup(
+ [
+ dbc.InputGroupText(
+ children=show_tooltip(self._tooltips,
+ "help-dut", "DUT")
+ ),
+ dbc.Select(
+ id="dd-ctrl-dut",
+ placeholder=(
+ "Select a Device under Test..."
)
- ]
- )
- ]
- ),
- dbc.Row(
- id="row-ctrl-testtype",
- class_name="gy-1",
- children=[
- dbc.Label(
- children=show_tooltip(self._tooltips,
- "help-ttype", "Test Type"),
- class_name="p-0"
- ),
- dbc.Col(
- children=[
- dbc.Checklist(
- id="cl-ctrl-testtype-all",
- options=C.CL_ALL_DISABLED,
- inline=True,
- switch=False
- ),
- ],
- width=3
- ),
- dbc.Col(
- children=[
- dbc.Checklist(
- id="cl-ctrl-testtype",
- inline=True,
- switch=False
+ )
+ ],
+ size="sm",
+ ),
+ ]
+ ),
+ dbc.Row(
+ class_name="g-0 p-1",
+ children=[
+ dbc.InputGroup(
+ [
+ dbc.InputGroupText(
+ children=show_tooltip(self._tooltips,
+ "help-dut-ver", "DUT Version")
+ ),
+ dbc.Select(
+ id="dd-ctrl-dutver",
+ placeholder=(
+ "Select a Version of "
+ "Device under Test..."
)
- ]
- )
- ]
- ),
- dbc.Row(
- id="row-ctrl-normalize",
- class_name="gy-1",
- children=[
- dbc.Label(
- children=show_tooltip(self._tooltips,
- "help-normalize", "Normalize"),
- class_name="p-0"
- ),
- dbc.Col(
- children=[
- dbc.Checklist(
- id="cl-ctrl-normalize",
- options=[{
- "value": "normalize",
- "label": (
- "Normalize results to CPU"
- "frequency 2GHz"
- )
- }],
- value=[],
- inline=True,
- switch=False
- ),
- ]
- )
- ]
- ),
- dbc.Row(
- class_name="gy-1 p-0",
- children=[
- dbc.ButtonGroup(
- [
- dbc.Button(
- id="btn-ctrl-add",
- children="Add Selected",
- class_name="me-1",
- color="info"
+ )
+ ],
+ size="sm",
+ ),
+ ]
+ ),
+ dbc.Row(
+ class_name="g-0 p-1",
+ children=[
+ dbc.InputGroup(
+ [
+ dbc.InputGroupText(
+ children=show_tooltip(self._tooltips,
+ "help-infra", "Infra")
+ ),
+ dbc.Select(
+ id="dd-ctrl-phy",
+ placeholder=(
+ "Select a Physical Test Bed "
+ "Topology..."
)
- ],
- size="md",
- )
- ]
- ),
- dbc.Row(
- id="row-card-sel-tests",
- class_name="gy-1",
- style=C.STYLE_DISABLED,
- children=[
- dbc.Label(
- "Selected tests",
- class_name="p-0"
- ),
- dbc.Checklist(
- class_name="overflow-auto",
- id="cl-selected",
- options=[],
- inline=False,
- style={"max-height": "20em"},
- )
- ],
- ),
- dbc.Row(
- id="row-btns-sel-tests",
- style=C.STYLE_DISABLED,
- children=[
- dbc.ButtonGroup(
- class_name="gy-2",
- children=[
- dbc.Button(
- id="btn-sel-remove",
- children="Remove Selected",
- class_name="w-100 me-1",
- color="info",
- disabled=False
- ),
- dbc.Button(
- id="btn-sel-remove-all",
- children="Remove All",
- class_name="w-100 me-1",
- color="info",
- disabled=False
- ),
- ],
- size="md",
- )
- ]
- ),
- ]
- )
+ )
+ ],
+ size="sm",
+ ),
+ ]
+ ),
+ dbc.Row(
+ class_name="g-0 p-1",
+ children=[
+ dbc.InputGroup(
+ [
+ dbc.InputGroupText(
+ children=show_tooltip(self._tooltips,
+ "help-area", "Area")
+ ),
+ dbc.Select(
+ id="dd-ctrl-area",
+ placeholder="Select an Area...",
+ disabled=True,
+ ),
+ ],
+ size="sm",
+ ),
+ ]
+ ),
+ dbc.Row(
+ class_name="g-0 p-1",
+ children=[
+ dbc.InputGroup(
+ [
+ dbc.InputGroupText(
+ children=show_tooltip(self._tooltips,
+ "help-test", "Test")
+ ),
+ dbc.Select(
+ id="dd-ctrl-test",
+ placeholder="Select a Test...",
+ disabled=True,
+ ),
+ ],
+ size="sm",
+ ),
+ ]
+ ),
+ dbc.Row(
+ class_name="g-0 p-1",
+ children=[
+ dbc.Label(
+ children=show_tooltip(self._tooltips,
+ "help-framesize", "Frame Size"),
+ ),
+ dbc.Col(
+ children=[
+ dbc.Checklist(
+ id="cl-ctrl-framesize-all",
+ options=C.CL_ALL_DISABLED,
+ inline=True,
+ switch=False
+ ),
+ ],
+ width=3
+ ),
+ dbc.Col(
+ children=[
+ dbc.Checklist(
+ id="cl-ctrl-framesize",
+ inline=True,
+ switch=False
+ )
+ ]
+ )
+ ]
+ ),
+ dbc.Row(
+ class_name="g-0 p-1",
+ children=[
+ dbc.Label(
+ children=show_tooltip(self._tooltips,
+ "help-cores", "Number of Cores"),
+ ),
+ dbc.Col(
+ children=[
+ dbc.Checklist(
+ id="cl-ctrl-core-all",
+ options=C.CL_ALL_DISABLED,
+ inline=False,
+ switch=False
+ )
+ ],
+ width=3
+ ),
+ dbc.Col(
+ children=[
+ dbc.Checklist(
+ id="cl-ctrl-core",
+ inline=True,
+ switch=False
+ )
+ ]
+ )
+ ]
+ ),
+ dbc.Row(
+ class_name="g-0 p-1",
+ children=[
+ dbc.Label(
+ children=show_tooltip(self._tooltips,
+ "help-ttype", "Test Type"),
+ ),
+ dbc.Col(
+ children=[
+ dbc.Checklist(
+ id="cl-ctrl-testtype-all",
+ options=C.CL_ALL_DISABLED,
+ inline=True,
+ switch=False
+ ),
+ ],
+ width=3
+ ),
+ dbc.Col(
+ children=[
+ dbc.Checklist(
+ id="cl-ctrl-testtype",
+ inline=True,
+ switch=False
+ )
+ ]
+ )
+ ]
+ ),
+ dbc.Row(
+ class_name="g-0 p-1",
+ children=[
+ dbc.Label(
+ children=show_tooltip(self._tooltips,
+ "help-normalize", "Normalize"),
+ ),
+ dbc.Col(
+ children=[
+ dbc.Checklist(
+ id="cl-ctrl-normalize",
+ options=[{
+ "value": "normalize",
+ "label": (
+ "Normalize results to CPU "
+ "frequency 2GHz"
+ )
+ }],
+ value=[],
+ inline=True,
+ switch=False
+ ),
+ ]
+ )
+ ]
+ ),
+ dbc.Row(
+ class_name="g-0 p-1",
+ children=[
+ dbc.ButtonGroup(
+ [
+ dbc.Button(
+ id="btn-ctrl-add",
+ children="Add Selected",
+ color="info"
+ )
+ ]
+ )
+ ]
+ ),
+ dbc.Row(
+ id="row-card-sel-tests",
+ class_name="g-0 p-1",
+ style=C.STYLE_DISABLED,
+ children=[
+ dbc.Label("Selected tests"),
+ dbc.Checklist(
+ class_name="overflow-auto",
+ id="cl-selected",
+ options=[],
+ inline=False,
+ style={"max-height": "20em"},
+ )
+ ],
+ ),
+ dbc.Row(
+ id="row-btns-sel-tests",
+ class_name="g-0 p-1",
+ style=C.STYLE_DISABLED,
+ children=[
+ dbc.ButtonGroup(
+ children=[
+ dbc.Button(
+ id="btn-sel-remove",
+ children="Remove Selected",
+ class_name="w-100",
+ color="info",
+ disabled=False
+ ),
+ dbc.Button(
+ id="btn-sel-remove-all",
+ children="Remove All",
+ class_name="w-100",
+ color="info",
+ disabled=False
+ ),
+ ]
+ )
+ ]
+ ),
+ ]
class ControlPanel:
"""A class representing the control panel.
@@ -1001,9 +978,14 @@ class Layout:
"""
ctrl_panel = self.ControlPanel(cp_data)
+ norm = cl_normalize
# Parse the url:
parsed_url = url_decode(href)
+ if parsed_url:
+ url_params = parsed_url["params"]
+ else:
+ url_params = None
row_fig_tput = no_update
row_fig_lat = no_update
@@ -1016,11 +998,8 @@ class Layout:
if trigger_id == "dd-ctrl-rls":
try:
- rls = self.spec_tbs[dd_rls]
- options = sorted(
- [{"label": v, "value": v} for v in rls.keys()],
- key=lambda d: d["label"]
- )
+ options = \
+ generate_options(sorted(self.spec_tbs[dd_rls].keys()))
disabled = False
except KeyError:
options = list()
@@ -1059,10 +1038,7 @@ class Layout:
try:
rls = ctrl_panel.get("dd-rls-value")
dut = self.spec_tbs[rls][dd_dut]
- options = sorted(
- [{"label": v, "value": v} for v in dut.keys()],
- key=lambda d: d["label"]
- )
+ options = generate_options(sorted(dut.keys()))
disabled = False
except KeyError:
options = list()
@@ -1099,10 +1075,7 @@ class Layout:
rls = ctrl_panel.get("dd-rls-value")
dut = ctrl_panel.get("dd-dut-value")
dutver = self.spec_tbs[rls][dut][dd_dutver]
- options = sorted(
- [{"label": v, "value": v} for v in dutver.keys()],
- key=lambda d: d["label"]
- )
+ options = generate_options(sorted(dutver.keys()))
disabled = False
except KeyError:
options = list()
@@ -1137,10 +1110,8 @@ class Layout:
dut = ctrl_panel.get("dd-dut-value")
dutver = ctrl_panel.get("dd-dutver-value")
phy = self.spec_tbs[rls][dut][dutver][dd_phy]
- options = sorted(
- [{"label": label(v), "value": v} for v in phy.keys()],
- key=lambda d: d["label"]
- )
+ options = [{"label": label(v), "value": v} \
+ for v in sorted(phy.keys())]
disabled = False
except KeyError:
options = list()
@@ -1173,10 +1144,7 @@ class Layout:
dutver = ctrl_panel.get("dd-dutver-value")
phy = ctrl_panel.get("dd-phy-value")
area = self.spec_tbs[rls][dut][dutver][phy][dd_area]
- options = sorted(
- [{"label": v, "value": v} for v in area.keys()],
- key=lambda d: d["label"]
- )
+ options = generate_options(sorted(area.keys()))
disabled = False
except KeyError:
options = list()
@@ -1205,22 +1173,22 @@ class Layout:
dutver = ctrl_panel.get("dd-dutver-value")
phy = ctrl_panel.get("dd-phy-value")
area = ctrl_panel.get("dd-area-value")
- test = self.spec_tbs[rls][dut][dutver][phy][area][dd_test]
- if dut and phy and area and dd_test:
+ if all((rls, dut, dutver, phy, area, dd_test, )):
+ test = self.spec_tbs[rls][dut][dutver][phy][area][dd_test]
ctrl_panel.set({
"dd-test-value": dd_test,
- "cl-core-options": [{"label": v, "value": v}
- for v in sorted(test["core"])],
+ "cl-core-options": \
+ generate_options(sorted(test["core"])),
"cl-core-value": list(),
"cl-core-all-value": list(),
"cl-core-all-options": C.CL_ALL_ENABLED,
- "cl-framesize-options": [{"label": v, "value": v}
- for v in sorted(test["frame-size"])],
+ "cl-framesize-options": \
+ generate_options(sorted(test["frame-size"])),
"cl-framesize-value": list(),
"cl-framesize-all-value": list(),
"cl-framesize-all-options": C.CL_ALL_ENABLED,
- "cl-testtype-options": [{"label": v, "value": v}
- for v in sorted(test["test-type"])],
+ "cl-testtype-options": \
+ generate_options(sorted(test["test-type"])),
"cl-testtype-value": list(),
"cl-testtype-all-value": list(),
"cl-testtype-all-options": C.CL_ALL_ENABLED,
@@ -1356,14 +1324,70 @@ class Layout:
new_store_sel.append(item)
store_sel = new_store_sel
elif trigger_id == "url":
- # TODO: Add verification
- url_params = parsed_url["params"]
if url_params:
- store_sel = literal_eval(
- url_params.get("store_sel", list())[0])
+ try:
+ store_sel = literal_eval(url_params["store_sel"][0])
+ norm = literal_eval(url_params["norm"][0])
+ except (KeyError, IndexError):
+ pass
if store_sel:
row_card_sel_tests = C.STYLE_ENABLED
row_btns_sel_tests = C.STYLE_ENABLED
+ last_test = store_sel[-1]
+ test = self.spec_tbs[last_test["rls"]]\
+ [last_test["dut"]][last_test["dutver"]]\
+ [last_test["phy"]][last_test["area"]]\
+ [last_test["test"]]
+ ctrl_panel.set({
+ "dd-rls-value": last_test["rls"],
+ "dd-dut-value": last_test["dut"],
+ "dd-dut-options": generate_options(sorted(
+ self.spec_tbs[last_test["rls"]].keys())),
+ "dd-dut-disabled": False,
+ "dd-dutver-value": last_test["dutver"],
+ "dd-dutver-options": generate_options(sorted(
+ self.spec_tbs[last_test["rls"]]\
+ [last_test["dut"]].keys())),
+ "dd-dutver-disabled": False,
+ "dd-phy-value": last_test["phy"],
+ "dd-phy-options": generate_options(sorted(
+ self.spec_tbs[last_test["rls"]]\
+ [last_test["dut"]]\
+ [last_test["dutver"]].keys())),
+ "dd-phy-disabled": False,
+ "dd-area-value": last_test["area"],
+ "dd-area-options": [
+ {"label": label(v), "value": v} for v in \
+ sorted(self.spec_tbs[last_test["rls"]]\
+ [last_test["dut"]][last_test["dutver"]]\
+ [last_test["phy"]].keys())
+ ],
+ "dd-area-disabled": False,
+ "dd-test-value": last_test["test"],
+ "dd-test-options": generate_options(sorted(
+ self.spec_tbs[last_test["rls"]]\
+ [last_test["dut"]][last_test["dutver"]]\
+ [last_test["phy"]]\
+ [last_test["area"]].keys())),
+ "dd-test-disabled": False,
+ "cl-core-options": generate_options(sorted(
+ test["core"])),
+ "cl-core-value": [last_test["core"].upper(), ],
+ "cl-core-all-value": list(),
+ "cl-core-all-options": C.CL_ALL_ENABLED,
+ "cl-framesize-options": generate_options(
+ sorted(test["frame-size"])),
+ "cl-framesize-value": \
+ [last_test["framesize"].upper(), ],
+ "cl-framesize-all-value": list(),
+ "cl-framesize-all-options": C.CL_ALL_ENABLED,
+ "cl-testtype-options": generate_options(sorted(
+ test["test-type"])),
+ "cl-testtype-value": \
+ [last_test["testtype"].upper(), ],
+ "cl-testtype-all-value": list(),
+ "cl-testtype-all-options": C.CL_ALL_ENABLED
+ })
if trigger_id in ("btn-ctrl-add", "url", "btn-sel-remove",
"cl-ctrl-normalize"):
@@ -1371,13 +1395,15 @@ class Layout:
row_fig_tput, row_fig_lat, row_table, row_btn_dwnld = \
_generate_plotting_area(
graph_iterative(
- self.data, store_sel, self.layout,
- bool(cl_normalize)
+ self.data, store_sel, self.layout, bool(norm)
),
table_comparison(
- self.data, store_sel, bool(cl_normalize)
+ self.data, store_sel, bool(norm)
),
- gen_new_url(parsed_url, {"store_sel": store_sel})
+ gen_new_url(
+ parsed_url,
+ {"store_sel": store_sel, "norm": norm}
+ )
)
ctrl_panel.set({
"cl-selected-options": list_tests(store_sel)
@@ -1400,7 +1426,7 @@ class Layout:
disabled = True
ctrl_panel.set({
"btn-add-disabled": disabled,
- "cl-normalize-value": cl_normalize
+ "cl-normalize-value": norm
})
ret_val = [
diff --git a/resources/tools/dash/app/pal/report/layout.yaml b/csit.infra.dash/app/cdash/report/layout.yaml
index 689a91d291..c4ef13bf8b 100644
--- a/resources/tools/dash/app/pal/report/layout.yaml
+++ b/csit.infra.dash/app/cdash/report/layout.yaml
@@ -89,18 +89,10 @@ plot-latency:
namelength: -1
plot-hdrh-latency:
- # title:
- # text: "Latency by Percentile Distribution"
- # xanchor: "center"
- # x: 0.5
- # font:
- # size: 10
showlegend: True
legend:
traceorder: "normal"
orientation: "h"
- # font:
- # size: 16
xanchor: "left"
yanchor: "top"
x: 0
@@ -110,8 +102,6 @@ plot-hdrh-latency:
xaxis:
type: "log"
title: "Percentile [%]"
- # titlefont:
- # size: 14
autorange: False
fixedrange: True
gridcolor: "rgb(230, 230, 230)"
@@ -123,12 +113,8 @@ plot-hdrh-latency:
tickcolor: "rgb(220, 220, 220)"
tickvals: [1, 2, 1e1, 20, 1e2, 1e3, 1e4, 1e5, 1e6]
ticktext: [0, 50, 90, 95, 99, 99.9, 99.99, 99.999, 99.9999]
- # tickfont:
- # size: 14
yaxis:
title: "One-Way Latency per Direction [us]"
- # titlefont:
- # size: 14
gridcolor: "rgb(230, 230, 230)"
linecolor: "rgb(220, 220, 220)"
linewidth: 1
@@ -136,105 +122,6 @@ plot-hdrh-latency:
showline: True
showticklabels: True
tickcolor: "rgb(220, 220, 220)"
- # tickfont:
- # size: 14
autosize: True
- #height: 400
paper_bgcolor: "white"
plot_bgcolor: "white"
-
-plot-throughput-speedup-analysis:
- titlefont:
- size: 16
- xaxis:
- title: "<b>Number of Cores [Qty]</b>"
- titlefont:
- size: 14
- autorange: True
- fixedrange: False
- gridcolor: "rgb(230, 230, 230)"
- linecolor: "rgb(220, 220, 220)"
- linewidth: 1
- showgrid: True
- showline: True
- showticklabels: True
- tickcolor: "rgb(238, 238, 238)"
- tickmode: "linear"
- tickfont:
- size: 14
- zeroline: False
- yaxis:
- title: "<b>Packet Throughput [Mpps]</b>"
- titlefont:
- size: 14
- type: "linear"
- gridcolor: "rgb(230, 230, 230)"
- hoverformat: ".4s"
- linecolor: "rgb(220, 220, 220)"
- linewidth: 1
- showgrid: True
- showline: True
- showticklabels: True
- tickcolor: "rgb(220, 220, 220)"
- tickformat: ".4s"
- tickfont:
- size: 14
- zeroline: True
- rangemode: "tozero"
- range: [0, 100]
- legend:
- orientation: "h"
- font:
- size: 14
- xanchor: "left"
- yanchor: "top"
- x: 0
- y: -0.2
- bgcolor: "rgba(255, 255, 255, 0)"
- bordercolor: "rgba(255, 255, 255, 0)"
- traceorder: "normal"
- autosize: False
- margin:
- 't': 50
- 'b': 150
- 'l': 85
- 'r': 10
- showlegend: True
- width: 700
- height: 700
- paper_bgcolor: "#fff"
- plot_bgcolor: "#fff"
- hoverlabel:
- namelength: -1
- annotations: [
- {
- text: "_ _ __ ...",
- align: "left",
- showarrow: False,
- xref: "paper",
- yref: "paper",
- xanchor: "left",
- yanchor: "top",
- x: 0,
- y: -0.14,
- font: {
- family: "Consolas, Courier New",
- size: 13
- },
- },
- {
- text: " Perfect Measured Limit",
- align: "left",
- showarrow: False,
- xref: "paper",
- yref: "paper",
- xanchor: "left",
- yanchor: "top",
- x: 0,
- y: -0.15,
- font: {
- family: "Consolas, Courier New",
- size: 13
- },
- },
- ]
diff --git a/resources/tools/dash/app/pal/report/report.py b/csit.infra.dash/app/cdash/report/report.py
index e4565731ec..28fced433e 100644
--- a/resources/tools/dash/app/pal/report/report.py
+++ b/csit.infra.dash/app/cdash/report/report.py
@@ -31,13 +31,14 @@ def init_report(server, releases):
dash_app = dash.Dash(
server=server,
routes_pathname_prefix=C.REPORT_ROUTES_PATHNAME_PREFIX,
- external_stylesheets=C.EXTERNAL_STYLESHEETS
+ external_stylesheets=C.EXTERNAL_STYLESHEETS,
+ title=C.REPORT_TITLE
)
layout = Layout(
app=dash_app,
releases=releases,
- html_layout_file=C.REPORT_HTML_LAYOUT_FILE,
+ html_layout_file=C.HTML_LAYOUT_FILE,
graph_layout_file=C.REPORT_GRAPH_LAYOUT_FILE,
data_spec_file=C.DATA_SPEC_FILE,
tooltip_file=C.TOOLTIP_FILE,
diff --git a/resources/tools/dash/app/pal/routes.py b/csit.infra.dash/app/cdash/routes.py
index 59af748168..81425692f2 100644
--- a/resources/tools/dash/app/pal/routes.py
+++ b/csit.infra.dash/app/cdash/routes.py
@@ -28,5 +28,9 @@ def home():
C.MAIN_HTML_LAYOUT_FILE,
title=C.TITLE,
description=C.DESCRIPTION,
+ trending_title=C.TREND_TITLE,
+ report_title=C.REPORT_TITLE,
+ stats_title=C.STATS_TITLE,
+ news_title=C.NEWS_TITLE,
template=C.TEMPLATE
)
diff --git a/resources/tools/dash/app/pal/static/dist/img/favicon.svg b/csit.infra.dash/app/cdash/static/dist/img/favicon.svg
index 689757e3fd..689757e3fd 100644
--- a/resources/tools/dash/app/pal/static/dist/img/favicon.svg
+++ b/csit.infra.dash/app/cdash/static/dist/img/favicon.svg
diff --git a/resources/tools/dash/app/pal/static/img/logo.svg b/csit.infra.dash/app/cdash/static/img/logo.svg
index 689757e3fd..689757e3fd 100644
--- a/resources/tools/dash/app/pal/static/img/logo.svg
+++ b/csit.infra.dash/app/cdash/static/img/logo.svg
diff --git a/csit.infra.dash/app/cdash/static/sass/_bootswatch.scss b/csit.infra.dash/app/cdash/static/sass/_bootswatch.scss
new file mode 100644
index 0000000000..900ccfb3c1
--- /dev/null
+++ b/csit.infra.dash/app/cdash/static/sass/_bootswatch.scss
@@ -0,0 +1,178 @@
+// Lux 5.2.1
+// Bootswatch
+
+
+// Variables
+
+$web-font-path: "https://fonts.googleapis.com/css2?family=Nunito+Sans:wght@400;600&display=swap" !default;
+@if $web-font-path {
+ @import url($web-font-path);
+}
+
+:root {
+ color-scheme: light;
+}
+
+// Navbar
+
+.navbar {
+ font-size: $font-size-sm;
+ font-weight: 600;
+ text-transform: uppercase;
+
+ &-nav {
+ .nav-link {
+ padding-top: .715rem;
+ padding-bottom: .715rem;
+ }
+ }
+
+ &-brand {
+ margin-right: 2rem;
+ }
+}
+
+.bg-light {
+ border: 1px solid rgba(0, 0, 0, .1);
+
+ &.navbar-fixed-top {
+ border-width: 0 0 1px;
+ }
+
+ &.navbar-bottom-top {
+ border-width: 1px 0 0;
+ }
+}
+
+.nav-item {
+ margin-right: 2rem;
+}
+
+// Buttons
+
+.btn {
+ font-size: $font-size-sm;
+ text-transform: uppercase;
+
+ &-sm {
+ font-size: 10px;
+ }
+
+ &-warning {
+ &,
+ &:hover,
+ &:not([disabled]):not(.disabled):active,
+ &:focus {
+ color: $white;
+ }
+ }
+}
+
+.btn-outline-secondary {
+ color: $gray-600;
+ border-color: $gray-600;
+
+ &:not([disabled]):not(.disabled):hover,
+ &:not([disabled]):not(.disabled):focus,
+ &:not([disabled]):not(.disabled):active {
+ color: $white;
+ background-color: $gray-400;
+ border-color: $gray-400;
+ }
+
+ &:not([disabled]):not(.disabled):focus {
+ box-shadow: 0 0 0 .2rem rgba($gray-400, .5);
+ }
+}
+
+[class*="btn-outline-"] {
+ border-width: 2px;
+}
+
+.border-secondary {
+ border: 1px solid $gray-400 !important;
+}
+
+// Typography
+
+body {
+ font-weight: 200;
+ letter-spacing: 1px;
+}
+
+h1,
+h2,
+h3,
+h4,
+h5,
+h6 {
+ text-transform: uppercase;
+ letter-spacing: 3px;
+}
+
+.text-secondary {
+ color: $body-color !important;
+}
+
+// Tables
+
+th {
+ font-size: $font-size-sm;
+ text-transform: uppercase;
+}
+
+.table {
+ th,
+ td {
+ padding: 1.5rem;
+ }
+
+ &-sm {
+ th,
+ td {
+ padding: .75rem;
+ }
+ }
+}
+
+// Navs
+
+.dropdown-menu {
+ font-size: $font-size-sm;
+ text-transform: none;
+}
+
+// Indicators
+
+.badge {
+ padding-top: .28rem;
+
+ &-pill {
+ border-radius: 10rem;
+ }
+
+ &.bg-secondary,
+ &.bg-light {
+ color: $dark;
+ }
+}
+
+// Containers
+
+.list-group-item,
+.card {
+ h1,
+ h2,
+ h3,
+ h4,
+ h5,
+ h6,
+ .h1,
+ .h2,
+ .h3,
+ .h4,
+ .h5,
+ .h6 {
+ color: inherit;
+ }
+}
diff --git a/csit.infra.dash/app/cdash/static/sass/_variables.scss b/csit.infra.dash/app/cdash/static/sass/_variables.scss
new file mode 100644
index 0000000000..6bfd6408b7
--- /dev/null
+++ b/csit.infra.dash/app/cdash/static/sass/_variables.scss
@@ -0,0 +1,103 @@
+// Lux 5.2.1
+// Bootswatch
+
+$theme: "lux" !default;
+
+//
+// Color system
+//
+
+$white: #fff !default;
+$gray-100: #f8f9fa !default;
+$gray-200: #f7f7f9 !default;
+$gray-300: #eceeef !default;
+$gray-400: #ced4da !default;
+$gray-500: #adb5bd !default;
+$gray-600: #919aa1 !default;
+$gray-700: #55595c !default;
+$gray-800: #343a40 !default;
+$gray-900: #1a1a1a !default;
+$black: #000 !default;
+
+$blue: #007bff !default;
+$indigo: #6610f2 !default;
+$purple: #6f42c1 !default;
+$pink: #e83e8c !default;
+$red: #d9534f !default;
+$orange: #fd7e14 !default;
+$yellow: #f0ad4e !default;
+$green: #4bbf73 !default;
+$teal: #20c997 !default;
+$cyan: #1f9bcf !default;
+
+$primary: $gray-900 !default;
+$secondary: $white !default;
+$success: $green !default;
+$info: $cyan !default;
+$warning: $yellow !default;
+$danger: $red !default;
+$light: $white !default;
+$dark: $gray-800 !default;
+
+$min-contrast-ratio: 2.3 !default;
+
+// Options
+
+$enable-rounded: false !default;
+
+// Body
+
+$body-color: $gray-700 !default;
+
+// Fonts
+
+// stylelint-disable-next-line value-keyword-case
+$font-family-sans-serif: "Nunito Sans", -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol" !default;
+$h1-font-size: 2rem !default;
+$h2-font-size: 1.75rem !default;
+$h3-font-size: 1.5rem !default;
+$h4-font-size: 1.25rem !default;
+$h5-font-size: 1rem !default;
+$h6-font-size: .75rem !default;
+$headings-font-weight: 600 !default;
+$headings-color: $gray-900 !default;
+
+// Tables
+
+$table-border-color: rgba(0, 0, 0, .05) !default;
+
+// Buttons + Forms
+
+$input-btn-border-width: 0 !default;
+
+// Buttons
+
+$btn-line-height: 1.5rem !default;
+$input-btn-padding-y: .75rem !default;
+$input-btn-padding-x: 1.5rem !default;
+$input-btn-padding-y-sm: .5rem !default;
+$input-btn-padding-x-sm: 1rem !default;
+$input-btn-padding-y-lg: 2rem !default;
+$input-btn-padding-x-lg: 2rem !default;
+$btn-font-weight: 600 !default;
+
+// Forms
+
+$input-line-height: 1.5 !default;
+$input-bg: $gray-200 !default;
+$input-disabled-bg: $gray-300 !default;
+$input-group-addon-bg: $gray-300 !default;
+
+// Navbar
+
+$navbar-padding-y: 1.5rem !default;
+$navbar-dark-hover-color: $white !default;
+$navbar-light-color: rgba($black, .3) !default;
+$navbar-light-hover-color: $gray-900 !default;
+$navbar-light-active-color: $gray-900 !default;
+
+// Pagination
+
+$pagination-border-color: transparent !default;
+$pagination-hover-border-color: $pagination-border-color !default;
+$pagination-disabled-border-color: $pagination-border-color !default;
diff --git a/csit.infra.dash/app/cdash/static/sass/bootstrap/_accordion.scss b/csit.infra.dash/app/cdash/static/sass/bootstrap/_accordion.scss
new file mode 100644
index 0000000000..f09601bab6
--- /dev/null
+++ b/csit.infra.dash/app/cdash/static/sass/bootstrap/_accordion.scss
@@ -0,0 +1,149 @@
+//
+// Base styles
+//
+
+.accordion {
+ // scss-docs-start accordion-css-vars
+ --#{$prefix}accordion-color: #{$accordion-color};
+ --#{$prefix}accordion-bg: #{$accordion-bg};
+ --#{$prefix}accordion-transition: #{$accordion-transition};
+ --#{$prefix}accordion-border-color: #{$accordion-border-color};
+ --#{$prefix}accordion-border-width: #{$accordion-border-width};
+ --#{$prefix}accordion-border-radius: #{$accordion-border-radius};
+ --#{$prefix}accordion-inner-border-radius: #{$accordion-inner-border-radius};
+ --#{$prefix}accordion-btn-padding-x: #{$accordion-button-padding-x};
+ --#{$prefix}accordion-btn-padding-y: #{$accordion-button-padding-y};
+ --#{$prefix}accordion-btn-color: #{$accordion-button-color};
+ --#{$prefix}accordion-btn-bg: #{$accordion-button-bg};
+ --#{$prefix}accordion-btn-icon: #{escape-svg($accordion-button-icon)};
+ --#{$prefix}accordion-btn-icon-width: #{$accordion-icon-width};
+ --#{$prefix}accordion-btn-icon-transform: #{$accordion-icon-transform};
+ --#{$prefix}accordion-btn-icon-transition: #{$accordion-icon-transition};
+ --#{$prefix}accordion-btn-active-icon: #{escape-svg($accordion-button-active-icon)};
+ --#{$prefix}accordion-btn-focus-border-color: #{$accordion-button-focus-border-color};
+ --#{$prefix}accordion-btn-focus-box-shadow: #{$accordion-button-focus-box-shadow};
+ --#{$prefix}accordion-body-padding-x: #{$accordion-body-padding-x};
+ --#{$prefix}accordion-body-padding-y: #{$accordion-body-padding-y};
+ --#{$prefix}accordion-active-color: #{$accordion-button-active-color};
+ --#{$prefix}accordion-active-bg: #{$accordion-button-active-bg};
+ // scss-docs-end accordion-css-vars
+}
+
+.accordion-button {
+ position: relative;
+ display: flex;
+ align-items: center;
+ width: 100%;
+ padding: var(--#{$prefix}accordion-btn-padding-y) var(--#{$prefix}accordion-btn-padding-x);
+ @include font-size($font-size-base);
+ color: var(--#{$prefix}accordion-btn-color);
+ text-align: left; // Reset button style
+ background-color: var(--#{$prefix}accordion-btn-bg);
+ border: 0;
+ @include border-radius(0);
+ overflow-anchor: none;
+ @include transition(var(--#{$prefix}accordion-transition));
+
+ &:not(.collapsed) {
+ color: var(--#{$prefix}accordion-active-color);
+ background-color: var(--#{$prefix}accordion-active-bg);
+ box-shadow: inset 0 calc(-1 * var(--#{$prefix}accordion-border-width)) 0 var(--#{$prefix}accordion-border-color); // stylelint-disable-line function-disallowed-list
+
+ &::after {
+ background-image: var(--#{$prefix}accordion-btn-active-icon);
+ transform: var(--#{$prefix}accordion-btn-icon-transform);
+ }
+ }
+
+ // Accordion icon
+ &::after {
+ flex-shrink: 0;
+ width: var(--#{$prefix}accordion-btn-icon-width);
+ height: var(--#{$prefix}accordion-btn-icon-width);
+ margin-left: auto;
+ content: "";
+ background-image: var(--#{$prefix}accordion-btn-icon);
+ background-repeat: no-repeat;
+ background-size: var(--#{$prefix}accordion-btn-icon-width);
+ @include transition(var(--#{$prefix}accordion-btn-icon-transition));
+ }
+
+ &:hover {
+ z-index: 2;
+ }
+
+ &:focus {
+ z-index: 3;
+ border-color: var(--#{$prefix}accordion-btn-focus-border-color);
+ outline: 0;
+ box-shadow: var(--#{$prefix}accordion-btn-focus-box-shadow);
+ }
+}
+
+.accordion-header {
+ margin-bottom: 0;
+}
+
+.accordion-item {
+ color: var(--#{$prefix}accordion-color);
+ background-color: var(--#{$prefix}accordion-bg);
+ border: var(--#{$prefix}accordion-border-width) solid var(--#{$prefix}accordion-border-color);
+
+ &:first-of-type {
+ @include border-top-radius(var(--#{$prefix}accordion-border-radius));
+
+ .accordion-button {
+ @include border-top-radius(var(--#{$prefix}accordion-inner-border-radius));
+ }
+ }
+
+ &:not(:first-of-type) {
+ border-top: 0;
+ }
+
+ // Only set a border-radius on the last item if the accordion is collapsed
+ &:last-of-type {
+ @include border-bottom-radius(var(--#{$prefix}accordion-border-radius));
+
+ .accordion-button {
+ &.collapsed {
+ @include border-bottom-radius(var(--#{$prefix}accordion-inner-border-radius));
+ }
+ }
+
+ .accordion-collapse {
+ @include border-bottom-radius(var(--#{$prefix}accordion-border-radius));
+ }
+ }
+}
+
+.accordion-body {
+ padding: var(--#{$prefix}accordion-body-padding-y) var(--#{$prefix}accordion-body-padding-x);
+}
+
+
+// Flush accordion items
+//
+// Remove borders and border-radius to keep accordion items edge-to-edge.
+
+.accordion-flush {
+ .accordion-collapse {
+ border-width: 0;
+ }
+
+ .accordion-item {
+ border-right: 0;
+ border-left: 0;
+ @include border-radius(0);
+
+ &:first-child { border-top: 0; }
+ &:last-child { border-bottom: 0; }
+
+ .accordion-button {
+ &,
+ &.collapsed {
+ @include border-radius(0);
+ }
+ }
+ }
+}
diff --git a/csit.infra.dash/app/cdash/static/sass/bootstrap/_alert.scss b/csit.infra.dash/app/cdash/static/sass/bootstrap/_alert.scss
new file mode 100644
index 0000000000..c8bc91b420
--- /dev/null
+++ b/csit.infra.dash/app/cdash/static/sass/bootstrap/_alert.scss
@@ -0,0 +1,71 @@
+//
+// Base styles
+//
+
+.alert {
+ // scss-docs-start alert-css-vars
+ --#{$prefix}alert-bg: transparent;
+ --#{$prefix}alert-padding-x: #{$alert-padding-x};
+ --#{$prefix}alert-padding-y: #{$alert-padding-y};
+ --#{$prefix}alert-margin-bottom: #{$alert-margin-bottom};
+ --#{$prefix}alert-color: inherit;
+ --#{$prefix}alert-border-color: transparent;
+ --#{$prefix}alert-border: #{$alert-border-width} solid var(--#{$prefix}alert-border-color);
+ --#{$prefix}alert-border-radius: #{$alert-border-radius};
+ // scss-docs-end alert-css-vars
+
+ position: relative;
+ padding: var(--#{$prefix}alert-padding-y) var(--#{$prefix}alert-padding-x);
+ margin-bottom: var(--#{$prefix}alert-margin-bottom);
+ color: var(--#{$prefix}alert-color);
+ background-color: var(--#{$prefix}alert-bg);
+ border: var(--#{$prefix}alert-border);
+ @include border-radius(var(--#{$prefix}alert-border-radius));
+}
+
+// Headings for larger alerts
+.alert-heading {
+ // Specified to prevent conflicts of changing $headings-color
+ color: inherit;
+}
+
+// Provide class for links that match alerts
+.alert-link {
+ font-weight: $alert-link-font-weight;
+}
+
+
+// Dismissible alerts
+//
+// Expand the right padding and account for the close button's positioning.
+
+.alert-dismissible {
+ padding-right: $alert-dismissible-padding-r;
+
+ // Adjust close link position
+ .btn-close {
+ position: absolute;
+ top: 0;
+ right: 0;
+ z-index: $stretched-link-z-index + 1;
+ padding: $alert-padding-y * 1.25 $alert-padding-x;
+ }
+}
+
+
+// scss-docs-start alert-modifiers
+// Generate contextual modifier classes for colorizing the alert.
+
+@each $state, $value in $theme-colors {
+ $alert-background: shift-color($value, $alert-bg-scale);
+ $alert-border: shift-color($value, $alert-border-scale);
+ $alert-color: shift-color($value, $alert-color-scale);
+
+ @if (contrast-ratio($alert-background, $alert-color) < $min-contrast-ratio) {
+ $alert-color: mix($value, color-contrast($alert-background), abs($alert-color-scale));
+ }
+ .alert-#{$state} {
+ @include alert-variant($alert-background, $alert-border, $alert-color);
+ }
+}
+// scss-docs-end alert-modifiers
diff --git a/csit.infra.dash/app/cdash/static/sass/bootstrap/_badge.scss b/csit.infra.dash/app/cdash/static/sass/bootstrap/_badge.scss
new file mode 100644
index 0000000000..cc3d269556
--- /dev/null
+++ b/csit.infra.dash/app/cdash/static/sass/bootstrap/_badge.scss
@@ -0,0 +1,38 @@
+// Base class
+//
+// Requires one of the contextual, color modifier classes for `color` and
+// `background-color`.
+
+.badge {
+ // scss-docs-start badge-css-vars
+ --#{$prefix}badge-padding-x: #{$badge-padding-x};
+ --#{$prefix}badge-padding-y: #{$badge-padding-y};
+ @include rfs($badge-font-size, --#{$prefix}badge-font-size);
+ --#{$prefix}badge-font-weight: #{$badge-font-weight};
+ --#{$prefix}badge-color: #{$badge-color};
+ --#{$prefix}badge-border-radius: #{$badge-border-radius};
+ // scss-docs-end badge-css-vars
+
+ display: inline-block;
+ padding: var(--#{$prefix}badge-padding-y) var(--#{$prefix}badge-padding-x);
+ @include font-size(var(--#{$prefix}badge-font-size));
+ font-weight: var(--#{$prefix}badge-font-weight);
+ line-height: 1;
+ color: var(--#{$prefix}badge-color);
+ text-align: center;
+ white-space: nowrap;
+ vertical-align: baseline;
+ @include border-radius(var(--#{$prefix}badge-border-radius));
+ @include gradient-bg();
+
+ // Empty badges collapse automatically
+ &:empty {
+ display: none;
+ }
+}
+
+// Quick fix for badges in buttons
+.btn .badge {
+ position: relative;
+ top: -1px;
+}
diff --git a/csit.infra.dash/app/cdash/static/sass/bootstrap/_breadcrumb.scss b/csit.infra.dash/app/cdash/static/sass/bootstrap/_breadcrumb.scss
new file mode 100644
index 0000000000..b8252ff215
--- /dev/null
+++ b/csit.infra.dash/app/cdash/static/sass/bootstrap/_breadcrumb.scss
@@ -0,0 +1,40 @@
+.breadcrumb {
+ // scss-docs-start breadcrumb-css-vars
+ --#{$prefix}breadcrumb-padding-x: #{$breadcrumb-padding-x};
+ --#{$prefix}breadcrumb-padding-y: #{$breadcrumb-padding-y};
+ --#{$prefix}breadcrumb-margin-bottom: #{$breadcrumb-margin-bottom};
+ @include rfs($breadcrumb-font-size, --#{$prefix}breadcrumb-font-size);
+ --#{$prefix}breadcrumb-bg: #{$breadcrumb-bg};
+ --#{$prefix}breadcrumb-border-radius: #{$breadcrumb-border-radius};
+ --#{$prefix}breadcrumb-divider-color: #{$breadcrumb-divider-color};
+ --#{$prefix}breadcrumb-item-padding-x: #{$breadcrumb-item-padding-x};
+ --#{$prefix}breadcrumb-item-active-color: #{$breadcrumb-active-color};
+ // scss-docs-end breadcrumb-css-vars
+
+ display: flex;
+ flex-wrap: wrap;
+ padding: var(--#{$prefix}breadcrumb-padding-y) var(--#{$prefix}breadcrumb-padding-x);
+ margin-bottom: var(--#{$prefix}breadcrumb-margin-bottom);
+ @include font-size(var(--#{$prefix}breadcrumb-font-size));
+ list-style: none;
+ background-color: var(--#{$prefix}breadcrumb-bg);
+ @include border-radius(var(--#{$prefix}breadcrumb-border-radius));
+}
+
+.breadcrumb-item {
+ // The separator between breadcrumbs (by default, a forward-slash: "/")
+ + .breadcrumb-item {
+ padding-left: var(--#{$prefix}breadcrumb-item-padding-x);
+
+ &::before {
+ float: left; // Suppress inline spacings and underlining of the separator
+ padding-right: var(--#{$prefix}breadcrumb-item-padding-x);
+ color: var(--#{$prefix}breadcrumb-divider-color);
+ content: var(--#{$prefix}breadcrumb-divider, escape-svg($breadcrumb-divider)) #{"/* rtl:"} var(--#{$prefix}breadcrumb-divider, escape-svg($breadcrumb-divider-flipped)) #{"*/"};
+ }
+ }
+
+ &.active {
+ color: var(--#{$prefix}breadcrumb-item-active-color);
+ }
+}
diff --git a/csit.infra.dash/app/cdash/static/sass/bootstrap/_button-group.scss b/csit.infra.dash/app/cdash/static/sass/bootstrap/_button-group.scss
new file mode 100644
index 0000000000..79b100cbfb
--- /dev/null
+++ b/csit.infra.dash/app/cdash/static/sass/bootstrap/_button-group.scss
@@ -0,0 +1,142 @@
+// Make the div behave like a button
+.btn-group,
+.btn-group-vertical {
+ position: relative;
+ display: inline-flex;
+ vertical-align: middle; // match .btn alignment given font-size hack above
+
+ > .btn {
+ position: relative;
+ flex: 1 1 auto;
+ }
+
+ // Bring the hover, focused, and "active" buttons to the front to overlay
+ // the borders properly
+ > .btn-check:checked + .btn,
+ > .btn-check:focus + .btn,
+ > .btn:hover,
+ > .btn:focus,
+ > .btn:active,
+ > .btn.active {
+ z-index: 1;
+ }
+}
+
+// Optional: Group multiple button groups together for a toolbar
+.btn-toolbar {
+ display: flex;
+ flex-wrap: wrap;
+ justify-content: flex-start;
+
+ .input-group {
+ width: auto;
+ }
+}
+
+.btn-group {
+ @include border-radius($btn-border-radius);
+
+ // Prevent double borders when buttons are next to each other
+ > :not(.btn-check:first-child) + .btn,
+ > .btn-group:not(:first-child) {
+ margin-left: -$btn-border-width;
+ }
+
+ // Reset rounded corners
+ > .btn:not(:last-child):not(.dropdown-toggle),
+ > .btn.dropdown-toggle-split:first-child,
+ > .btn-group:not(:last-child) > .btn {
+ @include border-end-radius(0);
+ }
+
+ // The left radius should be 0 if the button is:
+ // - the "third or more" child
+ // - the second child and the previous element isn't `.btn-check` (making it the first child visually)
+ // - part of a btn-group which isn't the first child
+ > .btn:nth-child(n + 3),
+ > :not(.btn-check) + .btn,
+ > .btn-group:not(:first-child) > .btn {
+ @include border-start-radius(0);
+ }
+}
+
+// Sizing
+//
+// Remix the default button sizing classes into new ones for easier manipulation.
+
+.btn-group-sm > .btn { @extend .btn-sm; }
+.btn-group-lg > .btn { @extend .btn-lg; }
+
+
+//
+// Split button dropdowns
+//
+
+.dropdown-toggle-split {
+ padding-right: $btn-padding-x * .75;
+ padding-left: $btn-padding-x * .75;
+
+ &::after,
+ .dropup &::after,
+ .dropend &::after {
+ margin-left: 0;
+ }
+
+ .dropstart &::before {
+ margin-right: 0;
+ }
+}
+
+.btn-sm + .dropdown-toggle-split {
+ padding-right: $btn-padding-x-sm * .75;
+ padding-left: $btn-padding-x-sm * .75;
+}
+
+.btn-lg + .dropdown-toggle-split {
+ padding-right: $btn-padding-x-lg * .75;
+ padding-left: $btn-padding-x-lg * .75;
+}
+
+
+// The clickable button for toggling the menu
+// Set the same inset shadow as the :active state
+.btn-group.show .dropdown-toggle {
+ @include box-shadow($btn-active-box-shadow);
+
+ // Show no shadow for `.btn-link` since it has no other button styles.
+ &.btn-link {
+ @include box-shadow(none);
+ }
+}
+
+
+//
+// Vertical button groups
+//
+
+.btn-group-vertical {
+ flex-direction: column;
+ align-items: flex-start;
+ justify-content: center;
+
+ > .btn,
+ > .btn-group {
+ width: 100%;
+ }
+
+ > .btn:not(:first-child),
+ > .btn-group:not(:first-child) {
+ margin-top: -$btn-border-width;
+ }
+
+ // Reset rounded corners
+ > .btn:not(:last-child):not(.dropdown-toggle),
+ > .btn-group:not(:last-child) > .btn {
+ @include border-bottom-radius(0);
+ }
+
+ > .btn ~ .btn,
+ > .btn-group:not(:first-child) > .btn {
+ @include border-top-radius(0);
+ }
+}
diff --git a/csit.infra.dash/app/cdash/static/sass/bootstrap/_buttons.scss b/csit.infra.dash/app/cdash/static/sass/bootstrap/_buttons.scss
new file mode 100644
index 0000000000..c2d0773516
--- /dev/null
+++ b/csit.infra.dash/app/cdash/static/sass/bootstrap/_buttons.scss
@@ -0,0 +1,201 @@
+//
+// Base styles
+//
+
+.btn {
+ // scss-docs-start btn-css-vars
+ --#{$prefix}btn-padding-x: #{$btn-padding-x};
+ --#{$prefix}btn-padding-y: #{$btn-padding-y};
+ --#{$prefix}btn-font-family: #{$btn-font-family};
+ @include rfs($btn-font-size, --#{$prefix}btn-font-size);
+ --#{$prefix}btn-font-weight: #{$btn-font-weight};
+ --#{$prefix}btn-line-height: #{$btn-line-height};
+ --#{$prefix}btn-color: #{$body-color};
+ --#{$prefix}btn-bg: transparent;
+ --#{$prefix}btn-border-width: #{$btn-border-width};
+ --#{$prefix}btn-border-color: transparent;
+ --#{$prefix}btn-border-radius: #{$btn-border-radius};
+ --#{$prefix}btn-hover-border-color: transparent;
+ --#{$prefix}btn-box-shadow: #{$btn-box-shadow};
+ --#{$prefix}btn-disabled-opacity: #{$btn-disabled-opacity};
+ --#{$prefix}btn-focus-box-shadow: 0 0 0 #{$btn-focus-width} rgba(var(--#{$prefix}btn-focus-shadow-rgb), .5);
+ // scss-docs-end btn-css-vars
+
+ display: inline-block;
+ padding: var(--#{$prefix}btn-padding-y) var(--#{$prefix}btn-padding-x);
+ font-family: var(--#{$prefix}btn-font-family);
+ @include font-size(var(--#{$prefix}btn-font-size));
+ font-weight: var(--#{$prefix}btn-font-weight);
+ line-height: var(--#{$prefix}btn-line-height);
+ color: var(--#{$prefix}btn-color);
+ text-align: center;
+ text-decoration: if($link-decoration == none, null, none);
+ white-space: $btn-white-space;
+ vertical-align: middle;
+ cursor: if($enable-button-pointers, pointer, null);
+ user-select: none;
+ border: var(--#{$prefix}btn-border-width) solid var(--#{$prefix}btn-border-color);
+ @include border-radius(var(--#{$prefix}btn-border-radius));
+ @include gradient-bg(var(--#{$prefix}btn-bg));
+ @include box-shadow(var(--#{$prefix}btn-box-shadow));
+ @include transition($btn-transition);
+
+ :not(.btn-check) + &:hover,
+ &:first-child:hover {
+ color: var(--#{$prefix}btn-hover-color);
+ text-decoration: if($link-hover-decoration == underline, none, null);
+ background-color: var(--#{$prefix}btn-hover-bg);
+ border-color: var(--#{$prefix}btn-hover-border-color);
+ }
+
+ &:focus-visible {
+ color: var(--#{$prefix}btn-hover-color);
+ @include gradient-bg(var(--#{$prefix}btn-hover-bg));
+ border-color: var(--#{$prefix}btn-hover-border-color);
+ outline: 0;
+ // Avoid using mixin so we can pass custom focus shadow properly
+ @if $enable-shadows {
+ box-shadow: var(--#{$prefix}btn-box-shadow), var(--#{$prefix}btn-focus-box-shadow);
+ } @else {
+ box-shadow: var(--#{$prefix}btn-focus-box-shadow);
+ }
+ }
+
+ .btn-check:focus-visible + & {
+ border-color: var(--#{$prefix}btn-hover-border-color);
+ outline: 0;
+ // Avoid using mixin so we can pass custom focus shadow properly
+ @if $enable-shadows {
+ box-shadow: var(--#{$prefix}btn-box-shadow), var(--#{$prefix}btn-focus-box-shadow);
+ } @else {
+ box-shadow: var(--#{$prefix}btn-focus-box-shadow);
+ }
+ }
+
+ .btn-check:checked + &,
+ :not(.btn-check) + &:active,
+ &:first-child:active,
+ &.active,
+ &.show {
+ color: var(--#{$prefix}btn-active-color);
+ background-color: var(--#{$prefix}btn-active-bg);
+ // Remove CSS gradients if they're enabled
+ background-image: if($enable-gradients, none, null);
+ border-color: var(--#{$prefix}btn-active-border-color);
+ @include box-shadow(var(--#{$prefix}btn-active-shadow));
+
+ &:focus-visible {
+ // Avoid using mixin so we can pass custom focus shadow properly
+ @if $enable-shadows {
+ box-shadow: var(--#{$prefix}btn-active-shadow), var(--#{$prefix}btn-focus-box-shadow);
+ } @else {
+ box-shadow: var(--#{$prefix}btn-focus-box-shadow);
+ }
+ }
+ }
+
+ &:disabled,
+ &.disabled,
+ fieldset:disabled & {
+ color: var(--#{$prefix}btn-disabled-color);
+ pointer-events: none;
+ background-color: var(--#{$prefix}btn-disabled-bg);
+ background-image: if($enable-gradients, none, null);
+ border-color: var(--#{$prefix}btn-disabled-border-color);
+ opacity: var(--#{$prefix}btn-disabled-opacity);
+ @include box-shadow(none);
+ }
+}
+
+
+//
+// Alternate buttons
+//
+
+// scss-docs-start btn-variant-loops
+@each $color, $value in $theme-colors {
+ .btn-#{$color} {
+ @if $color == "light" {
+ @include button-variant(
+ $value,
+ $value,
+ $hover-background: shade-color($value, $btn-hover-bg-shade-amount),
+ $hover-border: shade-color($value, $btn-hover-border-shade-amount),
+ $active-background: shade-color($value, $btn-active-bg-shade-amount),
+ $active-border: shade-color($value, $btn-active-border-shade-amount)
+ );
+ } @else if $color == "dark" {
+ @include button-variant(
+ $value,
+ $value,
+ $hover-background: tint-color($value, $btn-hover-bg-tint-amount),
+ $hover-border: tint-color($value, $btn-hover-border-tint-amount),
+ $active-background: tint-color($value, $btn-active-bg-tint-amount),
+ $active-border: tint-color($value, $btn-active-border-tint-amount)
+ );
+ } @else {
+ @include button-variant($value, $value);
+ }
+ }
+}
+
+@each $color, $value in $theme-colors {
+ .btn-outline-#{$color} {
+ @include button-outline-variant($value);
+ }
+}
+// scss-docs-end btn-variant-loops
+
+
+//
+// Link buttons
+//
+
+// Make a button look and behave like a link
+.btn-link {
+ --#{$prefix}btn-font-weight: #{$font-weight-normal};
+ --#{$prefix}btn-color: #{$btn-link-color};
+ --#{$prefix}btn-bg: transparent;
+ --#{$prefix}btn-border-color: transparent;
+ --#{$prefix}btn-hover-color: #{$btn-link-hover-color};
+ --#{$prefix}btn-hover-border-color: transparent;
+ --#{$prefix}btn-active-color: #{$btn-link-hover-color};
+ --#{$prefix}btn-active-border-color: transparent;
+ --#{$prefix}btn-disabled-color: #{$btn-link-disabled-color};
+ --#{$prefix}btn-disabled-border-color: transparent;
+ --#{$prefix}btn-box-shadow: none;
+ --#{$prefix}btn-focus-shadow-rgb: #{to-rgb(mix(color-contrast($primary), $primary, 15%))};
+
+ text-decoration: $link-decoration;
+ @if $enable-gradients {
+ background-image: none;
+ }
+
+ &:hover,
+ &:focus-visible {
+ text-decoration: $link-hover-decoration;
+ }
+
+ &:focus-visible {
+ color: var(--#{$prefix}btn-color);
+ }
+
+ &:hover {
+ color: var(--#{$prefix}btn-hover-color);
+ }
+
+ // No need for an active state here
+}
+
+
+//
+// Button Sizes
+//
+
+.btn-lg {
+ @include button-size($btn-padding-y-lg, $btn-padding-x-lg, $btn-font-size-lg, $btn-border-radius-lg);
+}
+
+.btn-sm {
+ @include button-size($btn-padding-y-sm, $btn-padding-x-sm, $btn-font-size-sm, $btn-border-radius-sm);
+}
diff --git a/csit.infra.dash/app/cdash/static/sass/bootstrap/_card.scss b/csit.infra.dash/app/cdash/static/sass/bootstrap/_card.scss
new file mode 100644
index 0000000000..ce8c02f1f2
--- /dev/null
+++ b/csit.infra.dash/app/cdash/static/sass/bootstrap/_card.scss
@@ -0,0 +1,234 @@
+//
+// Base styles
+//
+
+.card {
+ // scss-docs-start card-css-vars
+ --#{$prefix}card-spacer-y: #{$card-spacer-y};
+ --#{$prefix}card-spacer-x: #{$card-spacer-x};
+ --#{$prefix}card-title-spacer-y: #{$card-title-spacer-y};
+ --#{$prefix}card-border-width: #{$card-border-width};
+ --#{$prefix}card-border-color: #{$card-border-color};
+ --#{$prefix}card-border-radius: #{$card-border-radius};
+ --#{$prefix}card-box-shadow: #{$card-box-shadow};
+ --#{$prefix}card-inner-border-radius: #{$card-inner-border-radius};
+ --#{$prefix}card-cap-padding-y: #{$card-cap-padding-y};
+ --#{$prefix}card-cap-padding-x: #{$card-cap-padding-x};
+ --#{$prefix}card-cap-bg: #{$card-cap-bg};
+ --#{$prefix}card-cap-color: #{$card-cap-color};
+ --#{$prefix}card-height: #{$card-height};
+ --#{$prefix}card-color: #{$card-color};
+ --#{$prefix}card-bg: #{$card-bg};
+ --#{$prefix}card-img-overlay-padding: #{$card-img-overlay-padding};
+ --#{$prefix}card-group-margin: #{$card-group-margin};
+ // scss-docs-end card-css-vars
+
+ position: relative;
+ display: flex;
+ flex-direction: column;
+ min-width: 0; // See https://github.com/twbs/bootstrap/pull/22740#issuecomment-305868106
+ height: var(--#{$prefix}card-height);
+ word-wrap: break-word;
+ background-color: var(--#{$prefix}card-bg);
+ background-clip: border-box;
+ border: var(--#{$prefix}card-border-width) solid var(--#{$prefix}card-border-color);
+ @include border-radius(var(--#{$prefix}card-border-radius));
+ @include box-shadow(var(--#{$prefix}card-box-shadow));
+
+ > hr {
+ margin-right: 0;
+ margin-left: 0;
+ }
+
+ > .list-group {
+ border-top: inherit;
+ border-bottom: inherit;
+
+ &:first-child {
+ border-top-width: 0;
+ @include border-top-radius(var(--#{$prefix}card-inner-border-radius));
+ }
+
+ &:last-child {
+ border-bottom-width: 0;
+ @include border-bottom-radius(var(--#{$prefix}card-inner-border-radius));
+ }
+ }
+
+ // Due to specificity of the above selector (`.card > .list-group`), we must
+ // use a child selector here to prevent double borders.
+ > .card-header + .list-group,
+ > .list-group + .card-footer {
+ border-top: 0;
+ }
+}
+
+.card-body {
+ // Enable `flex-grow: 1` for decks and groups so that card blocks take up
+ // as much space as possible, ensuring footers are aligned to the bottom.
+ flex: 1 1 auto;
+ padding: var(--#{$prefix}card-spacer-y) var(--#{$prefix}card-spacer-x);
+ color: var(--#{$prefix}card-color);
+}
+
+.card-title {
+ margin-bottom: var(--#{$prefix}card-title-spacer-y);
+}
+
+.card-subtitle {
+ margin-top: calc(-.5 * var(--#{$prefix}card-title-spacer-y)); // stylelint-disable-line function-disallowed-list
+ margin-bottom: 0;
+}
+
+.card-text:last-child {
+ margin-bottom: 0;
+}
+
+.card-link {
+ &:hover {
+ text-decoration: if($link-hover-decoration == underline, none, null);
+ }
+
+ + .card-link {
+ margin-left: var(--#{$prefix}card-spacer-x);
+ }
+}
+
+//
+// Optional textual caps
+//
+
+.card-header {
+ padding: var(--#{$prefix}card-cap-padding-y) var(--#{$prefix}card-cap-padding-x);
+ margin-bottom: 0; // Removes the default margin-bottom of <hN>
+ color: var(--#{$prefix}card-cap-color);
+ background-color: var(--#{$prefix}card-cap-bg);
+ border-bottom: var(--#{$prefix}card-border-width) solid var(--#{$prefix}card-border-color);
+
+ &:first-child {
+ @include border-radius(var(--#{$prefix}card-inner-border-radius) var(--#{$prefix}card-inner-border-radius) 0 0);
+ }
+}
+
+.card-footer {
+ padding: var(--#{$prefix}card-cap-padding-y) var(--#{$prefix}card-cap-padding-x);
+ color: var(--#{$prefix}card-cap-color);
+ background-color: var(--#{$prefix}card-cap-bg);
+ border-top: var(--#{$prefix}card-border-width) solid var(--#{$prefix}card-border-color);
+
+ &:last-child {
+ @include border-radius(0 0 var(--#{$prefix}card-inner-border-radius) var(--#{$prefix}card-inner-border-radius));
+ }
+}
+
+
+//
+// Header navs
+//
+
+.card-header-tabs {
+ margin-right: calc(-.5 * var(--#{$prefix}card-cap-padding-x)); // stylelint-disable-line function-disallowed-list
+ margin-bottom: calc(-1 * var(--#{$prefix}card-cap-padding-y)); // stylelint-disable-line function-disallowed-list
+ margin-left: calc(-.5 * var(--#{$prefix}card-cap-padding-x)); // stylelint-disable-line function-disallowed-list
+ border-bottom: 0;
+
+ .nav-link.active {
+ background-color: var(--#{$prefix}card-bg);
+ border-bottom-color: var(--#{$prefix}card-bg);
+ }
+}
+
+.card-header-pills {
+ margin-right: calc(-.5 * var(--#{$prefix}card-cap-padding-x)); // stylelint-disable-line function-disallowed-list
+ margin-left: calc(-.5 * var(--#{$prefix}card-cap-padding-x)); // stylelint-disable-line function-disallowed-list
+}
+
+// Card image
+.card-img-overlay {
+ position: absolute;
+ top: 0;
+ right: 0;
+ bottom: 0;
+ left: 0;
+ padding: var(--#{$prefix}card-img-overlay-padding);
+ @include border-radius(var(--#{$prefix}card-inner-border-radius));
+}
+
+.card-img,
+.card-img-top,
+.card-img-bottom {
+ width: 100%; // Required because we use flexbox and this inherently applies align-self: stretch
+}
+
+.card-img,
+.card-img-top {
+ @include border-top-radius(var(--#{$prefix}card-inner-border-radius));
+}
+
+.card-img,
+.card-img-bottom {
+ @include border-bottom-radius(var(--#{$prefix}card-inner-border-radius));
+}
+
+
+//
+// Card groups
+//
+
+.card-group {
+ // The child selector allows nested `.card` within `.card-group`
+ // to display properly.
+ > .card {
+ margin-bottom: var(--#{$prefix}card-group-margin);
+ }
+
+ @include media-breakpoint-up(sm) {
+ display: flex;
+ flex-flow: row wrap;
+ // The child selector allows nested `.card` within `.card-group`
+ // to display properly.
+ > .card {
+ // Flexbugs #4: https://github.com/philipwalton/flexbugs#flexbug-4
+ flex: 1 0 0%;
+ margin-bottom: 0;
+
+ + .card {
+ margin-left: 0;
+ border-left: 0;
+ }
+
+ // Handle rounded corners
+ @if $enable-rounded {
+ &:not(:last-child) {
+ @include border-end-radius(0);
+
+ .card-img-top,
+ .card-header {
+ // stylelint-disable-next-line property-disallowed-list
+ border-top-right-radius: 0;
+ }
+ .card-img-bottom,
+ .card-footer {
+ // stylelint-disable-next-line property-disallowed-list
+ border-bottom-right-radius: 0;
+ }
+ }
+
+ &:not(:first-child) {
+ @include border-start-radius(0);
+
+ .card-img-top,
+ .card-header {
+ // stylelint-disable-next-line property-disallowed-list
+ border-top-left-radius: 0;
+ }
+ .card-img-bottom,
+ .card-footer {
+ // stylelint-disable-next-line property-disallowed-list
+ border-bottom-left-radius: 0;
+ }
+ }
+ }
+ }
+ }
+}
diff --git a/csit.infra.dash/app/cdash/static/sass/bootstrap/_carousel.scss b/csit.infra.dash/app/cdash/static/sass/bootstrap/_carousel.scss
new file mode 100644
index 0000000000..3d8fb15a06
--- /dev/null
+++ b/csit.infra.dash/app/cdash/static/sass/bootstrap/_carousel.scss
@@ -0,0 +1,229 @@
+// Notes on the classes:
+//
+// 1. .carousel.pointer-event should ideally be pan-y (to allow for users to scroll vertically)
+// even when their scroll action started on a carousel, but for compatibility (with Firefox)
+// we're preventing all actions instead
+// 2. The .carousel-item-start and .carousel-item-end is used to indicate where
+// the active slide is heading.
+// 3. .active.carousel-item is the current slide.
+// 4. .active.carousel-item-start and .active.carousel-item-end is the current
+// slide in its in-transition state. Only one of these occurs at a time.
+// 5. .carousel-item-next.carousel-item-start and .carousel-item-prev.carousel-item-end
+// is the upcoming slide in transition.
+
+.carousel {
+ position: relative;
+}
+
+.carousel.pointer-event {
+ touch-action: pan-y;
+}
+
+.carousel-inner {
+ position: relative;
+ width: 100%;
+ overflow: hidden;
+ @include clearfix();
+}
+
+.carousel-item {
+ position: relative;
+ display: none;
+ float: left;
+ width: 100%;
+ margin-right: -100%;
+ backface-visibility: hidden;
+ @include transition($carousel-transition);
+}
+
+.carousel-item.active,
+.carousel-item-next,
+.carousel-item-prev {
+ display: block;
+}
+
+/* rtl:begin:ignore */
+.carousel-item-next:not(.carousel-item-start),
+.active.carousel-item-end {
+ transform: translateX(100%);
+}
+
+.carousel-item-prev:not(.carousel-item-end),
+.active.carousel-item-start {
+ transform: translateX(-100%);
+}
+
+/* rtl:end:ignore */
+
+
+//
+// Alternate transitions
+//
+
+.carousel-fade {
+ .carousel-item {
+ opacity: 0;
+ transition-property: opacity;
+ transform: none;
+ }
+
+ .carousel-item.active,
+ .carousel-item-next.carousel-item-start,
+ .carousel-item-prev.carousel-item-end {
+ z-index: 1;
+ opacity: 1;
+ }
+
+ .active.carousel-item-start,
+ .active.carousel-item-end {
+ z-index: 0;
+ opacity: 0;
+ @include transition(opacity 0s $carousel-transition-duration);
+ }
+}
+
+
+//
+// Left/right controls for nav
+//
+
+.carousel-control-prev,
+.carousel-control-next {
+ position: absolute;
+ top: 0;
+ bottom: 0;
+ z-index: 1;
+ // Use flex for alignment (1-3)
+ display: flex; // 1. allow flex styles
+ align-items: center; // 2. vertically center contents
+ justify-content: center; // 3. horizontally center contents
+ width: $carousel-control-width;
+ padding: 0;
+ color: $carousel-control-color;
+ text-align: center;
+ background: none;
+ border: 0;
+ opacity: $carousel-control-opacity;
+ @include transition($carousel-control-transition);
+
+ // Hover/focus state
+ &:hover,
+ &:focus {
+ color: $carousel-control-color;
+ text-decoration: none;
+ outline: 0;
+ opacity: $carousel-control-hover-opacity;
+ }
+}
+.carousel-control-prev {
+ left: 0;
+ background-image: if($enable-gradients, linear-gradient(90deg, rgba($black, .25), rgba($black, .001)), null);
+}
+.carousel-control-next {
+ right: 0;
+ background-image: if($enable-gradients, linear-gradient(270deg, rgba($black, .25), rgba($black, .001)), null);
+}
+
+// Icons for within
+.carousel-control-prev-icon,
+.carousel-control-next-icon {
+ display: inline-block;
+ width: $carousel-control-icon-width;
+ height: $carousel-control-icon-width;
+ background-repeat: no-repeat;
+ background-position: 50%;
+ background-size: 100% 100%;
+}
+
+/* rtl:options: {
+ "autoRename": true,
+ "stringMap":[ {
+ "name" : "prev-next",
+ "search" : "prev",
+ "replace" : "next"
+ } ]
+} */
+.carousel-control-prev-icon {
+ background-image: escape-svg($carousel-control-prev-icon-bg);
+}
+.carousel-control-next-icon {
+ background-image: escape-svg($carousel-control-next-icon-bg);
+}
+
+// Optional indicator pips/controls
+//
+// Add a container (such as a list) with the following class and add an item (ideally a focusable control,
+// like a button) with data-bs-target for each slide your carousel holds.
+
+.carousel-indicators {
+ position: absolute;
+ right: 0;
+ bottom: 0;
+ left: 0;
+ z-index: 2;
+ display: flex;
+ justify-content: center;
+ padding: 0;
+ // Use the .carousel-control's width as margin so we don't overlay those
+ margin-right: $carousel-control-width;
+ margin-bottom: 1rem;
+ margin-left: $carousel-control-width;
+ list-style: none;
+
+ [data-bs-target] {
+ box-sizing: content-box;
+ flex: 0 1 auto;
+ width: $carousel-indicator-width;
+ height: $carousel-indicator-height;
+ padding: 0;
+ margin-right: $carousel-indicator-spacer;
+ margin-left: $carousel-indicator-spacer;
+ text-indent: -999px;
+ cursor: pointer;
+ background-color: $carousel-indicator-active-bg;
+ background-clip: padding-box;
+ border: 0;
+ // Use transparent borders to increase the hit area by 10px on top and bottom.
+ border-top: $carousel-indicator-hit-area-height solid transparent;
+ border-bottom: $carousel-indicator-hit-area-height solid transparent;
+ opacity: $carousel-indicator-opacity;
+ @include transition($carousel-indicator-transition);
+ }
+
+ .active {
+ opacity: $carousel-indicator-active-opacity;
+ }
+}
+
+
+// Optional captions
+//
+//
+
+.carousel-caption {
+ position: absolute;
+ right: (100% - $carousel-caption-width) * .5;
+ bottom: $carousel-caption-spacer;
+ left: (100% - $carousel-caption-width) * .5;
+ padding-top: $carousel-caption-padding-y;
+ padding-bottom: $carousel-caption-padding-y;
+ color: $carousel-caption-color;
+ text-align: center;
+}
+
+// Dark mode carousel
+
+.carousel-dark {
+ .carousel-control-prev-icon,
+ .carousel-control-next-icon {
+ filter: $carousel-dark-control-icon-filter;
+ }
+
+ .carousel-indicators [data-bs-target] {
+ background-color: $carousel-dark-indicator-active-bg;
+ }
+
+ .carousel-caption {
+ color: $carousel-dark-caption-color;
+ }
+}
diff --git a/csit.infra.dash/app/cdash/static/sass/bootstrap/_close.scss b/csit.infra.dash/app/cdash/static/sass/bootstrap/_close.scss
new file mode 100644
index 0000000000..a0813de8d3
--- /dev/null
+++ b/csit.infra.dash/app/cdash/static/sass/bootstrap/_close.scss
@@ -0,0 +1,40 @@
+// Transparent background and border properties included for button version.
+// iOS requires the button element instead of an anchor tag.
+// If you want the anchor version, it requires `href="#"`.
+// See https://developer.mozilla.org/en-US/docs/Web/Events/click#Safari_Mobile
+
+.btn-close {
+ box-sizing: content-box;
+ width: $btn-close-width;
+ height: $btn-close-height;
+ padding: $btn-close-padding-y $btn-close-padding-x;
+ color: $btn-close-color;
+ background: transparent escape-svg($btn-close-bg) center / $btn-close-width auto no-repeat; // include transparent for button elements
+ border: 0; // for button elements
+ @include border-radius();
+ opacity: $btn-close-opacity;
+
+ // Override <a>'s hover style
+ &:hover {
+ color: $btn-close-color;
+ text-decoration: none;
+ opacity: $btn-close-hover-opacity;
+ }
+
+ &:focus {
+ outline: 0;
+ box-shadow: $btn-close-focus-shadow;
+ opacity: $btn-close-focus-opacity;
+ }
+
+ &:disabled,
+ &.disabled {
+ pointer-events: none;
+ user-select: none;
+ opacity: $btn-close-disabled-opacity;
+ }
+}
+
+.btn-close-white {
+ filter: $btn-close-white-filter;
+}
diff --git a/csit.infra.dash/app/cdash/static/sass/bootstrap/_containers.scss b/csit.infra.dash/app/cdash/static/sass/bootstrap/_containers.scss
new file mode 100644
index 0000000000..83b31381bf
--- /dev/null
+++ b/csit.infra.dash/app/cdash/static/sass/bootstrap/_containers.scss
@@ -0,0 +1,41 @@
+// Container widths
+//
+// Set the container width, and override it for fixed navbars in media queries.
+
+@if $enable-container-classes {
+ // Single container class with breakpoint max-widths
+ .container,
+ // 100% wide container at all breakpoints
+ .container-fluid {
+ @include make-container();
+ }
+
+ // Responsive containers that are 100% wide until a breakpoint
+ @each $breakpoint, $container-max-width in $container-max-widths {
+ .container-#{$breakpoint} {
+ @extend .container-fluid;
+ }
+
+ @include media-breakpoint-up($breakpoint, $grid-breakpoints) {
+ %responsive-container-#{$breakpoint} {
+ max-width: $container-max-width;
+ }
+
+ // Extend each breakpoint which is smaller or equal to the current breakpoint
+ $extend-breakpoint: true;
+
+ @each $name, $width in $grid-breakpoints {
+ @if ($extend-breakpoint) {
+ .container#{breakpoint-infix($name, $grid-breakpoints)} {
+ @extend %responsive-container-#{$breakpoint};
+ }
+
+ // Once the current breakpoint is reached, stop extending
+ @if ($breakpoint == $name) {
+ $extend-breakpoint: false;
+ }
+ }
+ }
+ }
+ }
+}
diff --git a/csit.infra.dash/app/cdash/static/sass/bootstrap/_dropdown.scss b/csit.infra.dash/app/cdash/static/sass/bootstrap/_dropdown.scss
new file mode 100644
index 0000000000..8899d25a0d
--- /dev/null
+++ b/csit.infra.dash/app/cdash/static/sass/bootstrap/_dropdown.scss
@@ -0,0 +1,249 @@
+// The dropdown wrapper (`<div>`)
+.dropup,
+.dropend,
+.dropdown,
+.dropstart,
+.dropup-center,
+.dropdown-center {
+ position: relative;
+}
+
+.dropdown-toggle {
+ white-space: nowrap;
+
+ // Generate the caret automatically
+ @include caret();
+}
+
+// The dropdown menu
+.dropdown-menu {
+ // scss-docs-start dropdown-css-vars
+ --#{$prefix}dropdown-zindex: #{$zindex-dropdown};
+ --#{$prefix}dropdown-min-width: #{$dropdown-min-width};
+ --#{$prefix}dropdown-padding-x: #{$dropdown-padding-x};
+ --#{$prefix}dropdown-padding-y: #{$dropdown-padding-y};
+ --#{$prefix}dropdown-spacer: #{$dropdown-spacer};
+ @include rfs($dropdown-font-size, --#{$prefix}dropdown-font-size);
+ --#{$prefix}dropdown-color: #{$dropdown-color};
+ --#{$prefix}dropdown-bg: #{$dropdown-bg};
+ --#{$prefix}dropdown-border-color: #{$dropdown-border-color};
+ --#{$prefix}dropdown-border-radius: #{$dropdown-border-radius};
+ --#{$prefix}dropdown-border-width: #{$dropdown-border-width};
+ --#{$prefix}dropdown-inner-border-radius: #{$dropdown-inner-border-radius};
+ --#{$prefix}dropdown-divider-bg: #{$dropdown-divider-bg};
+ --#{$prefix}dropdown-divider-margin-y: #{$dropdown-divider-margin-y};
+ --#{$prefix}dropdown-box-shadow: #{$dropdown-box-shadow};
+ --#{$prefix}dropdown-link-color: #{$dropdown-link-color};
+ --#{$prefix}dropdown-link-hover-color: #{$dropdown-link-hover-color};
+ --#{$prefix}dropdown-link-hover-bg: #{$dropdown-link-hover-bg};
+ --#{$prefix}dropdown-link-active-color: #{$dropdown-link-active-color};
+ --#{$prefix}dropdown-link-active-bg: #{$dropdown-link-active-bg};
+ --#{$prefix}dropdown-link-disabled-color: #{$dropdown-link-disabled-color};
+ --#{$prefix}dropdown-item-padding-x: #{$dropdown-item-padding-x};
+ --#{$prefix}dropdown-item-padding-y: #{$dropdown-item-padding-y};
+ --#{$prefix}dropdown-header-color: #{$dropdown-header-color};
+ --#{$prefix}dropdown-header-padding-x: #{$dropdown-header-padding-x};
+ --#{$prefix}dropdown-header-padding-y: #{$dropdown-header-padding-y};
+ // scss-docs-end dropdown-css-vars
+
+ position: absolute;
+ z-index: var(--#{$prefix}dropdown-zindex);
+ display: none; // none by default, but block on "open" of the menu
+ min-width: var(--#{$prefix}dropdown-min-width);
+ padding: var(--#{$prefix}dropdown-padding-y) var(--#{$prefix}dropdown-padding-x);
+ margin: 0; // Override default margin of ul
+ @include font-size(var(--#{$prefix}dropdown-font-size));
+ color: var(--#{$prefix}dropdown-color);
+ text-align: left; // Ensures proper alignment if parent has it changed (e.g., modal footer)
+ list-style: none;
+ background-color: var(--#{$prefix}dropdown-bg);
+ background-clip: padding-box;
+ border: var(--#{$prefix}dropdown-border-width) solid var(--#{$prefix}dropdown-border-color);
+ @include border-radius(var(--#{$prefix}dropdown-border-radius));
+ @include box-shadow(var(--#{$prefix}dropdown-box-shadow));
+
+ &[data-bs-popper] {
+ top: 100%;
+ left: 0;
+ margin-top: var(--#{$prefix}dropdown-spacer);
+ }
+
+ @if $dropdown-padding-y == 0 {
+ > .dropdown-item:first-child,
+ > li:first-child .dropdown-item {
+ @include border-top-radius(var(--#{$prefix}dropdown-inner-border-radius));
+ }
+ > .dropdown-item:last-child,
+ > li:last-child .dropdown-item {
+ @include border-bottom-radius(var(--#{$prefix}dropdown-inner-border-radius));
+ }
+
+ }
+}
+
+// scss-docs-start responsive-breakpoints
+// We deliberately hardcode the `bs-` prefix because we check
+// this custom property in JS to determine Popper's positioning
+
+@each $breakpoint in map-keys($grid-breakpoints) {
+ @include media-breakpoint-up($breakpoint) {
+ $infix: breakpoint-infix($breakpoint, $grid-breakpoints);
+
+ .dropdown-menu#{$infix}-start {
+ --bs-position: start;
+
+ &[data-bs-popper] {
+ right: auto;
+ left: 0;
+ }
+ }
+
+ .dropdown-menu#{$infix}-end {
+ --bs-position: end;
+
+ &[data-bs-popper] {
+ right: 0;
+ left: auto;
+ }
+ }
+ }
+}
+// scss-docs-end responsive-breakpoints
+
+// Allow for dropdowns to go bottom up (aka, dropup-menu)
+// Just add .dropup after the standard .dropdown class and you're set.
+.dropup {
+ .dropdown-menu[data-bs-popper] {
+ top: auto;
+ bottom: 100%;
+ margin-top: 0;
+ margin-bottom: var(--#{$prefix}dropdown-spacer);
+ }
+
+ .dropdown-toggle {
+ @include caret(up);
+ }
+}
+
+.dropend {
+ .dropdown-menu[data-bs-popper] {
+ top: 0;
+ right: auto;
+ left: 100%;
+ margin-top: 0;
+ margin-left: var(--#{$prefix}dropdown-spacer);
+ }
+
+ .dropdown-toggle {
+ @include caret(end);
+ &::after {
+ vertical-align: 0;
+ }
+ }
+}
+
+.dropstart {
+ .dropdown-menu[data-bs-popper] {
+ top: 0;
+ right: 100%;
+ left: auto;
+ margin-top: 0;
+ margin-right: var(--#{$prefix}dropdown-spacer);
+ }
+
+ .dropdown-toggle {
+ @include caret(start);
+ &::before {
+ vertical-align: 0;
+ }
+ }
+}
+
+
+// Dividers (basically an `<hr>`) within the dropdown
+.dropdown-divider {
+ height: 0;
+ margin: var(--#{$prefix}dropdown-divider-margin-y) 0;
+ overflow: hidden;
+ border-top: 1px solid var(--#{$prefix}dropdown-divider-bg);
+ opacity: 1; // Revisit in v6 to de-dupe styles that conflict with <hr> element
+}
+
+// Links, buttons, and more within the dropdown menu
+//
+// `<button>`-specific styles are denoted with `// For <button>s`
+.dropdown-item {
+ display: block;
+ width: 100%; // For `<button>`s
+ padding: var(--#{$prefix}dropdown-item-padding-y) var(--#{$prefix}dropdown-item-padding-x);
+ clear: both;
+ font-weight: $font-weight-normal;
+ color: var(--#{$prefix}dropdown-link-color);
+ text-align: inherit; // For `<button>`s
+ text-decoration: if($link-decoration == none, null, none);
+ white-space: nowrap; // prevent links from randomly breaking onto new lines
+ background-color: transparent; // For `<button>`s
+ border: 0; // For `<button>`s
+
+ &:hover,
+ &:focus {
+ color: var(--#{$prefix}dropdown-link-hover-color);
+ text-decoration: if($link-hover-decoration == underline, none, null);
+ @include gradient-bg(var(--#{$prefix}dropdown-link-hover-bg));
+ }
+
+ &.active,
+ &:active {
+ color: var(--#{$prefix}dropdown-link-active-color);
+ text-decoration: none;
+ @include gradient-bg(var(--#{$prefix}dropdown-link-active-bg));
+ }
+
+ &.disabled,
+ &:disabled {
+ color: var(--#{$prefix}dropdown-link-disabled-color);
+ pointer-events: none;
+ background-color: transparent;
+ // Remove CSS gradients if they're enabled
+ background-image: if($enable-gradients, none, null);
+ }
+}
+
+.dropdown-menu.show {
+ display: block;
+}
+
+// Dropdown section headers
+.dropdown-header {
+ display: block;
+ padding: var(--#{$prefix}dropdown-header-padding-y) var(--#{$prefix}dropdown-header-padding-x);
+ margin-bottom: 0; // for use with heading elements
+ @include font-size($font-size-sm);
+ color: var(--#{$prefix}dropdown-header-color);
+ white-space: nowrap; // as with > li > a
+}
+
+// Dropdown text
+.dropdown-item-text {
+ display: block;
+ padding: var(--#{$prefix}dropdown-item-padding-y) var(--#{$prefix}dropdown-item-padding-x);
+ color: var(--#{$prefix}dropdown-link-color);
+}
+
+// Dark dropdowns
+.dropdown-menu-dark {
+ // scss-docs-start dropdown-dark-css-vars
+ --#{$prefix}dropdown-color: #{$dropdown-dark-color};
+ --#{$prefix}dropdown-bg: #{$dropdown-dark-bg};
+ --#{$prefix}dropdown-border-color: #{$dropdown-dark-border-color};
+ --#{$prefix}dropdown-box-shadow: #{$dropdown-dark-box-shadow};
+ --#{$prefix}dropdown-link-color: #{$dropdown-dark-link-color};
+ --#{$prefix}dropdown-link-hover-color: #{$dropdown-dark-link-hover-color};
+ --#{$prefix}dropdown-divider-bg: #{$dropdown-dark-divider-bg};
+ --#{$prefix}dropdown-link-hover-bg: #{$dropdown-dark-link-hover-bg};
+ --#{$prefix}dropdown-link-active-color: #{$dropdown-dark-link-active-color};
+ --#{$prefix}dropdown-link-active-bg: #{$dropdown-dark-link-active-bg};
+ --#{$prefix}dropdown-link-disabled-color: #{$dropdown-dark-link-disabled-color};
+ --#{$prefix}dropdown-header-color: #{$dropdown-dark-header-color};
+ // scss-docs-end dropdown-dark-css-vars
+}
diff --git a/csit.infra.dash/app/cdash/static/sass/bootstrap/_forms.scss b/csit.infra.dash/app/cdash/static/sass/bootstrap/_forms.scss
new file mode 100644
index 0000000000..7b17d849ac
--- /dev/null
+++ b/csit.infra.dash/app/cdash/static/sass/bootstrap/_forms.scss
@@ -0,0 +1,9 @@
+@import "forms/labels";
+@import "forms/form-text";
+@import "forms/form-control";
+@import "forms/form-select";
+@import "forms/form-check";
+@import "forms/form-range";
+@import "forms/floating-labels";
+@import "forms/input-group";
+@import "forms/validation";
diff --git a/csit.infra.dash/app/cdash/static/sass/bootstrap/_functions.scss b/csit.infra.dash/app/cdash/static/sass/bootstrap/_functions.scss
new file mode 100644
index 0000000000..969a4b08bf
--- /dev/null
+++ b/csit.infra.dash/app/cdash/static/sass/bootstrap/_functions.scss
@@ -0,0 +1,302 @@
+// Bootstrap functions
+//
+// Utility mixins and functions for evaluating source code across our variables, maps, and mixins.
+
+// Ascending
+// Used to evaluate Sass maps like our grid breakpoints.
+@mixin _assert-ascending($map, $map-name) {
+ $prev-key: null;
+ $prev-num: null;
+ @each $key, $num in $map {
+ @if $prev-num == null or unit($num) == "%" or unit($prev-num) == "%" {
+ // Do nothing
+ } @else if not comparable($prev-num, $num) {
+ @warn "Potentially invalid value for #{$map-name}: This map must be in ascending order, but key '#{$key}' has value #{$num} whose unit makes it incomparable to #{$prev-num}, the value of the previous key '#{$prev-key}' !";
+ } @else if $prev-num >= $num {
+ @warn "Invalid value for #{$map-name}: This map must be in ascending order, but key '#{$key}' has value #{$num} which isn't greater than #{$prev-num}, the value of the previous key '#{$prev-key}' !";
+ }
+ $prev-key: $key;
+ $prev-num: $num;
+ }
+}
+
+// Starts at zero
+// Used to ensure the min-width of the lowest breakpoint starts at 0.
+@mixin _assert-starts-at-zero($map, $map-name: "$grid-breakpoints") {
+ @if length($map) > 0 {
+ $values: map-values($map);
+ $first-value: nth($values, 1);
+ @if $first-value != 0 {
+ @warn "First breakpoint in #{$map-name} must start at 0, but starts at #{$first-value}.";
+ }
+ }
+}
+
+// Colors
+@function to-rgb($value) {
+ @return red($value), green($value), blue($value);
+}
+
+// stylelint-disable scss/dollar-variable-pattern
+@function rgba-css-var($identifier, $target) {
+ @if $identifier == "body" and $target == "bg" {
+ @return rgba(var(--#{$prefix}#{$identifier}-bg-rgb), var(--#{$prefix}#{$target}-opacity));
+ } @if $identifier == "body" and $target == "text" {
+ @return rgba(var(--#{$prefix}#{$identifier}-color-rgb), var(--#{$prefix}#{$target}-opacity));
+ } @else {
+ @return rgba(var(--#{$prefix}#{$identifier}-rgb), var(--#{$prefix}#{$target}-opacity));
+ }
+}
+
+@function map-loop($map, $func, $args...) {
+ $_map: ();
+
+ @each $key, $value in $map {
+ // allow to pass the $key and $value of the map as an function argument
+ $_args: ();
+ @each $arg in $args {
+ $_args: append($_args, if($arg == "$key", $key, if($arg == "$value", $value, $arg)));
+ }
+
+ $_map: map-merge($_map, ($key: call(get-function($func), $_args...)));
+ }
+
+ @return $_map;
+}
+// stylelint-enable scss/dollar-variable-pattern
+
+@function varify($list) {
+ $result: null;
+ @each $entry in $list {
+ $result: append($result, var(--#{$prefix}#{$entry}), space);
+ }
+ @return $result;
+}
+
+// Internal Bootstrap function to turn maps into its negative variant.
+// It prefixes the keys with `n` and makes the value negative.
+@function negativify-map($map) {
+ $result: ();
+ @each $key, $value in $map {
+ @if $key != 0 {
+ $result: map-merge($result, ("n" + $key: (-$value)));
+ }
+ }
+ @return $result;
+}
+
+// Get multiple keys from a sass map
+@function map-get-multiple($map, $values) {
+ $result: ();
+ @each $key, $value in $map {
+ @if (index($values, $key) != null) {
+ $result: map-merge($result, ($key: $value));
+ }
+ }
+ @return $result;
+}
+
+// Merge multiple maps
+@function map-merge-multiple($maps...) {
+ $merged-maps: ();
+
+ @each $map in $maps {
+ $merged-maps: map-merge($merged-maps, $map);
+ }
+ @return $merged-maps;
+}
+
+// Replace `$search` with `$replace` in `$string`
+// Used on our SVG icon backgrounds for custom forms.
+//
+// @author Kitty Giraudel
+// @param {String} $string - Initial string
+// @param {String} $search - Substring to replace
+// @param {String} $replace ('') - New value
+// @return {String} - Updated string
+@function str-replace($string, $search, $replace: "") {
+ $index: str-index($string, $search);
+
+ @if $index {
+ @return str-slice($string, 1, $index - 1) + $replace + str-replace(str-slice($string, $index + str-length($search)), $search, $replace);
+ }
+
+ @return $string;
+}
+
+// See https://codepen.io/kevinweber/pen/dXWoRw
+//
+// Requires the use of quotes around data URIs.
+
+@function escape-svg($string) {
+ @if str-index($string, "data:image/svg+xml") {
+ @each $char, $encoded in $escaped-characters {
+ // Do not escape the url brackets
+ @if str-index($string, "url(") == 1 {
+ $string: url("#{str-replace(str-slice($string, 6, -3), $char, $encoded)}");
+ } @else {
+ $string: str-replace($string, $char, $encoded);
+ }
+ }
+ }
+
+ @return $string;
+}
+
+// Color contrast
+// See https://github.com/twbs/bootstrap/pull/30168
+
+// A list of pre-calculated numbers of pow(divide((divide($value, 255) + .055), 1.055), 2.4). (from 0 to 255)
+// stylelint-disable-next-line scss/dollar-variable-default, scss/dollar-variable-pattern
+$_luminance-list: .0008 .001 .0011 .0013 .0015 .0017 .002 .0022 .0025 .0027 .003 .0033 .0037 .004 .0044 .0048 .0052 .0056 .006 .0065 .007 .0075 .008 .0086 .0091 .0097 .0103 .011 .0116 .0123 .013 .0137 .0144 .0152 .016 .0168 .0176 .0185 .0194 .0203 .0212 .0222 .0232 .0242 .0252 .0262 .0273 .0284 .0296 .0307 .0319 .0331 .0343 .0356 .0369 .0382 .0395 .0409 .0423 .0437 .0452 .0467 .0482 .0497 .0513 .0529 .0545 .0561 .0578 .0595 .0612 .063 .0648 .0666 .0685 .0704 .0723 .0742 .0762 .0782 .0802 .0823 .0844 .0865 .0887 .0908 .0931 .0953 .0976 .0999 .1022 .1046 .107 .1095 .1119 .1144 .117 .1195 .1221 .1248 .1274 .1301 .1329 .1356 .1384 .1413 .1441 .147 .15 .1529 .1559 .159 .162 .1651 .1683 .1714 .1746 .1779 .1812 .1845 .1878 .1912 .1946 .1981 .2016 .2051 .2086 .2122 .2159 .2195 .2232 .227 .2307 .2346 .2384 .2423 .2462 .2502 .2542 .2582 .2623 .2664 .2705 .2747 .2789 .2831 .2874 .2918 .2961 .3005 .305 .3095 .314 .3185 .3231 .3278 .3325 .3372 .3419 .3467 .3515 .3564 .3613 .3663 .3712 .3763 .3813 .3864 .3916 .3968 .402 .4072 .4125 .4179 .4233 .4287 .4342 .4397 .4452 .4508 .4564 .4621 .4678 .4735 .4793 .4851 .491 .4969 .5029 .5089 .5149 .521 .5271 .5333 .5395 .5457 .552 .5583 .5647 .5711 .5776 .5841 .5906 .5972 .6038 .6105 .6172 .624 .6308 .6376 .6445 .6514 .6584 .6654 .6724 .6795 .6867 .6939 .7011 .7084 .7157 .7231 .7305 .7379 .7454 .7529 .7605 .7682 .7758 .7835 .7913 .7991 .807 .8148 .8228 .8308 .8388 .8469 .855 .8632 .8714 .8796 .8879 .8963 .9047 .9131 .9216 .9301 .9387 .9473 .956 .9647 .9734 .9823 .9911 1;
+
+@function color-contrast($background, $color-contrast-dark: $color-contrast-dark, $color-contrast-light: $color-contrast-light, $min-contrast-ratio: $min-contrast-ratio) {
+ $foregrounds: $color-contrast-light, $color-contrast-dark, $white, $black;
+ $max-ratio: 0;
+ $max-ratio-color: null;
+
+ @each $color in $foregrounds {
+ $contrast-ratio: contrast-ratio($background, $color);
+ @if $contrast-ratio > $min-contrast-ratio {
+ @return $color;
+ } @else if $contrast-ratio > $max-ratio {
+ $max-ratio: $contrast-ratio;
+ $max-ratio-color: $color;
+ }
+ }
+
+ @warn "Found no color leading to #{$min-contrast-ratio}:1 contrast ratio against #{$background}...";
+
+ @return $max-ratio-color;
+}
+
+@function contrast-ratio($background, $foreground: $color-contrast-light) {
+ $l1: luminance($background);
+ $l2: luminance(opaque($background, $foreground));
+
+ @return if($l1 > $l2, divide($l1 + .05, $l2 + .05), divide($l2 + .05, $l1 + .05));
+}
+
+// Return WCAG2.1 relative luminance
+// See https://www.w3.org/TR/WCAG/#dfn-relative-luminance
+// See https://www.w3.org/TR/WCAG/#dfn-contrast-ratio
+@function luminance($color) {
+ $rgb: (
+ "r": red($color),
+ "g": green($color),
+ "b": blue($color)
+ );
+
+ @each $name, $value in $rgb {
+ $value: if(divide($value, 255) < .03928, divide(divide($value, 255), 12.92), nth($_luminance-list, $value + 1));
+ $rgb: map-merge($rgb, ($name: $value));
+ }
+
+ @return (map-get($rgb, "r") * .2126) + (map-get($rgb, "g") * .7152) + (map-get($rgb, "b") * .0722);
+}
+
+// Return opaque color
+// opaque(#fff, rgba(0, 0, 0, .5)) => #808080
+@function opaque($background, $foreground) {
+ @return mix(rgba($foreground, 1), $background, opacity($foreground) * 100);
+}
+
+// scss-docs-start color-functions
+// Tint a color: mix a color with white
+@function tint-color($color, $weight) {
+ @return mix(white, $color, $weight);
+}
+
+// Shade a color: mix a color with black
+@function shade-color($color, $weight) {
+ @return mix(black, $color, $weight);
+}
+
+// Shade the color if the weight is positive, else tint it
+@function shift-color($color, $weight) {
+ @return if($weight > 0, shade-color($color, $weight), tint-color($color, -$weight));
+}
+// scss-docs-end color-functions
+
+// Return valid calc
+@function add($value1, $value2, $return-calc: true) {
+ @if $value1 == null {
+ @return $value2;
+ }
+
+ @if $value2 == null {
+ @return $value1;
+ }
+
+ @if type-of($value1) == number and type-of($value2) == number and comparable($value1, $value2) {
+ @return $value1 + $value2;
+ }
+
+ @return if($return-calc == true, calc(#{$value1} + #{$value2}), $value1 + unquote(" + ") + $value2);
+}
+
+@function subtract($value1, $value2, $return-calc: true) {
+ @if $value1 == null and $value2 == null {
+ @return null;
+ }
+
+ @if $value1 == null {
+ @return -$value2;
+ }
+
+ @if $value2 == null {
+ @return $value1;
+ }
+
+ @if type-of($value1) == number and type-of($value2) == number and comparable($value1, $value2) {
+ @return $value1 - $value2;
+ }
+
+ @if type-of($value2) != number {
+ $value2: unquote("(") + $value2 + unquote(")");
+ }
+
+ @return if($return-calc == true, calc(#{$value1} - #{$value2}), $value1 + unquote(" - ") + $value2);
+}
+
+@function divide($dividend, $divisor, $precision: 10) {
+ $sign: if($dividend > 0 and $divisor > 0 or $dividend < 0 and $divisor < 0, 1, -1);
+ $dividend: abs($dividend);
+ $divisor: abs($divisor);
+ @if $dividend == 0 {
+ @return 0;
+ }
+ @if $divisor == 0 {
+ @error "Cannot divide by 0";
+ }
+ $remainder: $dividend;
+ $result: 0;
+ $factor: 10;
+ @while ($remainder > 0 and $precision >= 0) {
+ $quotient: 0;
+ @while ($remainder >= $divisor) {
+ $remainder: $remainder - $divisor;
+ $quotient: $quotient + 1;
+ }
+ $result: $result * 10 + $quotient;
+ $factor: $factor * .1;
+ $remainder: $remainder * 10;
+ $precision: $precision - 1;
+ @if ($precision < 0 and $remainder >= $divisor * 5) {
+ $result: $result + 1;
+ }
+ }
+ $result: $result * $factor * $sign;
+ $dividend-unit: unit($dividend);
+ $divisor-unit: unit($divisor);
+ $unit-map: (
+ "px": 1px,
+ "rem": 1rem,
+ "em": 1em,
+ "%": 1%
+ );
+ @if ($dividend-unit != $divisor-unit and map-has-key($unit-map, $dividend-unit)) {
+ $result: $result * map-get($unit-map, $dividend-unit);
+ }
+ @return $result;
+}
diff --git a/csit.infra.dash/app/cdash/static/sass/bootstrap/_grid.scss b/csit.infra.dash/app/cdash/static/sass/bootstrap/_grid.scss
new file mode 100644
index 0000000000..0e0ba210ab
--- /dev/null
+++ b/csit.infra.dash/app/cdash/static/sass/bootstrap/_grid.scss
@@ -0,0 +1,33 @@
+// Row
+//
+// Rows contain your columns.
+
+@if $enable-grid-classes {
+ .row {
+ @include make-row();
+
+ > * {
+ @include make-col-ready();
+ }
+ }
+}
+
+@if $enable-cssgrid {
+ .grid {
+ display: grid;
+ grid-template-rows: repeat(var(--#{$prefix}rows, 1), 1fr);
+ grid-template-columns: repeat(var(--#{$prefix}columns, #{$grid-columns}), 1fr);
+ gap: var(--#{$prefix}gap, #{$grid-gutter-width});
+
+ @include make-cssgrid();
+ }
+}
+
+
+// Columns
+//
+// Common styles for small and large grid columns
+
+@if $enable-grid-classes {
+ @include make-grid-columns();
+}
diff --git a/csit.infra.dash/app/cdash/static/sass/bootstrap/_helpers.scss b/csit.infra.dash/app/cdash/static/sass/bootstrap/_helpers.scss
new file mode 100644
index 0000000000..644b693fbc
--- /dev/null
+++ b/csit.infra.dash/app/cdash/static/sass/bootstrap/_helpers.scss
@@ -0,0 +1,10 @@
+@import "helpers/clearfix";
+@import "helpers/color-bg";
+@import "helpers/colored-links";
+@import "helpers/ratio";
+@import "helpers/position";
+@import "helpers/stacks";
+@import "helpers/visually-hidden";
+@import "helpers/stretched-link";
+@import "helpers/text-truncation";
+@import "helpers/vr";
diff --git a/csit.infra.dash/app/cdash/static/sass/bootstrap/_images.scss b/csit.infra.dash/app/cdash/static/sass/bootstrap/_images.scss
new file mode 100644
index 0000000000..3d6a1014c4
--- /dev/null
+++ b/csit.infra.dash/app/cdash/static/sass/bootstrap/_images.scss
@@ -0,0 +1,42 @@
+// Responsive images (ensure images don't scale beyond their parents)
+//
+// This is purposefully opt-in via an explicit class rather than being the default for all `<img>`s.
+// We previously tried the "images are responsive by default" approach in Bootstrap v2,
+// and abandoned it in Bootstrap v3 because it breaks lots of third-party widgets (including Google Maps)
+// which weren't expecting the images within themselves to be involuntarily resized.
+// See also https://github.com/twbs/bootstrap/issues/18178
+.img-fluid {
+ @include img-fluid();
+}
+
+
+// Image thumbnails
+.img-thumbnail {
+ padding: $thumbnail-padding;
+ background-color: $thumbnail-bg;
+ border: $thumbnail-border-width solid $thumbnail-border-color;
+ @include border-radius($thumbnail-border-radius);
+ @include box-shadow($thumbnail-box-shadow);
+
+ // Keep them at most 100% wide
+ @include img-fluid();
+}
+
+//
+// Figures
+//
+
+.figure {
+ // Ensures the caption's text aligns with the image.
+ display: inline-block;
+}
+
+.figure-img {
+ margin-bottom: $spacer * .5;
+ line-height: 1;
+}
+
+.figure-caption {
+ @include font-size($figure-caption-font-size);
+ color: $figure-caption-color;
+}
diff --git a/csit.infra.dash/app/cdash/static/sass/bootstrap/_list-group.scss b/csit.infra.dash/app/cdash/static/sass/bootstrap/_list-group.scss
new file mode 100644
index 0000000000..c0ec16468d
--- /dev/null
+++ b/csit.infra.dash/app/cdash/static/sass/bootstrap/_list-group.scss
@@ -0,0 +1,192 @@
+// Base class
+//
+// Easily usable on <ul>, <ol>, or <div>.
+
+.list-group {
+ // scss-docs-start list-group-css-vars
+ --#{$prefix}list-group-color: #{$list-group-color};
+ --#{$prefix}list-group-bg: #{$list-group-bg};
+ --#{$prefix}list-group-border-color: #{$list-group-border-color};
+ --#{$prefix}list-group-border-width: #{$list-group-border-width};
+ --#{$prefix}list-group-border-radius: #{$list-group-border-radius};
+ --#{$prefix}list-group-item-padding-x: #{$list-group-item-padding-x};
+ --#{$prefix}list-group-item-padding-y: #{$list-group-item-padding-y};
+ --#{$prefix}list-group-action-color: #{$list-group-action-color};
+ --#{$prefix}list-group-action-hover-color: #{$list-group-action-hover-color};
+ --#{$prefix}list-group-action-hover-bg: #{$list-group-hover-bg};
+ --#{$prefix}list-group-action-active-color: #{$list-group-action-active-color};
+ --#{$prefix}list-group-action-active-bg: #{$list-group-action-active-bg};
+ --#{$prefix}list-group-disabled-color: #{$list-group-disabled-color};
+ --#{$prefix}list-group-disabled-bg: #{$list-group-disabled-bg};
+ --#{$prefix}list-group-active-color: #{$list-group-active-color};
+ --#{$prefix}list-group-active-bg: #{$list-group-active-bg};
+ --#{$prefix}list-group-active-border-color: #{$list-group-active-border-color};
+ // scss-docs-end list-group-css-vars
+
+ display: flex;
+ flex-direction: column;
+
+ // No need to set list-style: none; since .list-group-item is block level
+ padding-left: 0; // reset padding because ul and ol
+ margin-bottom: 0;
+ @include border-radius(var(--#{$prefix}list-group-border-radius));
+}
+
+.list-group-numbered {
+ list-style-type: none;
+ counter-reset: section;
+
+ > .list-group-item::before {
+ // Increments only this instance of the section counter
+ content: counters(section, ".") ". ";
+ counter-increment: section;
+ }
+}
+
+// Interactive list items
+//
+// Use anchor or button elements instead of `li`s or `div`s to create interactive
+// list items. Includes an extra `.active` modifier class for selected items.
+
+.list-group-item-action {
+ width: 100%; // For `<button>`s (anchors become 100% by default though)
+ color: var(--#{$prefix}list-group-action-color);
+ text-align: inherit; // For `<button>`s (anchors inherit)
+
+ // Hover state
+ &:hover,
+ &:focus {
+ z-index: 1; // Place hover/focus items above their siblings for proper border styling
+ color: var(--#{$prefix}list-group-action-hover-color);
+ text-decoration: none;
+ background-color: var(--#{$prefix}list-group-action-hover-bg);
+ }
+
+ &:active {
+ color: var(--#{$prefix}list-group-action-active-color);
+ background-color: var(--#{$prefix}list-group-action-active-bg);
+ }
+}
+
+// Individual list items
+//
+// Use on `li`s or `div`s within the `.list-group` parent.
+
+.list-group-item {
+ position: relative;
+ display: block;
+ padding: var(--#{$prefix}list-group-item-padding-y) var(--#{$prefix}list-group-item-padding-x);
+ color: var(--#{$prefix}list-group-color);
+ text-decoration: if($link-decoration == none, null, none);
+ background-color: var(--#{$prefix}list-group-bg);
+ border: var(--#{$prefix}list-group-border-width) solid var(--#{$prefix}list-group-border-color);
+
+ &:first-child {
+ @include border-top-radius(inherit);
+ }
+
+ &:last-child {
+ @include border-bottom-radius(inherit);
+ }
+
+ &.disabled,
+ &:disabled {
+ color: var(--#{$prefix}list-group-disabled-color);
+ pointer-events: none;
+ background-color: var(--#{$prefix}list-group-disabled-bg);
+ }
+
+ // Include both here for `<a>`s and `<button>`s
+ &.active {
+ z-index: 2; // Place active items above their siblings for proper border styling
+ color: var(--#{$prefix}list-group-active-color);
+ background-color: var(--#{$prefix}list-group-active-bg);
+ border-color: var(--#{$prefix}list-group-active-border-color);
+ }
+
+ // stylelint-disable-next-line scss/selector-no-redundant-nesting-selector
+ & + .list-group-item {
+ border-top-width: 0;
+
+ &.active {
+ margin-top: calc(-1 * var(--#{$prefix}list-group-border-width)); // stylelint-disable-line function-disallowed-list
+ border-top-width: var(--#{$prefix}list-group-border-width);
+ }
+ }
+}
+
+// Horizontal
+//
+// Change the layout of list group items from vertical (default) to horizontal.
+
+@each $breakpoint in map-keys($grid-breakpoints) {
+ @include media-breakpoint-up($breakpoint) {
+ $infix: breakpoint-infix($breakpoint, $grid-breakpoints);
+
+ .list-group-horizontal#{$infix} {
+ flex-direction: row;
+
+ > .list-group-item {
+ &:first-child:not(:last-child) {
+ @include border-bottom-start-radius(var(--#{$prefix}list-group-border-radius));
+ @include border-top-end-radius(0);
+ }
+
+ &:last-child:not(:first-child) {
+ @include border-top-end-radius(var(--#{$prefix}list-group-border-radius));
+ @include border-bottom-start-radius(0);
+ }
+
+ &.active {
+ margin-top: 0;
+ }
+
+ + .list-group-item {
+ border-top-width: var(--#{$prefix}list-group-border-width);
+ border-left-width: 0;
+
+ &.active {
+ margin-left: calc(-1 * var(--#{$prefix}list-group-border-width)); // stylelint-disable-line function-disallowed-list
+ border-left-width: var(--#{$prefix}list-group-border-width);
+ }
+ }
+ }
+ }
+ }
+}
+
+
+// Flush list items
+//
+// Remove borders and border-radius to keep list group items edge-to-edge. Most
+// useful within other components (e.g., cards).
+
+.list-group-flush {
+ @include border-radius(0);
+
+ > .list-group-item {
+ border-width: 0 0 var(--#{$prefix}list-group-border-width);
+
+ &:last-child {
+ border-bottom-width: 0;
+ }
+ }
+}
+
+
+// scss-docs-start list-group-modifiers
+// List group contextual variants
+//
+// Add modifier classes to change text and background color on individual items.
+// Organizationally, this must come after the `:hover` states.
+
+@each $state, $value in $theme-colors {
+ $list-group-variant-bg: shift-color($value, $list-group-item-bg-scale);
+ $list-group-variant-color: shift-color($value, $list-group-item-color-scale);
+ @if (contrast-ratio($list-group-variant-bg, $list-group-variant-color) < $min-contrast-ratio) {
+ $list-group-variant-color: mix($value, color-contrast($list-group-variant-bg), abs($list-group-item-color-scale));
+ }
+
+ @include list-group-item-variant($state, $list-group-variant-bg, $list-group-variant-color);
+}
+// scss-docs-end list-group-modifiers
diff --git a/csit.infra.dash/app/cdash/static/sass/bootstrap/_maps.scss b/csit.infra.dash/app/cdash/static/sass/bootstrap/_maps.scss
new file mode 100644
index 0000000000..2770a67615
--- /dev/null
+++ b/csit.infra.dash/app/cdash/static/sass/bootstrap/_maps.scss
@@ -0,0 +1,54 @@
+// Re-assigned maps
+//
+// Placed here so that others can override the default Sass maps and see automatic updates to utilities and more.
+
+// scss-docs-start theme-colors-rgb
+$theme-colors-rgb: map-loop($theme-colors, to-rgb, "$value") !default;
+// scss-docs-end theme-colors-rgb
+
+// Utilities maps
+//
+// Extends the default `$theme-colors` maps to help create our utilities.
+
+// Come v6, we'll de-dupe these variables. Until then, for backward compatibility, we keep them to reassign.
+// scss-docs-start utilities-colors
+$utilities-colors: $theme-colors-rgb !default;
+// scss-docs-end utilities-colors
+
+// scss-docs-start utilities-text-colors
+$utilities-text: map-merge(
+ $utilities-colors,
+ (
+ "black": to-rgb($black),
+ "white": to-rgb($white),
+ "body": to-rgb($body-color)
+ )
+) !default;
+$utilities-text-colors: map-loop($utilities-text, rgba-css-var, "$key", "text") !default;
+// scss-docs-end utilities-text-colors
+
+// scss-docs-start utilities-bg-colors
+$utilities-bg: map-merge(
+ $utilities-colors,
+ (
+ "black": to-rgb($black),
+ "white": to-rgb($white),
+ "body": to-rgb($body-bg)
+ )
+) !default;
+$utilities-bg-colors: map-loop($utilities-bg, rgba-css-var, "$key", "bg") !default;
+// scss-docs-end utilities-bg-colors
+
+// scss-docs-start utilities-border-colors
+$utilities-border: map-merge(
+ $utilities-colors,
+ (
+ "white": to-rgb($white)
+ )
+) !default;
+$utilities-border-colors: map-loop($utilities-border, rgba-css-var, "$key", "border") !default;
+// scss-docs-end utilities-border-colors
+
+$negative-spacers: if($enable-negative-margins, negativify-map($spacers), null) !default;
+
+$gutters: $spacers !default;
diff --git a/csit.infra.dash/app/cdash/static/sass/bootstrap/_mixins.scss b/csit.infra.dash/app/cdash/static/sass/bootstrap/_mixins.scss
new file mode 100644
index 0000000000..af1f74f72e
--- /dev/null
+++ b/csit.infra.dash/app/cdash/static/sass/bootstrap/_mixins.scss
@@ -0,0 +1,43 @@
+// Toggles
+//
+// Used in conjunction with global variables to enable certain theme features.
+
+// Vendor
+@import "vendor/rfs";
+
+// Deprecate
+@import "mixins/deprecate";
+
+// Helpers
+@import "mixins/breakpoints";
+@import "mixins/color-scheme";
+@import "mixins/image";
+@import "mixins/resize";
+@import "mixins/visually-hidden";
+@import "mixins/reset-text";
+@import "mixins/text-truncate";
+
+// Utilities
+@import "mixins/utilities";
+
+// Components
+@import "mixins/alert";
+@import "mixins/backdrop";
+@import "mixins/buttons";
+@import "mixins/caret";
+@import "mixins/pagination";
+@import "mixins/lists";
+@import "mixins/list-group";
+@import "mixins/forms";
+@import "mixins/table-variants";
+
+// Skins
+@import "mixins/border-radius";
+@import "mixins/box-shadow";
+@import "mixins/gradients";
+@import "mixins/transition";
+
+// Layout
+@import "mixins/clearfix";
+@import "mixins/container";
+@import "mixins/grid";
diff --git a/csit.infra.dash/app/cdash/static/sass/bootstrap/_modal.scss b/csit.infra.dash/app/cdash/static/sass/bootstrap/_modal.scss
new file mode 100644
index 0000000000..5f1429fe4b
--- /dev/null
+++ b/csit.infra.dash/app/cdash/static/sass/bootstrap/_modal.scss
@@ -0,0 +1,237 @@
+// stylelint-disable function-disallowed-list
+
+// .modal-open - body class for killing the scroll
+// .modal - container to scroll within
+// .modal-dialog - positioning shell for the actual modal
+// .modal-content - actual modal w/ bg and corners and stuff
+
+
+// Container that the modal scrolls within
+.modal {
+ // scss-docs-start modal-css-vars
+ --#{$prefix}modal-zindex: #{$zindex-modal};
+ --#{$prefix}modal-width: #{$modal-md};
+ --#{$prefix}modal-padding: #{$modal-inner-padding};
+ --#{$prefix}modal-margin: #{$modal-dialog-margin};
+ --#{$prefix}modal-color: #{$modal-content-color};
+ --#{$prefix}modal-bg: #{$modal-content-bg};
+ --#{$prefix}modal-border-color: #{$modal-content-border-color};
+ --#{$prefix}modal-border-width: #{$modal-content-border-width};
+ --#{$prefix}modal-border-radius: #{$modal-content-border-radius};
+ --#{$prefix}modal-box-shadow: #{$modal-content-box-shadow-xs};
+ --#{$prefix}modal-inner-border-radius: #{$modal-content-inner-border-radius};
+ --#{$prefix}modal-header-padding-x: #{$modal-header-padding-x};
+ --#{$prefix}modal-header-padding-y: #{$modal-header-padding-y};
+ --#{$prefix}modal-header-padding: #{$modal-header-padding}; // Todo in v6: Split this padding into x and y
+ --#{$prefix}modal-header-border-color: #{$modal-header-border-color};
+ --#{$prefix}modal-header-border-width: #{$modal-header-border-width};
+ --#{$prefix}modal-title-line-height: #{$modal-title-line-height};
+ --#{$prefix}modal-footer-gap: #{$modal-footer-margin-between};
+ --#{$prefix}modal-footer-bg: #{$modal-footer-bg};
+ --#{$prefix}modal-footer-border-color: #{$modal-footer-border-color};
+ --#{$prefix}modal-footer-border-width: #{$modal-footer-border-width};
+ // scss-docs-end modal-css-vars
+
+ position: fixed;
+ top: 0;
+ left: 0;
+ z-index: var(--#{$prefix}modal-zindex);
+ display: none;
+ width: 100%;
+ height: 100%;
+ overflow-x: hidden;
+ overflow-y: auto;
+ // Prevent Chrome on Windows from adding a focus outline. For details, see
+ // https://github.com/twbs/bootstrap/pull/10951.
+ outline: 0;
+ // We deliberately don't use `-webkit-overflow-scrolling: touch;` due to a
+ // gnarly iOS Safari bug: https://bugs.webkit.org/show_bug.cgi?id=158342
+ // See also https://github.com/twbs/bootstrap/issues/17695
+}
+
+// Shell div to position the modal with bottom padding
+.modal-dialog {
+ position: relative;
+ width: auto;
+ margin: var(--#{$prefix}modal-margin);
+ // allow clicks to pass through for custom click handling to close modal
+ pointer-events: none;
+
+ // When fading in the modal, animate it to slide down
+ .modal.fade & {
+ @include transition($modal-transition);
+ transform: $modal-fade-transform;
+ }
+ .modal.show & {
+ transform: $modal-show-transform;
+ }
+
+ // When trying to close, animate focus to scale
+ .modal.modal-static & {
+ transform: $modal-scale-transform;
+ }
+}
+
+.modal-dialog-scrollable {
+ height: calc(100% - var(--#{$prefix}modal-margin) * 2);
+
+ .modal-content {
+ max-height: 100%;
+ overflow: hidden;
+ }
+
+ .modal-body {
+ overflow-y: auto;
+ }
+}
+
+.modal-dialog-centered {
+ display: flex;
+ align-items: center;
+ min-height: calc(100% - var(--#{$prefix}modal-margin) * 2);
+}
+
+// Actual modal
+.modal-content {
+ position: relative;
+ display: flex;
+ flex-direction: column;
+ width: 100%; // Ensure `.modal-content` extends the full width of the parent `.modal-dialog`
+ // counteract the pointer-events: none; in the .modal-dialog
+ color: var(--#{$prefix}modal-color);
+ pointer-events: auto;
+ background-color: var(--#{$prefix}modal-bg);
+ background-clip: padding-box;
+ border: var(--#{$prefix}modal-border-width) solid var(--#{$prefix}modal-border-color);
+ @include border-radius(var(--#{$prefix}modal-border-radius));
+ @include box-shadow(var(--#{$prefix}modal-box-shadow));
+ // Remove focus outline from opened modal
+ outline: 0;
+}
+
+// Modal background
+.modal-backdrop {
+ // scss-docs-start modal-backdrop-css-vars
+ --#{$prefix}backdrop-zindex: #{$zindex-modal-backdrop};
+ --#{$prefix}backdrop-bg: #{$modal-backdrop-bg};
+ --#{$prefix}backdrop-opacity: #{$modal-backdrop-opacity};
+ // scss-docs-end modal-backdrop-css-vars
+
+ @include overlay-backdrop(var(--#{$prefix}backdrop-zindex), var(--#{$prefix}backdrop-bg), var(--#{$prefix}backdrop-opacity));
+}
+
+// Modal header
+// Top section of the modal w/ title and dismiss
+.modal-header {
+ display: flex;
+ flex-shrink: 0;
+ align-items: center;
+ justify-content: space-between; // Put modal header elements (title and dismiss) on opposite ends
+ padding: var(--#{$prefix}modal-header-padding);
+ border-bottom: var(--#{$prefix}modal-header-border-width) solid var(--#{$prefix}modal-header-border-color);
+ @include border-top-radius(var(--#{$prefix}modal-inner-border-radius));
+
+ .btn-close {
+ padding: calc(var(--#{$prefix}modal-header-padding-y) * .5) calc(var(--#{$prefix}modal-header-padding-x) * .5);
+ margin: calc(-.5 * var(--#{$prefix}modal-header-padding-y)) calc(-.5 * var(--#{$prefix}modal-header-padding-x)) calc(-.5 * var(--#{$prefix}modal-header-padding-y)) auto;
+ }
+}
+
+// Title text within header
+.modal-title {
+ margin-bottom: 0;
+ line-height: var(--#{$prefix}modal-title-line-height);
+}
+
+// Modal body
+// Where all modal content resides (sibling of .modal-header and .modal-footer)
+.modal-body {
+ position: relative;
+ // Enable `flex-grow: 1` so that the body take up as much space as possible
+ // when there should be a fixed height on `.modal-dialog`.
+ flex: 1 1 auto;
+ padding: var(--#{$prefix}modal-padding);
+}
+
+// Footer (for actions)
+.modal-footer {
+ display: flex;
+ flex-shrink: 0;
+ flex-wrap: wrap;
+ align-items: center; // vertically center
+ justify-content: flex-end; // Right align buttons with flex property because text-align doesn't work on flex items
+ padding: calc(var(--#{$prefix}modal-padding) - var(--#{$prefix}modal-footer-gap) * .5);
+ background-color: var(--#{$prefix}modal-footer-bg);
+ border-top: var(--#{$prefix}modal-footer-border-width) solid var(--#{$prefix}modal-footer-border-color);
+ @include border-bottom-radius(var(--#{$prefix}modal-inner-border-radius));
+
+ // Place margin between footer elements
+ // This solution is far from ideal because of the universal selector usage,
+ // but is needed to fix https://github.com/twbs/bootstrap/issues/24800
+ > * {
+ margin: calc(var(--#{$prefix}modal-footer-gap) * .5); // Todo in v6: replace with gap on parent class
+ }
+}
+
+// Scale up the modal
+@include media-breakpoint-up(sm) {
+ .modal {
+ --#{$prefix}modal-margin: #{$modal-dialog-margin-y-sm-up};
+ --#{$prefix}modal-box-shadow: #{$modal-content-box-shadow-sm-up};
+ }
+
+ // Automatically set modal's width for larger viewports
+ .modal-dialog {
+ max-width: var(--#{$prefix}modal-width);
+ margin-right: auto;
+ margin-left: auto;
+ }
+
+ .modal-sm {
+ --#{$prefix}modal-width: #{$modal-sm};
+ }
+}
+
+@include media-breakpoint-up(lg) {
+ .modal-lg,
+ .modal-xl {
+ --#{$prefix}modal-width: #{$modal-lg};
+ }
+}
+
+@include media-breakpoint-up(xl) {
+ .modal-xl {
+ --#{$prefix}modal-width: #{$modal-xl};
+ }
+}
+
+// scss-docs-start modal-fullscreen-loop
+@each $breakpoint in map-keys($grid-breakpoints) {
+ $infix: breakpoint-infix($breakpoint, $grid-breakpoints);
+ $postfix: if($infix != "", $infix + "-down", "");
+
+ @include media-breakpoint-down($breakpoint) {
+ .modal-fullscreen#{$postfix} {
+ width: 100vw;
+ max-width: none;
+ height: 100%;
+ margin: 0;
+
+ .modal-content {
+ height: 100%;
+ border: 0;
+ @include border-radius(0);
+ }
+
+ .modal-header,
+ .modal-footer {
+ @include border-radius(0);
+ }
+
+ .modal-body {
+ overflow-y: auto;
+ }
+ }
+ }
+}
+// scss-docs-end modal-fullscreen-loop
diff --git a/csit.infra.dash/app/cdash/static/sass/bootstrap/_nav.scss b/csit.infra.dash/app/cdash/static/sass/bootstrap/_nav.scss
new file mode 100644
index 0000000000..9efc03bc8f
--- /dev/null
+++ b/csit.infra.dash/app/cdash/static/sass/bootstrap/_nav.scss
@@ -0,0 +1,172 @@
+// Base class
+//
+// Kickstart any navigation component with a set of style resets. Works with
+// `<nav>`s, `<ul>`s or `<ol>`s.
+
+.nav {
+ // scss-docs-start nav-css-vars
+ --#{$prefix}nav-link-padding-x: #{$nav-link-padding-x};
+ --#{$prefix}nav-link-padding-y: #{$nav-link-padding-y};
+ @include rfs($nav-link-font-size, --#{$prefix}nav-link-font-size);
+ --#{$prefix}nav-link-font-weight: #{$nav-link-font-weight};
+ --#{$prefix}nav-link-color: #{$nav-link-color};
+ --#{$prefix}nav-link-hover-color: #{$nav-link-hover-color};
+ --#{$prefix}nav-link-disabled-color: #{$nav-link-disabled-color};
+ // scss-docs-end nav-css-vars
+
+ display: flex;
+ flex-wrap: wrap;
+ padding-left: 0;
+ margin-bottom: 0;
+ list-style: none;
+}
+
+.nav-link {
+ display: block;
+ padding: var(--#{$prefix}nav-link-padding-y) var(--#{$prefix}nav-link-padding-x);
+ @include font-size(var(--#{$prefix}nav-link-font-size));
+ font-weight: var(--#{$prefix}nav-link-font-weight);
+ color: var(--#{$prefix}nav-link-color);
+ text-decoration: if($link-decoration == none, null, none);
+ @include transition($nav-link-transition);
+
+ &:hover,
+ &:focus {
+ color: var(--#{$prefix}nav-link-hover-color);
+ text-decoration: if($link-hover-decoration == underline, none, null);
+ }
+
+ // Disabled state lightens text
+ &.disabled {
+ color: var(--#{$prefix}nav-link-disabled-color);
+ pointer-events: none;
+ cursor: default;
+ }
+}
+
+//
+// Tabs
+//
+
+.nav-tabs {
+ // scss-docs-start nav-tabs-css-vars
+ --#{$prefix}nav-tabs-border-width: #{$nav-tabs-border-width};
+ --#{$prefix}nav-tabs-border-color: #{$nav-tabs-border-color};
+ --#{$prefix}nav-tabs-border-radius: #{$nav-tabs-border-radius};
+ --#{$prefix}nav-tabs-link-hover-border-color: #{$nav-tabs-link-hover-border-color};
+ --#{$prefix}nav-tabs-link-active-color: #{$nav-tabs-link-active-color};
+ --#{$prefix}nav-tabs-link-active-bg: #{$nav-tabs-link-active-bg};
+ --#{$prefix}nav-tabs-link-active-border-color: #{$nav-tabs-link-active-border-color};
+ // scss-docs-end nav-tabs-css-vars
+
+ border-bottom: var(--#{$prefix}nav-tabs-border-width) solid var(--#{$prefix}nav-tabs-border-color);
+
+ .nav-link {
+ margin-bottom: calc(-1 * var(--#{$prefix}nav-tabs-border-width)); // stylelint-disable-line function-disallowed-list
+ background: none;
+ border: var(--#{$prefix}nav-tabs-border-width) solid transparent;
+ @include border-top-radius(var(--#{$prefix}nav-tabs-border-radius));
+
+ &:hover,
+ &:focus {
+ // Prevents active .nav-link tab overlapping focus outline of previous/next .nav-link
+ isolation: isolate;
+ border-color: var(--#{$prefix}nav-tabs-link-hover-border-color);
+ }
+
+ &.disabled,
+ &:disabled {
+ color: var(--#{$prefix}nav-link-disabled-color);
+ background-color: transparent;
+ border-color: transparent;
+ }
+ }
+
+ .nav-link.active,
+ .nav-item.show .nav-link {
+ color: var(--#{$prefix}nav-tabs-link-active-color);
+ background-color: var(--#{$prefix}nav-tabs-link-active-bg);
+ border-color: var(--#{$prefix}nav-tabs-link-active-border-color);
+ }
+
+ .dropdown-menu {
+ // Make dropdown border overlap tab border
+ margin-top: calc(-1 * var(--#{$prefix}nav-tabs-border-width)); // stylelint-disable-line function-disallowed-list
+ // Remove the top rounded corners here since there is a hard edge above the menu
+ @include border-top-radius(0);
+ }
+}
+
+
+//
+// Pills
+//
+
+.nav-pills {
+ // scss-docs-start nav-pills-css-vars
+ --#{$prefix}nav-pills-border-radius: #{$nav-pills-border-radius};
+ --#{$prefix}nav-pills-link-active-color: #{$nav-pills-link-active-color};
+ --#{$prefix}nav-pills-link-active-bg: #{$nav-pills-link-active-bg};
+ // scss-docs-end nav-pills-css-vars
+
+ .nav-link {
+ background: none;
+ border: 0;
+ @include border-radius(var(--#{$prefix}nav-pills-border-radius));
+
+ &:disabled {
+ color: var(--#{$prefix}nav-link-disabled-color);
+ background-color: transparent;
+ border-color: transparent;
+ }
+ }
+
+ .nav-link.active,
+ .show > .nav-link {
+ color: var(--#{$prefix}nav-pills-link-active-color);
+ @include gradient-bg(var(--#{$prefix}nav-pills-link-active-bg));
+ }
+}
+
+
+//
+// Justified variants
+//
+
+.nav-fill {
+ > .nav-link,
+ .nav-item {
+ flex: 1 1 auto;
+ text-align: center;
+ }
+}
+
+.nav-justified {
+ > .nav-link,
+ .nav-item {
+ flex-basis: 0;
+ flex-grow: 1;
+ text-align: center;
+ }
+}
+
+.nav-fill,
+.nav-justified {
+ .nav-item .nav-link {
+ width: 100%; // Make sure button will grow
+ }
+}
+
+
+// Tabbable tabs
+//
+// Hide tabbable panes to start, show them when `.active`
+
+.tab-content {
+ > .tab-pane {
+ display: none;
+ }
+ > .active {
+ display: block;
+ }
+}
diff --git a/csit.infra.dash/app/cdash/static/sass/bootstrap/_navbar.scss b/csit.infra.dash/app/cdash/static/sass/bootstrap/_navbar.scss
new file mode 100644
index 0000000000..599b055ebc
--- /dev/null
+++ b/csit.infra.dash/app/cdash/static/sass/bootstrap/_navbar.scss
@@ -0,0 +1,278 @@
+// Navbar
+//
+// Provide a static navbar from which we expand to create full-width, fixed, and
+// other navbar variations.
+
+.navbar {
+ // scss-docs-start navbar-css-vars
+ --#{$prefix}navbar-padding-x: #{if($navbar-padding-x == null, 0, $navbar-padding-x)};
+ --#{$prefix}navbar-padding-y: #{$navbar-padding-y};
+ --#{$prefix}navbar-color: #{$navbar-light-color};
+ --#{$prefix}navbar-hover-color: #{$navbar-light-hover-color};
+ --#{$prefix}navbar-disabled-color: #{$navbar-light-disabled-color};
+ --#{$prefix}navbar-active-color: #{$navbar-light-active-color};
+ --#{$prefix}navbar-brand-padding-y: #{$navbar-brand-padding-y};
+ --#{$prefix}navbar-brand-margin-end: #{$navbar-brand-margin-end};
+ --#{$prefix}navbar-brand-font-size: #{$navbar-brand-font-size};
+ --#{$prefix}navbar-brand-color: #{$navbar-light-brand-color};
+ --#{$prefix}navbar-brand-hover-color: #{$navbar-light-brand-hover-color};
+ --#{$prefix}navbar-nav-link-padding-x: #{$navbar-nav-link-padding-x};
+ --#{$prefix}navbar-toggler-padding-y: #{$navbar-toggler-padding-y};
+ --#{$prefix}navbar-toggler-padding-x: #{$navbar-toggler-padding-x};
+ --#{$prefix}navbar-toggler-font-size: #{$navbar-toggler-font-size};
+ --#{$prefix}navbar-toggler-icon-bg: #{escape-svg($navbar-light-toggler-icon-bg)};
+ --#{$prefix}navbar-toggler-border-color: #{$navbar-light-toggler-border-color};
+ --#{$prefix}navbar-toggler-border-radius: #{$navbar-toggler-border-radius};
+ --#{$prefix}navbar-toggler-focus-width: #{$navbar-toggler-focus-width};
+ --#{$prefix}navbar-toggler-transition: #{$navbar-toggler-transition};
+ // scss-docs-end navbar-css-vars
+
+ position: relative;
+ display: flex;
+ flex-wrap: wrap; // allow us to do the line break for collapsing content
+ align-items: center;
+ justify-content: space-between; // space out brand from logo
+ padding: var(--#{$prefix}navbar-padding-y) var(--#{$prefix}navbar-padding-x);
+ @include gradient-bg();
+
+ // Because flex properties aren't inherited, we need to redeclare these first
+ // few properties so that content nested within behave properly.
+ // The `flex-wrap` property is inherited to simplify the expanded navbars
+ %container-flex-properties {
+ display: flex;
+ flex-wrap: inherit;
+ align-items: center;
+ justify-content: space-between;
+ }
+
+ > .container,
+ > .container-fluid {
+ @extend %container-flex-properties;
+ }
+
+ @each $breakpoint, $container-max-width in $container-max-widths {
+ > .container#{breakpoint-infix($breakpoint, $container-max-widths)} {
+ @extend %container-flex-properties;
+ }
+ }
+}
+
+
+// Navbar brand
+//
+// Used for brand, project, or site names.
+
+.navbar-brand {
+ padding-top: var(--#{$prefix}navbar-brand-padding-y);
+ padding-bottom: var(--#{$prefix}navbar-brand-padding-y);
+ margin-right: var(--#{$prefix}navbar-brand-margin-end);
+ @include font-size(var(--#{$prefix}navbar-brand-font-size));
+ color: var(--#{$prefix}navbar-brand-color);
+ text-decoration: if($link-decoration == none, null, none);
+ white-space: nowrap;
+
+ &:hover,
+ &:focus {
+ color: var(--#{$prefix}navbar-brand-hover-color);
+ text-decoration: if($link-hover-decoration == underline, none, null);
+ }
+}
+
+
+// Navbar nav
+//
+// Custom navbar navigation (doesn't require `.nav`, but does make use of `.nav-link`).
+
+.navbar-nav {
+ // scss-docs-start navbar-nav-css-vars
+ --#{$prefix}nav-link-padding-x: 0;
+ --#{$prefix}nav-link-padding-y: #{$nav-link-padding-y};
+ @include rfs($nav-link-font-size, --#{$prefix}nav-link-font-size);
+ --#{$prefix}nav-link-font-weight: #{$nav-link-font-weight};
+ --#{$prefix}nav-link-color: var(--#{$prefix}navbar-color);
+ --#{$prefix}nav-link-hover-color: var(--#{$prefix}navbar-hover-color);
+ --#{$prefix}nav-link-disabled-color: var(--#{$prefix}navbar-disabled-color);
+ // scss-docs-end navbar-nav-css-vars
+
+ display: flex;
+ flex-direction: column; // cannot use `inherit` to get the `.navbar`s value
+ padding-left: 0;
+ margin-bottom: 0;
+ list-style: none;
+
+ .show > .nav-link,
+ .nav-link.active {
+ color: var(--#{$prefix}navbar-active-color);
+ }
+
+ .dropdown-menu {
+ position: static;
+ }
+}
+
+
+// Navbar text
+//
+//
+
+.navbar-text {
+ padding-top: $nav-link-padding-y;
+ padding-bottom: $nav-link-padding-y;
+ color: var(--#{$prefix}navbar-color);
+
+ a,
+ a:hover,
+ a:focus {
+ color: var(--#{$prefix}navbar-active-color);
+ }
+}
+
+
+// Responsive navbar
+//
+// Custom styles for responsive collapsing and toggling of navbar contents.
+// Powered by the collapse Bootstrap JavaScript plugin.
+
+// When collapsed, prevent the toggleable navbar contents from appearing in
+// the default flexbox row orientation. Requires the use of `flex-wrap: wrap`
+// on the `.navbar` parent.
+.navbar-collapse {
+ flex-basis: 100%;
+ flex-grow: 1;
+ // For always expanded or extra full navbars, ensure content aligns itself
+ // properly vertically. Can be easily overridden with flex utilities.
+ align-items: center;
+}
+
+// Button for toggling the navbar when in its collapsed state
+.navbar-toggler {
+ padding: var(--#{$prefix}navbar-toggler-padding-y) var(--#{$prefix}navbar-toggler-padding-x);
+ @include font-size(var(--#{$prefix}navbar-toggler-font-size));
+ line-height: 1;
+ color: var(--#{$prefix}navbar-color);
+ background-color: transparent; // remove default button style
+ border: var(--#{$prefix}border-width) solid var(--#{$prefix}navbar-toggler-border-color); // remove default button style
+ @include border-radius(var(--#{$prefix}navbar-toggler-border-radius));
+ @include transition(var(--#{$prefix}navbar-toggler-transition));
+
+ &:hover {
+ text-decoration: none;
+ }
+
+ &:focus {
+ text-decoration: none;
+ outline: 0;
+ box-shadow: 0 0 0 var(--#{$prefix}navbar-toggler-focus-width);
+ }
+}
+
+// Keep as a separate element so folks can easily override it with another icon
+// or image file as needed.
+.navbar-toggler-icon {
+ display: inline-block;
+ width: 1.5em;
+ height: 1.5em;
+ vertical-align: middle;
+ background-image: var(--#{$prefix}navbar-toggler-icon-bg);
+ background-repeat: no-repeat;
+ background-position: center;
+ background-size: 100%;
+}
+
+.navbar-nav-scroll {
+ max-height: var(--#{$prefix}scroll-height, 75vh);
+ overflow-y: auto;
+}
+
+// scss-docs-start navbar-expand-loop
+// Generate series of `.navbar-expand-*` responsive classes for configuring
+// where your navbar collapses.
+.navbar-expand {
+ @each $breakpoint in map-keys($grid-breakpoints) {
+ $next: breakpoint-next($breakpoint, $grid-breakpoints);
+ $infix: breakpoint-infix($next, $grid-breakpoints);
+
+ // stylelint-disable-next-line scss/selector-no-union-class-name
+ &#{$infix} {
+ @include media-breakpoint-up($next) {
+ flex-wrap: nowrap;
+ justify-content: flex-start;
+
+ .navbar-nav {
+ flex-direction: row;
+
+ .dropdown-menu {
+ position: absolute;
+ }
+
+ .nav-link {
+ padding-right: var(--#{$prefix}navbar-nav-link-padding-x);
+ padding-left: var(--#{$prefix}navbar-nav-link-padding-x);
+ }
+ }
+
+ .navbar-nav-scroll {
+ overflow: visible;
+ }
+
+ .navbar-collapse {
+ display: flex !important; // stylelint-disable-line declaration-no-important
+ flex-basis: auto;
+ }
+
+ .navbar-toggler {
+ display: none;
+ }
+
+ .offcanvas {
+ // stylelint-disable declaration-no-important
+ position: static;
+ z-index: auto;
+ flex-grow: 1;
+ width: auto !important;
+ height: auto !important;
+ visibility: visible !important;
+ background-color: transparent !important;
+ border: 0 !important;
+ transform: none !important;
+ @include box-shadow(none);
+ @include transition(none);
+ // stylelint-enable declaration-no-important
+
+ .offcanvas-header {
+ display: none;
+ }
+
+ .offcanvas-body {
+ display: flex;
+ flex-grow: 0;
+ padding: 0;
+ overflow-y: visible;
+ }
+ }
+ }
+ }
+ }
+}
+// scss-docs-end navbar-expand-loop
+
+// Navbar themes
+//
+// Styles for switching between navbars with light or dark background.
+
+.navbar-light {
+ @include deprecate("`.navbar-light`", "v5.2.0", "v6.0.0", true);
+}
+
+.navbar-dark {
+ // scss-docs-start navbar-dark-css-vars
+ --#{$prefix}navbar-color: #{$navbar-dark-color};
+ --#{$prefix}navbar-hover-color: #{$navbar-dark-hover-color};
+ --#{$prefix}navbar-disabled-color: #{$navbar-dark-disabled-color};
+ --#{$prefix}navbar-active-color: #{$navbar-dark-active-color};
+ --#{$prefix}navbar-brand-color: #{$navbar-dark-brand-color};
+ --#{$prefix}navbar-brand-hover-color: #{$navbar-dark-brand-hover-color};
+ --#{$prefix}navbar-toggler-border-color: #{$navbar-dark-toggler-border-color};
+ --#{$prefix}navbar-toggler-icon-bg: #{escape-svg($navbar-dark-toggler-icon-bg)};
+ // scss-docs-end navbar-dark-css-vars
+}
diff --git a/csit.infra.dash/app/cdash/static/sass/bootstrap/_offcanvas.scss b/csit.infra.dash/app/cdash/static/sass/bootstrap/_offcanvas.scss
new file mode 100644
index 0000000000..23fc357f2b
--- /dev/null
+++ b/csit.infra.dash/app/cdash/static/sass/bootstrap/_offcanvas.scss
@@ -0,0 +1,144 @@
+// stylelint-disable function-disallowed-list
+
+%offcanvas-css-vars {
+ // scss-docs-start offcanvas-css-vars
+ --#{$prefix}offcanvas-zindex: #{$zindex-offcanvas};
+ --#{$prefix}offcanvas-width: #{$offcanvas-horizontal-width};
+ --#{$prefix}offcanvas-height: #{$offcanvas-vertical-height};
+ --#{$prefix}offcanvas-padding-x: #{$offcanvas-padding-x};
+ --#{$prefix}offcanvas-padding-y: #{$offcanvas-padding-y};
+ --#{$prefix}offcanvas-color: #{$offcanvas-color};
+ --#{$prefix}offcanvas-bg: #{$offcanvas-bg-color};
+ --#{$prefix}offcanvas-border-width: #{$offcanvas-border-width};
+ --#{$prefix}offcanvas-border-color: #{$offcanvas-border-color};
+ --#{$prefix}offcanvas-box-shadow: #{$offcanvas-box-shadow};
+ // scss-docs-end offcanvas-css-vars
+}
+
+@each $breakpoint in map-keys($grid-breakpoints) {
+ $next: breakpoint-next($breakpoint, $grid-breakpoints);
+ $infix: breakpoint-infix($next, $grid-breakpoints);
+
+ .offcanvas#{$infix} {
+ @extend %offcanvas-css-vars;
+ }
+}
+
+@each $breakpoint in map-keys($grid-breakpoints) {
+ $next: breakpoint-next($breakpoint, $grid-breakpoints);
+ $infix: breakpoint-infix($next, $grid-breakpoints);
+
+ .offcanvas#{$infix} {
+ @include media-breakpoint-down($next) {
+ position: fixed;
+ bottom: 0;
+ z-index: var(--#{$prefix}offcanvas-zindex);
+ display: flex;
+ flex-direction: column;
+ max-width: 100%;
+ color: var(--#{$prefix}offcanvas-color);
+ visibility: hidden;
+ background-color: var(--#{$prefix}offcanvas-bg);
+ background-clip: padding-box;
+ outline: 0;
+ @include box-shadow(var(--#{$prefix}offcanvas-box-shadow));
+ @include transition(transform $offcanvas-transition-duration ease-in-out);
+
+ &.offcanvas-start {
+ top: 0;
+ left: 0;
+ width: var(--#{$prefix}offcanvas-width);
+ border-right: var(--#{$prefix}offcanvas-border-width) solid var(--#{$prefix}offcanvas-border-color);
+ transform: translateX(-100%);
+ }
+
+ &.offcanvas-end {
+ top: 0;
+ right: 0;
+ width: var(--#{$prefix}offcanvas-width);
+ border-left: var(--#{$prefix}offcanvas-border-width) solid var(--#{$prefix}offcanvas-border-color);
+ transform: translateX(100%);
+ }
+
+ &.offcanvas-top {
+ top: 0;
+ right: 0;
+ left: 0;
+ height: var(--#{$prefix}offcanvas-height);
+ max-height: 100%;
+ border-bottom: var(--#{$prefix}offcanvas-border-width) solid var(--#{$prefix}offcanvas-border-color);
+ transform: translateY(-100%);
+ }
+
+ &.offcanvas-bottom {
+ right: 0;
+ left: 0;
+ height: var(--#{$prefix}offcanvas-height);
+ max-height: 100%;
+ border-top: var(--#{$prefix}offcanvas-border-width) solid var(--#{$prefix}offcanvas-border-color);
+ transform: translateY(100%);
+ }
+
+ &.showing,
+ &.show:not(.hiding) {
+ transform: none;
+ }
+
+ &.showing,
+ &.hiding,
+ &.show {
+ visibility: visible;
+ }
+ }
+
+ @if not ($infix == "") {
+ @include media-breakpoint-up($next) {
+ --#{$prefix}offcanvas-height: auto;
+ --#{$prefix}offcanvas-border-width: 0;
+ background-color: transparent !important; // stylelint-disable-line declaration-no-important
+
+ .offcanvas-header {
+ display: none;
+ }
+
+ .offcanvas-body {
+ display: flex;
+ flex-grow: 0;
+ padding: 0;
+ overflow-y: visible;
+ // Reset `background-color` in case `.bg-*` classes are used in offcanvas
+ background-color: transparent !important; // stylelint-disable-line declaration-no-important
+ }
+ }
+ }
+ }
+}
+
+.offcanvas-backdrop {
+ @include overlay-backdrop($zindex-offcanvas-backdrop, $offcanvas-backdrop-bg, $offcanvas-backdrop-opacity);
+}
+
+.offcanvas-header {
+ display: flex;
+ align-items: center;
+ justify-content: space-between;
+ padding: var(--#{$prefix}offcanvas-padding-y) var(--#{$prefix}offcanvas-padding-x);
+
+ .btn-close {
+ padding: calc(var(--#{$prefix}offcanvas-padding-y) * .5) calc(var(--#{$prefix}offcanvas-padding-x) * .5);
+ margin-top: calc(-.5 * var(--#{$prefix}offcanvas-padding-y));
+ margin-right: calc(-.5 * var(--#{$prefix}offcanvas-padding-x));
+ margin-bottom: calc(-.5 * var(--#{$prefix}offcanvas-padding-y));
+ }
+}
+
+.offcanvas-title {
+ margin-bottom: 0;
+ line-height: $offcanvas-title-line-height;
+}
+
+.offcanvas-body {
+ flex-grow: 1;
+ padding: var(--#{$prefix}offcanvas-padding-y) var(--#{$prefix}offcanvas-padding-x);
+ overflow-y: auto;
+}
diff --git a/csit.infra.dash/app/cdash/static/sass/bootstrap/_pagination.scss b/csit.infra.dash/app/cdash/static/sass/bootstrap/_pagination.scss
new file mode 100644
index 0000000000..cf4db3c361
--- /dev/null
+++ b/csit.infra.dash/app/cdash/static/sass/bootstrap/_pagination.scss
@@ -0,0 +1,109 @@
+.pagination {
+ // scss-docs-start pagination-css-vars
+ --#{$prefix}pagination-padding-x: #{$pagination-padding-x};
+ --#{$prefix}pagination-padding-y: #{$pagination-padding-y};
+ @include rfs($pagination-font-size, --#{$prefix}pagination-font-size);
+ --#{$prefix}pagination-color: #{$pagination-color};
+ --#{$prefix}pagination-bg: #{$pagination-bg};
+ --#{$prefix}pagination-border-width: #{$pagination-border-width};
+ --#{$prefix}pagination-border-color: #{$pagination-border-color};
+ --#{$prefix}pagination-border-radius: #{$pagination-border-radius};
+ --#{$prefix}pagination-hover-color: #{$pagination-hover-color};
+ --#{$prefix}pagination-hover-bg: #{$pagination-hover-bg};
+ --#{$prefix}pagination-hover-border-color: #{$pagination-hover-border-color};
+ --#{$prefix}pagination-focus-color: #{$pagination-focus-color};
+ --#{$prefix}pagination-focus-bg: #{$pagination-focus-bg};
+ --#{$prefix}pagination-focus-box-shadow: #{$pagination-focus-box-shadow};
+ --#{$prefix}pagination-active-color: #{$pagination-active-color};
+ --#{$prefix}pagination-active-bg: #{$pagination-active-bg};
+ --#{$prefix}pagination-active-border-color: #{$pagination-active-border-color};
+ --#{$prefix}pagination-disabled-color: #{$pagination-disabled-color};
+ --#{$prefix}pagination-disabled-bg: #{$pagination-disabled-bg};
+ --#{$prefix}pagination-disabled-border-color: #{$pagination-disabled-border-color};
+ // scss-docs-end pagination-css-vars
+
+ display: flex;
+ @include list-unstyled();
+}
+
+.page-link {
+ position: relative;
+ display: block;
+ padding: var(--#{$prefix}pagination-padding-y) var(--#{$prefix}pagination-padding-x);
+ @include font-size(var(--#{$prefix}pagination-font-size));
+ color: var(--#{$prefix}pagination-color);
+ text-decoration: if($link-decoration == none, null, none);
+ background-color: var(--#{$prefix}pagination-bg);
+ border: var(--#{$prefix}pagination-border-width) solid var(--#{$prefix}pagination-border-color);
+ @include transition($pagination-transition);
+
+ &:hover {
+ z-index: 2;
+ color: var(--#{$prefix}pagination-hover-color);
+ text-decoration: if($link-hover-decoration == underline, none, null);
+ background-color: var(--#{$prefix}pagination-hover-bg);
+ border-color: var(--#{$prefix}pagination-hover-border-color);
+ }
+
+ &:focus {
+ z-index: 3;
+ color: var(--#{$prefix}pagination-focus-color);
+ background-color: var(--#{$prefix}pagination-focus-bg);
+ outline: $pagination-focus-outline;
+ box-shadow: var(--#{$prefix}pagination-focus-box-shadow);
+ }
+
+ &.active,
+ .active > & {
+ z-index: 3;
+ color: var(--#{$prefix}pagination-active-color);
+ @include gradient-bg(var(--#{$prefix}pagination-active-bg));
+ border-color: var(--#{$prefix}pagination-active-border-color);
+ }
+
+ &.disabled,
+ .disabled > & {
+ color: var(--#{$prefix}pagination-disabled-color);
+ pointer-events: none;
+ background-color: var(--#{$prefix}pagination-disabled-bg);
+ border-color: var(--#{$prefix}pagination-disabled-border-color);
+ }
+}
+
+.page-item {
+ &:not(:first-child) .page-link {
+ margin-left: $pagination-margin-start;
+ }
+
+ @if $pagination-margin-start == ($pagination-border-width * -1) {
+ &:first-child {
+ .page-link {
+ @include border-start-radius(var(--#{$prefix}pagination-border-radius));
+ }
+ }
+
+ &:last-child {
+ .page-link {
+ @include border-end-radius(var(--#{$prefix}pagination-border-radius));
+ }
+ }
+ } @else {
+ // Add border-radius to all pageLinks in case they have left margin
+ .page-link {
+ @include border-radius(var(--#{$prefix}pagination-border-radius));
+ }
+ }
+}
+
+
+//
+// Sizing
+//
+
+.pagination-lg {
+ @include pagination-size($pagination-padding-y-lg, $pagination-padding-x-lg, $font-size-lg, $pagination-border-radius-lg);
+}
+
+.pagination-sm {
+ @include pagination-size($pagination-padding-y-sm, $pagination-padding-x-sm, $font-size-sm, $pagination-border-radius-sm);
+}
diff --git a/csit.infra.dash/app/cdash/static/sass/bootstrap/_placeholders.scss b/csit.infra.dash/app/cdash/static/sass/bootstrap/_placeholders.scss
new file mode 100644
index 0000000000..6e32e1cdb9
--- /dev/null
+++ b/csit.infra.dash/app/cdash/static/sass/bootstrap/_placeholders.scss
@@ -0,0 +1,51 @@
+.placeholder {
+ display: inline-block;
+ min-height: 1em;
+ vertical-align: middle;
+ cursor: wait;
+ background-color: currentcolor;
+ opacity: $placeholder-opacity-max;
+
+ &.btn::before {
+ display: inline-block;
+ content: "";
+ }
+}
+
+// Sizing
+.placeholder-xs {
+ min-height: .6em;
+}
+
+.placeholder-sm {
+ min-height: .8em;
+}
+
+.placeholder-lg {
+ min-height: 1.2em;
+}
+
+// Animation
+.placeholder-glow {
+ .placeholder {
+ animation: placeholder-glow 2s ease-in-out infinite;
+ }
+}
+
+@keyframes placeholder-glow {
+ 50% {
+ opacity: $placeholder-opacity-min;
+ }
+}
+
+.placeholder-wave {
+ mask-image: linear-gradient(130deg, $black 55%, rgba(0, 0, 0, (1 - $placeholder-opacity-min)) 75%, $black 95%);
+ mask-size: 200% 100%;
+ animation: placeholder-wave 2s linear infinite;
+}
+
+@keyframes placeholder-wave {
+ 100% {
+ mask-position: -200% 0%;
+ }
+}
diff --git a/csit.infra.dash/app/cdash/static/sass/bootstrap/_popover.scss b/csit.infra.dash/app/cdash/static/sass/bootstrap/_popover.scss
new file mode 100644
index 0000000000..7b69f62328
--- /dev/null
+++ b/csit.infra.dash/app/cdash/static/sass/bootstrap/_popover.scss
@@ -0,0 +1,196 @@
+.popover {
+ // scss-docs-start popover-css-vars
+ --#{$prefix}popover-zindex: #{$zindex-popover};
+ --#{$prefix}popover-max-width: #{$popover-max-width};
+ @include rfs($popover-font-size, --#{$prefix}popover-font-size);
+ --#{$prefix}popover-bg: #{$popover-bg};
+ --#{$prefix}popover-border-width: #{$popover-border-width};
+ --#{$prefix}popover-border-color: #{$popover-border-color};
+ --#{$prefix}popover-border-radius: #{$popover-border-radius};
+ --#{$prefix}popover-inner-border-radius: #{$popover-inner-border-radius};
+ --#{$prefix}popover-box-shadow: #{$popover-box-shadow};
+ --#{$prefix}popover-header-padding-x: #{$popover-header-padding-x};
+ --#{$prefix}popover-header-padding-y: #{$popover-header-padding-y};
+ @include rfs($popover-header-font-size, --#{$prefix}popover-header-font-size);
+ --#{$prefix}popover-header-color: #{$popover-header-color};
+ --#{$prefix}popover-header-bg: #{$popover-header-bg};
+ --#{$prefix}popover-body-padding-x: #{$popover-body-padding-x};
+ --#{$prefix}popover-body-padding-y: #{$popover-body-padding-y};
+ --#{$prefix}popover-body-color: #{$popover-body-color};
+ --#{$prefix}popover-arrow-width: #{$popover-arrow-width};
+ --#{$prefix}popover-arrow-height: #{$popover-arrow-height};
+ --#{$prefix}popover-arrow-border: var(--#{$prefix}popover-border-color);
+ // scss-docs-end popover-css-vars
+
+ z-index: var(--#{$prefix}popover-zindex);
+ display: block;
+ max-width: var(--#{$prefix}popover-max-width);
+ // Our parent element can be arbitrary since tooltips are by default inserted as a sibling of their target element.
+ // So reset our font and text properties to avoid inheriting weird values.
+ @include reset-text();
+ @include font-size(var(--#{$prefix}popover-font-size));
+ // Allow breaking very long words so they don't overflow the popover's bounds
+ word-wrap: break-word;
+ background-color: var(--#{$prefix}popover-bg);
+ background-clip: padding-box;
+ border: var(--#{$prefix}popover-border-width) solid var(--#{$prefix}popover-border-color);
+ @include border-radius(var(--#{$prefix}popover-border-radius));
+ @include box-shadow(var(--#{$prefix}popover-box-shadow));
+
+ .popover-arrow {
+ display: block;
+ width: var(--#{$prefix}popover-arrow-width);
+ height: var(--#{$prefix}popover-arrow-height);
+
+ &::before,
+ &::after {
+ position: absolute;
+ display: block;
+ content: "";
+ border-color: transparent;
+ border-style: solid;
+ border-width: 0;
+ }
+ }
+}
+
+.bs-popover-top {
+ > .popover-arrow {
+ bottom: calc(-1 * (var(--#{$prefix}popover-arrow-height)) - var(--#{$prefix}popover-border-width)); // stylelint-disable-line function-disallowed-list
+
+ &::before,
+ &::after {
+ border-width: var(--#{$prefix}popover-arrow-height) calc(var(--#{$prefix}popover-arrow-width) * .5) 0; // stylelint-disable-line function-disallowed-list
+ }
+
+ &::before {
+ bottom: 0;
+ border-top-color: var(--#{$prefix}popover-arrow-border);
+ }
+
+ &::after {
+ bottom: var(--#{$prefix}popover-border-width);
+ border-top-color: var(--#{$prefix}popover-bg);
+ }
+ }
+}
+
+/* rtl:begin:ignore */
+.bs-popover-end {
+ > .popover-arrow {
+ left: calc(-1 * (var(--#{$prefix}popover-arrow-height)) - var(--#{$prefix}popover-border-width)); // stylelint-disable-line function-disallowed-list
+ width: var(--#{$prefix}popover-arrow-height);
+ height: var(--#{$prefix}popover-arrow-width);
+
+ &::before,
+ &::after {
+ border-width: calc(var(--#{$prefix}popover-arrow-width) * .5) var(--#{$prefix}popover-arrow-height) calc(var(--#{$prefix}popover-arrow-width) * .5) 0; // stylelint-disable-line function-disallowed-list
+ }
+
+ &::before {
+ left: 0;
+ border-right-color: var(--#{$prefix}popover-arrow-border);
+ }
+
+ &::after {
+ left: var(--#{$prefix}popover-border-width);
+ border-right-color: var(--#{$prefix}popover-bg);
+ }
+ }
+}
+
+/* rtl:end:ignore */
+
+.bs-popover-bottom {
+ > .popover-arrow {
+ top: calc(-1 * (var(--#{$prefix}popover-arrow-height)) - var(--#{$prefix}popover-border-width)); // stylelint-disable-line function-disallowed-list
+
+ &::before,
+ &::after {
+ border-width: 0 calc(var(--#{$prefix}popover-arrow-width) * .5) var(--#{$prefix}popover-arrow-height); // stylelint-disable-line function-disallowed-list
+ }
+
+ &::before {
+ top: 0;
+ border-bottom-color: var(--#{$prefix}popover-arrow-border);
+ }
+
+ &::after {
+ top: var(--#{$prefix}popover-border-width);
+ border-bottom-color: var(--#{$prefix}popover-bg);
+ }
+ }
+
+ // This will remove the popover-header's border just below the arrow
+ .popover-header::before {
+ position: absolute;
+ top: 0;
+ left: 50%;
+ display: block;
+ width: var(--#{$prefix}popover-arrow-width);
+ margin-left: calc(-.5 * var(--#{$prefix}popover-arrow-width)); // stylelint-disable-line function-disallowed-list
+ content: "";
+ border-bottom: var(--#{$prefix}popover-border-width) solid var(--#{$prefix}popover-header-bg);
+ }
+}
+
+/* rtl:begin:ignore */
+.bs-popover-start {
+ > .popover-arrow {
+ right: calc(-1 * (var(--#{$prefix}popover-arrow-height)) - var(--#{$prefix}popover-border-width)); // stylelint-disable-line function-disallowed-list
+ width: var(--#{$prefix}popover-arrow-height);
+ height: var(--#{$prefix}popover-arrow-width);
+
+ &::before,
+ &::after {
+ border-width: calc(var(--#{$prefix}popover-arrow-width) * .5) 0 calc(var(--#{$prefix}popover-arrow-width) * .5) var(--#{$prefix}popover-arrow-height); // stylelint-disable-line function-disallowed-list
+ }
+
+ &::before {
+ right: 0;
+ border-left-color: var(--#{$prefix}popover-arrow-border);
+ }
+
+ &::after {
+ right: var(--#{$prefix}popover-border-width);
+ border-left-color: var(--#{$prefix}popover-bg);
+ }
+ }
+}
+
+/* rtl:end:ignore */
+
+.bs-popover-auto {
+ &[data-popper-placement^="top"] {
+ @extend .bs-popover-top;
+ }
+ &[data-popper-placement^="right"] {
+ @extend .bs-popover-end;
+ }
+ &[data-popper-placement^="bottom"] {
+ @extend .bs-popover-bottom;
+ }
+ &[data-popper-placement^="left"] {
+ @extend .bs-popover-start;
+ }
+}
+
+// Offset the popover to account for the popover arrow
+.popover-header {
+ padding: var(--#{$prefix}popover-header-padding-y) var(--#{$prefix}popover-header-padding-x);
+ margin-bottom: 0; // Reset the default from Reboot
+ @include font-size(var(--#{$prefix}popover-header-font-size));
+ color: var(--#{$prefix}popover-header-color);
+ background-color: var(--#{$prefix}popover-header-bg);
+ border-bottom: var(--#{$prefix}popover-border-width) solid var(--#{$prefix}popover-border-color);
+ @include border-top-radius(var(--#{$prefix}popover-inner-border-radius));
+
+ &:empty {
+ display: none;
+ }
+}
+
+.popover-body {
+ padding: var(--#{$prefix}popover-body-padding-y) var(--#{$prefix}popover-body-padding-x);
+ color: var(--#{$prefix}popover-body-color);
+}
diff --git a/csit.infra.dash/app/cdash/static/sass/bootstrap/_progress.scss b/csit.infra.dash/app/cdash/static/sass/bootstrap/_progress.scss
new file mode 100644
index 0000000000..1bfafb58fa
--- /dev/null
+++ b/csit.infra.dash/app/cdash/static/sass/bootstrap/_progress.scss
@@ -0,0 +1,59 @@
+// Disable animation if transitions are disabled
+
+// scss-docs-start progress-keyframes
+@if $enable-transitions {
+ @keyframes progress-bar-stripes {
+ 0% { background-position-x: $progress-height; }
+ }
+}
+// scss-docs-end progress-keyframes
+
+.progress {
+ // scss-docs-start progress-css-vars
+ --#{$prefix}progress-height: #{$progress-height};
+ @include rfs($progress-font-size, --#{$prefix}progress-font-size);
+ --#{$prefix}progress-bg: #{$progress-bg};
+ --#{$prefix}progress-border-radius: #{$progress-border-radius};
+ --#{$prefix}progress-box-shadow: #{$progress-box-shadow};
+ --#{$prefix}progress-bar-color: #{$progress-bar-color};
+ --#{$prefix}progress-bar-bg: #{$progress-bar-bg};
+ --#{$prefix}progress-bar-transition: #{$progress-bar-transition};
+ // scss-docs-end progress-css-vars
+
+ display: flex;
+ height: var(--#{$prefix}progress-height);
+ overflow: hidden; // force rounded corners by cropping it
+ @include font-size(var(--#{$prefix}progress-font-size));
+ background-color: var(--#{$prefix}progress-bg);
+ @include border-radius(var(--#{$prefix}progress-border-radius));
+ @include box-shadow(var(--#{$prefix}progress-box-shadow));
+}
+
+.progress-bar {
+ display: flex;
+ flex-direction: column;
+ justify-content: center;
+ overflow: hidden;
+ color: var(--#{$prefix}progress-bar-color);
+ text-align: center;
+ white-space: nowrap;
+ background-color: var(--#{$prefix}progress-bar-bg);
+ @include transition(var(--#{$prefix}progress-bar-transition));
+}
+
+.progress-bar-striped {
+ @include gradient-striped();
+ background-size: var(--#{$prefix}progress-height) var(--#{$prefix}progress-height);
+}
+
+@if $enable-transitions {
+ .progress-bar-animated {
+ animation: $progress-bar-animation-timing progress-bar-stripes;
+
+ @if $enable-reduced-motion {
+ @media (prefers-reduced-motion: reduce) {
+ animation: none;
+ }
+ }
+ }
+}
diff --git a/csit.infra.dash/app/cdash/static/sass/bootstrap/_reboot.scss b/csit.infra.dash/app/cdash/static/sass/bootstrap/_reboot.scss
new file mode 100644
index 0000000000..8ac790399f
--- /dev/null
+++ b/csit.infra.dash/app/cdash/static/sass/bootstrap/_reboot.scss
@@ -0,0 +1,610 @@
+// stylelint-disable declaration-no-important, selector-no-qualifying-type, property-no-vendor-prefix
+
+
+// Reboot
+//
+// Normalization of HTML elements, manually forked from Normalize.css to remove
+// styles targeting irrelevant browsers while applying new styles.
+//
+// Normalize is licensed MIT. https://github.com/necolas/normalize.css
+
+
+// Document
+//
+// Change from `box-sizing: content-box` so that `width` is not affected by `padding` or `border`.
+
+*,
+*::before,
+*::after {
+ box-sizing: border-box;
+}
+
+
+// Root
+//
+// Ability to the value of the root font sizes, affecting the value of `rem`.
+// null by default, thus nothing is generated.
+
+:root {
+ @if $font-size-root != null {
+ @include font-size(var(--#{$prefix}root-font-size));
+ }
+
+ @if $enable-smooth-scroll {
+ @media (prefers-reduced-motion: no-preference) {
+ scroll-behavior: smooth;
+ }
+ }
+}
+
+
+// Body
+//
+// 1. Remove the margin in all browsers.
+// 2. As a best practice, apply a default `background-color`.
+// 3. Prevent adjustments of font size after orientation changes in iOS.
+// 4. Change the default tap highlight to be completely transparent in iOS.
+
+// scss-docs-start reboot-body-rules
+body {
+ margin: 0; // 1
+ font-family: var(--#{$prefix}body-font-family);
+ @include font-size(var(--#{$prefix}body-font-size));
+ font-weight: var(--#{$prefix}body-font-weight);
+ line-height: var(--#{$prefix}body-line-height);
+ color: var(--#{$prefix}body-color);
+ text-align: var(--#{$prefix}body-text-align);
+ background-color: var(--#{$prefix}body-bg); // 2
+ -webkit-text-size-adjust: 100%; // 3
+ -webkit-tap-highlight-color: rgba($black, 0); // 4
+}
+// scss-docs-end reboot-body-rules
+
+
+// Content grouping
+//
+// 1. Reset Firefox's gray color
+
+hr {
+ margin: $hr-margin-y 0;
+ color: $hr-color; // 1
+ border: 0;
+ border-top: $hr-border-width solid $hr-border-color;
+ opacity: $hr-opacity;
+}
+
+
+// Typography
+//
+// 1. Remove top margins from headings
+// By default, `<h1>`-`<h6>` all receive top and bottom margins. We nuke the top
+// margin for easier control within type scales as it avoids margin collapsing.
+
+%heading {
+ margin-top: 0; // 1
+ margin-bottom: $headings-margin-bottom;
+ font-family: $headings-font-family;
+ font-style: $headings-font-style;
+ font-weight: $headings-font-weight;
+ line-height: $headings-line-height;
+ color: $headings-color;
+}
+
+h1 {
+ @extend %heading;
+ @include font-size($h1-font-size);
+}
+
+h2 {
+ @extend %heading;
+ @include font-size($h2-font-size);
+}
+
+h3 {
+ @extend %heading;
+ @include font-size($h3-font-size);
+}
+
+h4 {
+ @extend %heading;
+ @include font-size($h4-font-size);
+}
+
+h5 {
+ @extend %heading;
+ @include font-size($h5-font-size);
+}
+
+h6 {
+ @extend %heading;
+ @include font-size($h6-font-size);
+}
+
+
+// Reset margins on paragraphs
+//
+// Similarly, the top margin on `<p>`s get reset. However, we also reset the
+// bottom margin to use `rem` units instead of `em`.
+
+p {
+ margin-top: 0;
+ margin-bottom: $paragraph-margin-bottom;
+}
+
+
+// Abbreviations
+//
+// 1. Add the correct text decoration in Chrome, Edge, Opera, and Safari.
+// 2. Add explicit cursor to indicate changed behavior.
+// 3. Prevent the text-decoration to be skipped.
+
+abbr[title] {
+ text-decoration: underline dotted; // 1
+ cursor: help; // 2
+ text-decoration-skip-ink: none; // 3
+}
+
+
+// Address
+
+address {
+ margin-bottom: 1rem;
+ font-style: normal;
+ line-height: inherit;
+}
+
+
+// Lists
+
+ol,
+ul {
+ padding-left: 2rem;
+}
+
+ol,
+ul,
+dl {
+ margin-top: 0;
+ margin-bottom: 1rem;
+}
+
+ol ol,
+ul ul,
+ol ul,
+ul ol {
+ margin-bottom: 0;
+}
+
+dt {
+ font-weight: $dt-font-weight;
+}
+
+// 1. Undo browser default
+
+dd {
+ margin-bottom: .5rem;
+ margin-left: 0; // 1
+}
+
+
+// Blockquote
+
+blockquote {
+ margin: 0 0 1rem;
+}
+
+
+// Strong
+//
+// Add the correct font weight in Chrome, Edge, and Safari
+
+b,
+strong {
+ font-weight: $font-weight-bolder;
+}
+
+
+// Small
+//
+// Add the correct font size in all browsers
+
+small {
+ @include font-size($small-font-size);
+}
+
+
+// Mark
+
+mark {
+ padding: $mark-padding;
+ background-color: var(--#{$prefix}highlight-bg);
+}
+
+
+// Sub and Sup
+//
+// Prevent `sub` and `sup` elements from affecting the line height in
+// all browsers.
+
+sub,
+sup {
+ position: relative;
+ @include font-size($sub-sup-font-size);
+ line-height: 0;
+ vertical-align: baseline;
+}
+
+sub { bottom: -.25em; }
+sup { top: -.5em; }
+
+
+// Links
+
+a {
+ color: var(--#{$prefix}link-color);
+ text-decoration: $link-decoration;
+
+ &:hover {
+ color: var(--#{$prefix}link-hover-color);
+ text-decoration: $link-hover-decoration;
+ }
+}
+
+// And undo these styles for placeholder links/named anchors (without href).
+// It would be more straightforward to just use a[href] in previous block, but that
+// causes specificity issues in many other styles that are too complex to fix.
+// See https://github.com/twbs/bootstrap/issues/19402
+
+a:not([href]):not([class]) {
+ &,
+ &:hover {
+ color: inherit;
+ text-decoration: none;
+ }
+}
+
+
+// Code
+
+pre,
+code,
+kbd,
+samp {
+ font-family: $font-family-code;
+ @include font-size(1em); // Correct the odd `em` font sizing in all browsers.
+}
+
+// 1. Remove browser default top margin
+// 2. Reset browser default of `1em` to use `rem`s
+// 3. Don't allow content to break outside
+
+pre {
+ display: block;
+ margin-top: 0; // 1
+ margin-bottom: 1rem; // 2
+ overflow: auto; // 3
+ @include font-size($code-font-size);
+ color: $pre-color;
+
+ // Account for some code outputs that place code tags in pre tags
+ code {
+ @include font-size(inherit);
+ color: inherit;
+ word-break: normal;
+ }
+}
+
+code {
+ @include font-size($code-font-size);
+ color: var(--#{$prefix}code-color);
+ word-wrap: break-word;
+
+ // Streamline the style when inside anchors to avoid broken underline and more
+ a > & {
+ color: inherit;
+ }
+}
+
+kbd {
+ padding: $kbd-padding-y $kbd-padding-x;
+ @include font-size($kbd-font-size);
+ color: $kbd-color;
+ background-color: $kbd-bg;
+ @include border-radius($border-radius-sm);
+
+ kbd {
+ padding: 0;
+ @include font-size(1em);
+ font-weight: $nested-kbd-font-weight;
+ }
+}
+
+
+// Figures
+//
+// Apply a consistent margin strategy (matches our type styles).
+
+figure {
+ margin: 0 0 1rem;
+}
+
+
+// Images and content
+
+img,
+svg {
+ vertical-align: middle;
+}
+
+
+// Tables
+//
+// Prevent double borders
+
+table {
+ caption-side: bottom;
+ border-collapse: collapse;
+}
+
+caption {
+ padding-top: $table-cell-padding-y;
+ padding-bottom: $table-cell-padding-y;
+ color: $table-caption-color;
+ text-align: left;
+}
+
+// 1. Removes font-weight bold by inheriting
+// 2. Matches default `<td>` alignment by inheriting `text-align`.
+// 3. Fix alignment for Safari
+
+th {
+ font-weight: $table-th-font-weight; // 1
+ text-align: inherit; // 2
+ text-align: -webkit-match-parent; // 3
+}
+
+thead,
+tbody,
+tfoot,
+tr,
+td,
+th {
+ border-color: inherit;
+ border-style: solid;
+ border-width: 0;
+}
+
+
+// Forms
+//
+// 1. Allow labels to use `margin` for spacing.
+
+label {
+ display: inline-block; // 1
+}
+
+// Remove the default `border-radius` that macOS Chrome adds.
+// See https://github.com/twbs/bootstrap/issues/24093
+
+button {
+ // stylelint-disable-next-line property-disallowed-list
+ border-radius: 0;
+}
+
+// Explicitly remove focus outline in Chromium when it shouldn't be
+// visible (e.g. as result of mouse click or touch tap). It already
+// should be doing this automatically, but seems to currently be
+// confused and applies its very visible two-tone outline anyway.
+
+button:focus:not(:focus-visible) {
+ outline: 0;
+}
+
+// 1. Remove the margin in Firefox and Safari
+
+input,
+button,
+select,
+optgroup,
+textarea {
+ margin: 0; // 1
+ font-family: inherit;
+ @include font-size(inherit);
+ line-height: inherit;
+}
+
+// Remove the inheritance of text transform in Firefox
+button,
+select {
+ text-transform: none;
+}
+// Set the cursor for non-`<button>` buttons
+//
+// Details at https://github.com/twbs/bootstrap/pull/30562
+[role="button"] {
+ cursor: pointer;
+}
+
+select {
+ // Remove the inheritance of word-wrap in Safari.
+ // See https://github.com/twbs/bootstrap/issues/24990
+ word-wrap: normal;
+
+ // Undo the opacity change from Chrome
+ &:disabled {
+ opacity: 1;
+ }
+}
+
+// Remove the dropdown arrow only from text type inputs built with datalists in Chrome.
+// See https://stackoverflow.com/a/54997118
+
+[list]:not([type="date"]):not([type="datetime-local"]):not([type="month"]):not([type="week"]):not([type="time"])::-webkit-calendar-picker-indicator {
+ display: none !important;
+}
+
+// 1. Prevent a WebKit bug where (2) destroys native `audio` and `video`
+// controls in Android 4.
+// 2. Correct the inability to style clickable types in iOS and Safari.
+// 3. Opinionated: add "hand" cursor to non-disabled button elements.
+
+button,
+[type="button"], // 1
+[type="reset"],
+[type="submit"] {
+ -webkit-appearance: button; // 2
+
+ @if $enable-button-pointers {
+ &:not(:disabled) {
+ cursor: pointer; // 3
+ }
+ }
+}
+
+// Remove inner border and padding from Firefox, but don't restore the outline like Normalize.
+
+::-moz-focus-inner {
+ padding: 0;
+ border-style: none;
+}
+
+// 1. Textareas should really only resize vertically so they don't break their (horizontal) containers.
+
+textarea {
+ resize: vertical; // 1
+}
+
+// 1. Browsers set a default `min-width: min-content;` on fieldsets,
+// unlike e.g. `<div>`s, which have `min-width: 0;` by default.
+// So we reset that to ensure fieldsets behave more like a standard block element.
+// See https://github.com/twbs/bootstrap/issues/12359
+// and https://html.spec.whatwg.org/multipage/#the-fieldset-and-legend-elements
+// 2. Reset the default outline behavior of fieldsets so they don't affect page layout.
+
+fieldset {
+ min-width: 0; // 1
+ padding: 0; // 2
+ margin: 0; // 2
+ border: 0; // 2
+}
+
+// 1. By using `float: left`, the legend will behave like a block element.
+// This way the border of a fieldset wraps around the legend if present.
+// 2. Fix wrapping bug.
+// See https://github.com/twbs/bootstrap/issues/29712
+
+legend {
+ float: left; // 1
+ width: 100%;
+ padding: 0;
+ margin-bottom: $legend-margin-bottom;
+ @include font-size($legend-font-size);
+ font-weight: $legend-font-weight;
+ line-height: inherit;
+
+ + * {
+ clear: left; // 2
+ }
+}
+
+// Fix height of inputs with a type of datetime-local, date, month, week, or time
+// See https://github.com/twbs/bootstrap/issues/18842
+
+::-webkit-datetime-edit-fields-wrapper,
+::-webkit-datetime-edit-text,
+::-webkit-datetime-edit-minute,
+::-webkit-datetime-edit-hour-field,
+::-webkit-datetime-edit-day-field,
+::-webkit-datetime-edit-month-field,
+::-webkit-datetime-edit-year-field {
+ padding: 0;
+}
+
+::-webkit-inner-spin-button {
+ height: auto;
+}
+
+// 1. Correct the outline style in Safari.
+// 2. This overrides the extra rounded corners on search inputs in iOS so that our
+// `.form-control` class can properly style them. Note that this cannot simply
+// be added to `.form-control` as it's not specific enough. For details, see
+// https://github.com/twbs/bootstrap/issues/11586.
+
+[type="search"] {
+ outline-offset: -2px; // 1
+ -webkit-appearance: textfield; // 2
+}
+
+// 1. A few input types should stay LTR
+// See https://rtlstyling.com/posts/rtl-styling#form-inputs
+// 2. RTL only output
+// See https://rtlcss.com/learn/usage-guide/control-directives/#raw
+
+/* rtl:raw:
+[type="tel"],
+[type="url"],
+[type="email"],
+[type="number"] {
+ direction: ltr;
+}
+*/
+
+// Remove the inner padding in Chrome and Safari on macOS.
+
+::-webkit-search-decoration {
+ -webkit-appearance: none;
+}
+
+// Remove padding around color pickers in webkit browsers
+
+::-webkit-color-swatch-wrapper {
+ padding: 0;
+}
+
+
+// 1. Inherit font family and line height for file input buttons
+// 2. Correct the inability to style clickable types in iOS and Safari.
+
+::file-selector-button {
+ font: inherit; // 1
+ -webkit-appearance: button; // 2
+}
+
+// Correct element displays
+
+output {
+ display: inline-block;
+}
+
+// Remove border from iframe
+
+iframe {
+ border: 0;
+}
+
+// Summary
+//
+// 1. Add the correct display in all browsers
+
+summary {
+ display: list-item; // 1
+ cursor: pointer;
+}
+
+
+// Progress
+//
+// Add the correct vertical alignment in Chrome, Firefox, and Opera.
+
+progress {
+ vertical-align: baseline;
+}
+
+
+// Hidden attribute
+//
+// Always hide an element with the `hidden` HTML attribute.
+
+[hidden] {
+ display: none !important;
+}
diff --git a/csit.infra.dash/app/cdash/static/sass/bootstrap/_root.scss b/csit.infra.dash/app/cdash/static/sass/bootstrap/_root.scss
new file mode 100644
index 0000000000..e64ae04e57
--- /dev/null
+++ b/csit.infra.dash/app/cdash/static/sass/bootstrap/_root.scss
@@ -0,0 +1,73 @@
+:root {
+ // Note: Custom variable values only support SassScript inside `#{}`.
+
+ // Colors
+ //
+ // Generate palettes for full colors, grays, and theme colors.
+
+ @each $color, $value in $colors {
+ --#{$prefix}#{$color}: #{$value};
+ }
+
+ @each $color, $value in $grays {
+ --#{$prefix}gray-#{$color}: #{$value};
+ }
+
+ @each $color, $value in $theme-colors {
+ --#{$prefix}#{$color}: #{$value};
+ }
+
+ @each $color, $value in $theme-colors-rgb {
+ --#{$prefix}#{$color}-rgb: #{$value};
+ }
+
+ --#{$prefix}white-rgb: #{to-rgb($white)};
+ --#{$prefix}black-rgb: #{to-rgb($black)};
+ --#{$prefix}body-color-rgb: #{to-rgb($body-color)};
+ --#{$prefix}body-bg-rgb: #{to-rgb($body-bg)};
+
+ // Fonts
+
+ // Note: Use `inspect` for lists so that quoted items keep the quotes.
+ // See https://github.com/sass/sass/issues/2383#issuecomment-336349172
+ --#{$prefix}font-sans-serif: #{inspect($font-family-sans-serif)};
+ --#{$prefix}font-monospace: #{inspect($font-family-monospace)};
+ --#{$prefix}gradient: #{$gradient};
+
+ // Root and body
+ // scss-docs-start root-body-variables
+ @if $font-size-root != null {
+ --#{$prefix}root-font-size: #{$font-size-root};
+ }
+ --#{$prefix}body-font-family: #{$font-family-base};
+ @include rfs($font-size-base, --#{$prefix}body-font-size);
+ --#{$prefix}body-font-weight: #{$font-weight-base};
+ --#{$prefix}body-line-height: #{$line-height-base};
+ --#{$prefix}body-color: #{$body-color};
+ @if $body-text-align != null {
+ --#{$prefix}body-text-align: #{$body-text-align};
+ }
+ --#{$prefix}body-bg: #{$body-bg};
+ // scss-docs-end root-body-variables
+
+ // scss-docs-start root-border-var
+ --#{$prefix}border-width: #{$border-width};
+ --#{$prefix}border-style: #{$border-style};
+ --#{$prefix}border-color: #{$border-color};
+ --#{$prefix}border-color-translucent: #{$border-color-translucent};
+
+ --#{$prefix}border-radius: #{$border-radius};
+ --#{$prefix}border-radius-sm: #{$border-radius-sm};
+ --#{$prefix}border-radius-lg: #{$border-radius-lg};
+ --#{$prefix}border-radius-xl: #{$border-radius-xl};
+ --#{$prefix}border-radius-2xl: #{$border-radius-2xl};
+ --#{$prefix}border-radius-pill: #{$border-radius-pill};
+ // scss-docs-end root-border-var
+
+ --#{$prefix}link-color: #{$link-color};
+ --#{$prefix}link-hover-color: #{$link-hover-color};
+
+ --#{$prefix}code-color: #{$code-color};
+
+ --#{$prefix}highlight-bg: #{$mark-bg};
+}
diff --git a/csit.infra.dash/app/cdash/static/sass/bootstrap/_spinners.scss b/csit.infra.dash/app/cdash/static/sass/bootstrap/_spinners.scss
new file mode 100644
index 0000000000..ec8473207e
--- /dev/null
+++ b/csit.infra.dash/app/cdash/static/sass/bootstrap/_spinners.scss
@@ -0,0 +1,85 @@
+//
+// Rotating border
+//
+
+.spinner-grow,
+.spinner-border {
+ display: inline-block;
+ width: var(--#{$prefix}spinner-width);
+ height: var(--#{$prefix}spinner-height);
+ vertical-align: var(--#{$prefix}spinner-vertical-align);
+ // stylelint-disable-next-line property-disallowed-list
+ border-radius: 50%;
+ animation: var(--#{$prefix}spinner-animation-speed) linear infinite var(--#{$prefix}spinner-animation-name);
+}
+
+// scss-docs-start spinner-border-keyframes
+@keyframes spinner-border {
+ to { transform: rotate(360deg) #{"/* rtl:ignore */"}; }
+}
+// scss-docs-end spinner-border-keyframes
+
+.spinner-border {
+ // scss-docs-start spinner-border-css-vars
+ --#{$prefix}spinner-width: #{$spinner-width};
+ --#{$prefix}spinner-height: #{$spinner-height};
+ --#{$prefix}spinner-vertical-align: #{$spinner-vertical-align};
+ --#{$prefix}spinner-border-width: #{$spinner-border-width};
+ --#{$prefix}spinner-animation-speed: #{$spinner-animation-speed};
+ --#{$prefix}spinner-animation-name: spinner-border;
+ // scss-docs-end spinner-border-css-vars
+
+ border: var(--#{$prefix}spinner-border-width) solid currentcolor;
+ border-right-color: transparent;
+}
+
+.spinner-border-sm {
+ // scss-docs-start spinner-border-sm-css-vars
+ --#{$prefix}spinner-width: #{$spinner-width-sm};
+ --#{$prefix}spinner-height: #{$spinner-height-sm};
+ --#{$prefix}spinner-border-width: #{$spinner-border-width-sm};
+ // scss-docs-end spinner-border-sm-css-vars
+}
+
+//
+// Growing circle
+//
+
+// scss-docs-start spinner-grow-keyframes
+@keyframes spinner-grow {
+ 0% {
+ transform: scale(0);
+ }
+ 50% {
+ opacity: 1;
+ transform: none;
+ }
+}
+// scss-docs-end spinner-grow-keyframes
+
+.spinner-grow {
+ // scss-docs-start spinner-grow-css-vars
+ --#{$prefix}spinner-width: #{$spinner-width};
+ --#{$prefix}spinner-height: #{$spinner-height};
+ --#{$prefix}spinner-vertical-align: #{$spinner-vertical-align};
+ --#{$prefix}spinner-animation-speed: #{$spinner-animation-speed};
+ --#{$prefix}spinner-animation-name: spinner-grow;
+ // scss-docs-end spinner-grow-css-vars
+
+ background-color: currentcolor;
+ opacity: 0;
+}
+
+.spinner-grow-sm {
+ --#{$prefix}spinner-width: #{$spinner-width-sm};
+ --#{$prefix}spinner-height: #{$spinner-height-sm};
+}
+
+@if $enable-reduced-motion {
+ @media (prefers-reduced-motion: reduce) {
+ .spinner-border,
+ .spinner-grow {
+ --#{$prefix}spinner-animation-speed: #{$spinner-animation-speed * 2};
+ }
+ }
+}
diff --git a/csit.infra.dash/app/cdash/static/sass/bootstrap/_tables.scss b/csit.infra.dash/app/cdash/static/sass/bootstrap/_tables.scss
new file mode 100644
index 0000000000..1fdd43c6bb
--- /dev/null
+++ b/csit.infra.dash/app/cdash/static/sass/bootstrap/_tables.scss
@@ -0,0 +1,164 @@
+//
+// Basic Bootstrap table
+//
+
+.table {
+ --#{$prefix}table-color: #{$table-color};
+ --#{$prefix}table-bg: #{$table-bg};
+ --#{$prefix}table-border-color: #{$table-border-color};
+ --#{$prefix}table-accent-bg: #{$table-accent-bg};
+ --#{$prefix}table-striped-color: #{$table-striped-color};
+ --#{$prefix}table-striped-bg: #{$table-striped-bg};
+ --#{$prefix}table-active-color: #{$table-active-color};
+ --#{$prefix}table-active-bg: #{$table-active-bg};
+ --#{$prefix}table-hover-color: #{$table-hover-color};
+ --#{$prefix}table-hover-bg: #{$table-hover-bg};
+
+ width: 100%;
+ margin-bottom: $spacer;
+ color: var(--#{$prefix}table-color);
+ vertical-align: $table-cell-vertical-align;
+ border-color: var(--#{$prefix}table-border-color);
+
+ // Target th & td
+ // We need the child combinator to prevent styles leaking to nested tables which doesn't have a `.table` class.
+ // We use the universal selectors here to simplify the selector (else we would need 6 different selectors).
+ // Another advantage is that this generates less code and makes the selector less specific making it easier to override.
+ // stylelint-disable-next-line selector-max-universal
+ > :not(caption) > * > * {
+ padding: $table-cell-padding-y $table-cell-padding-x;
+ background-color: var(--#{$prefix}table-bg);
+ border-bottom-width: $table-border-width;
+ box-shadow: inset 0 0 0 9999px var(--#{$prefix}table-accent-bg);
+ }
+
+ > tbody {
+ vertical-align: inherit;
+ }
+
+ > thead {
+ vertical-align: bottom;
+ }
+}
+
+.table-group-divider {
+ border-top: ($table-border-width * 2) solid $table-group-separator-color;
+}
+
+//
+// Change placement of captions with a class
+//
+
+.caption-top {
+ caption-side: top;
+}
+
+
+//
+// Condensed table w/ half padding
+//
+
+.table-sm {
+ // stylelint-disable-next-line selector-max-universal
+ > :not(caption) > * > * {
+ padding: $table-cell-padding-y-sm $table-cell-padding-x-sm;
+ }
+}
+
+
+// Border versions
+//
+// Add or remove borders all around the table and between all the columns.
+//
+// When borders are added on all sides of the cells, the corners can render odd when
+// these borders do not have the same color or if they are semi-transparent.
+// Therefor we add top and border bottoms to the `tr`s and left and right borders
+// to the `td`s or `th`s
+
+.table-bordered {
+ > :not(caption) > * {
+ border-width: $table-border-width 0;
+
+ // stylelint-disable-next-line selector-max-universal
+ > * {
+ border-width: 0 $table-border-width;
+ }
+ }
+}
+
+.table-borderless {
+ // stylelint-disable-next-line selector-max-universal
+ > :not(caption) > * > * {
+ border-bottom-width: 0;
+ }
+
+ > :not(:first-child) {
+ border-top-width: 0;
+ }
+}
+
+// Zebra-striping
+//
+// Default zebra-stripe styles (alternating gray and transparent backgrounds)
+
+// For rows
+.table-striped {
+ > tbody > tr:nth-of-type(#{$table-striped-order}) > * {
+ --#{$prefix}table-accent-bg: var(--#{$prefix}table-striped-bg);
+ color: var(--#{$prefix}table-striped-color);
+ }
+}
+
+// For columns
+.table-striped-columns {
+ > :not(caption) > tr > :nth-child(#{$table-striped-columns-order}) {
+ --#{$prefix}table-accent-bg: var(--#{$prefix}table-striped-bg);
+ color: var(--#{$prefix}table-striped-color);
+ }
+}
+
+// Active table
+//
+// The `.table-active` class can be added to highlight rows or cells
+
+.table-active {
+ --#{$prefix}table-accent-bg: var(--#{$prefix}table-active-bg);
+ color: var(--#{$prefix}table-active-color);
+}
+
+// Hover effect
+//
+// Placed here since it has to come after the potential zebra striping
+
+.table-hover {
+ > tbody > tr:hover > * {
+ --#{$prefix}table-accent-bg: var(--#{$prefix}table-hover-bg);
+ color: var(--#{$prefix}table-hover-color);
+ }
+}
+
+
+// Table variants
+//
+// Table variants set the table cell backgrounds, border colors
+// and the colors of the striped, hovered & active tables
+
+@each $color, $value in $table-variants {
+ @include table-variant($color, $value);
+}
+
+// Responsive tables
+//
+// Generate series of `.table-responsive-*` classes for configuring the screen
+// size of where your table will overflow.
+
+@each $breakpoint in map-keys($grid-breakpoints) {
+ $infix: breakpoint-infix($breakpoint, $grid-breakpoints);
+
+ @include media-breakpoint-down($breakpoint) {
+ .table-responsive#{$infix} {
+ overflow-x: auto;
+ -webkit-overflow-scrolling: touch;
+ }
+ }
+}
diff --git a/csit.infra.dash/app/cdash/static/sass/bootstrap/_toasts.scss b/csit.infra.dash/app/cdash/static/sass/bootstrap/_toasts.scss
new file mode 100644
index 0000000000..c34e49b241
--- /dev/null
+++ b/csit.infra.dash/app/cdash/static/sass/bootstrap/_toasts.scss
@@ -0,0 +1,71 @@
+.toast {
+ // scss-docs-start toast-css-vars
+ --#{$prefix}toast-zindex: #{$zindex-toast};
+ --#{$prefix}toast-padding-x: #{$toast-padding-x};
+ --#{$prefix}toast-padding-y: #{$toast-padding-y};
+ --#{$prefix}toast-spacing: #{$toast-spacing};
+ --#{$prefix}toast-max-width: #{$toast-max-width};
+ @include rfs($toast-font-size, --#{$prefix}toast-font-size);
+ --#{$prefix}toast-color: #{$toast-color};
+ --#{$prefix}toast-bg: #{$toast-background-color};
+ --#{$prefix}toast-border-width: #{$toast-border-width};
+ --#{$prefix}toast-border-color: #{$toast-border-color};
+ --#{$prefix}toast-border-radius: #{$toast-border-radius};
+ --#{$prefix}toast-box-shadow: #{$toast-box-shadow};
+ --#{$prefix}toast-header-color: #{$toast-header-color};
+ --#{$prefix}toast-header-bg: #{$toast-header-background-color};
+ --#{$prefix}toast-header-border-color: #{$toast-header-border-color};
+ // scss-docs-end toast-css-vars
+
+ width: var(--#{$prefix}toast-max-width);
+ max-width: 100%;
+ @include font-size(var(--#{$prefix}toast-font-size));
+ color: var(--#{$prefix}toast-color);
+ pointer-events: auto;
+ background-color: var(--#{$prefix}toast-bg);
+ background-clip: padding-box;
+ border: var(--#{$prefix}toast-border-width) solid var(--#{$prefix}toast-border-color);
+ box-shadow: var(--#{$prefix}toast-box-shadow);
+ @include border-radius(var(--#{$prefix}toast-border-radius));
+
+ &.showing {
+ opacity: 0;
+ }
+
+ &:not(.show) {
+ display: none;
+ }
+}
+
+.toast-container {
+ position: absolute;
+ z-index: var(--#{$prefix}toast-zindex);
+ width: max-content;
+ max-width: 100%;
+ pointer-events: none;
+
+ > :not(:last-child) {
+ margin-bottom: var(--#{$prefix}toast-spacing);
+ }
+}
+
+.toast-header {
+ display: flex;
+ align-items: center;
+ padding: var(--#{$prefix}toast-padding-y) var(--#{$prefix}toast-padding-x);
+ color: var(--#{$prefix}toast-header-color);
+ background-color: var(--#{$prefix}toast-header-bg);
+ background-clip: padding-box;
+ border-bottom: var(--#{$prefix}toast-border-width) solid var(--#{$prefix}toast-header-border-color);
+ @include border-top-radius(calc(var(--#{$prefix}toast-border-radius) - var(--#{$prefix}toast-border-width)));
+
+ .btn-close {
+ margin-right: calc(-.5 * var(--#{$prefix}toast-padding-x)); // stylelint-disable-line function-disallowed-list
+ margin-left: var(--#{$prefix}toast-padding-x);
+ }
+}
+
+.toast-body {
+ padding: var(--#{$prefix}toast-padding-x);
+ word-wrap: break-word;
+}
diff --git a/csit.infra.dash/app/cdash/static/sass/bootstrap/_tooltip.scss b/csit.infra.dash/app/cdash/static/sass/bootstrap/_tooltip.scss
new file mode 100644
index 0000000000..7da3df3e00
--- /dev/null
+++ b/csit.infra.dash/app/cdash/static/sass/bootstrap/_tooltip.scss
@@ -0,0 +1,120 @@
+// Base class
+.tooltip {
+ // scss-docs-start tooltip-css-vars
+ --#{$prefix}tooltip-zindex: #{$zindex-tooltip};
+ --#{$prefix}tooltip-max-width: #{$tooltip-max-width};
+ --#{$prefix}tooltip-padding-x: #{$tooltip-padding-x};
+ --#{$prefix}tooltip-padding-y: #{$tooltip-padding-y};
+ --#{$prefix}tooltip-margin: #{$tooltip-margin};
+ @include rfs($tooltip-font-size, --#{$prefix}tooltip-font-size);
+ --#{$prefix}tooltip-color: #{$tooltip-color};
+ --#{$prefix}tooltip-bg: #{$tooltip-bg};
+ --#{$prefix}tooltip-border-radius: #{$tooltip-border-radius};
+ --#{$prefix}tooltip-opacity: #{$tooltip-opacity};
+ --#{$prefix}tooltip-arrow-width: #{$tooltip-arrow-width};
+ --#{$prefix}tooltip-arrow-height: #{$tooltip-arrow-height};
+ // scss-docs-end tooltip-css-vars
+
+ z-index: var(--#{$prefix}tooltip-zindex);
+ display: block;
+ padding: var(--#{$prefix}tooltip-arrow-height);
+ margin: var(--#{$prefix}tooltip-margin);
+ @include deprecate("`$tooltip-margin`", "v5", "v5.x", true);
+ // Our parent element can be arbitrary since tooltips are by default inserted as a sibling of their target element.
+ // So reset our font and text properties to avoid inheriting weird values.
+ @include reset-text();
+ @include font-size(var(--#{$prefix}tooltip-font-size));
+ // Allow breaking very long words so they don't overflow the tooltip's bounds
+ word-wrap: break-word;
+ opacity: 0;
+
+ &.show { opacity: var(--#{$prefix}tooltip-opacity); }
+
+ .tooltip-arrow {
+ display: block;
+ width: var(--#{$prefix}tooltip-arrow-width);
+ height: var(--#{$prefix}tooltip-arrow-height);
+
+ &::before {
+ position: absolute;
+ content: "";
+ border-color: transparent;
+ border-style: solid;
+ }
+ }
+}
+
+.bs-tooltip-top .tooltip-arrow {
+ bottom: 0;
+
+ &::before {
+ top: -1px;
+ border-width: var(--#{$prefix}tooltip-arrow-height) calc(var(--#{$prefix}tooltip-arrow-width) * .5) 0; // stylelint-disable-line function-disallowed-list
+ border-top-color: var(--#{$prefix}tooltip-bg);
+ }
+}
+
+/* rtl:begin:ignore */
+.bs-tooltip-end .tooltip-arrow {
+ left: 0;
+ width: var(--#{$prefix}tooltip-arrow-height);
+ height: var(--#{$prefix}tooltip-arrow-width);
+
+ &::before {
+ right: -1px;
+ border-width: calc(var(--#{$prefix}tooltip-arrow-width) * .5) var(--#{$prefix}tooltip-arrow-height) calc(var(--#{$prefix}tooltip-arrow-width) * .5) 0; // stylelint-disable-line function-disallowed-list
+ border-right-color: var(--#{$prefix}tooltip-bg);
+ }
+}
+
+/* rtl:end:ignore */
+
+.bs-tooltip-bottom .tooltip-arrow {
+ top: 0;
+
+ &::before {