diff --git a/3mdeb-templates.json b/3mdeb-templates.json index ecd7f8aa..9114e885 100644 --- a/3mdeb-templates.json +++ b/3mdeb-templates.json @@ -1,7 +1,7 @@ { "JobGroups": [ { - "template": "defaults:\n x86_64:\n machine: qemu\n priority: 70\nproducts:\n qubesos-4.2.3-install-iso-x86_64:\n distri: qubesos\n flavor: install-iso\n version: '4.2.3'\n qubesos-4.2.3-install-iso-iommu-x86_64:\n distri: qubesos\n flavor: install-iso-iommu\n version: '4.2.3'\n qubesos-4.2.3-install-iso-hw-x86_64:\n distri: qubesos\n flavor: install-iso-hw\n version: '4.2.3'\n qubesos-4.2.3-install-iso-optiplex-uefi-x86_64:\n distri: qubesos\n flavor: install-iso-optiplex-uefi\n version: '4.2.3'\n qubesos-4.2.3-install-iso-hpt630v1-legacy-x86_64:\n distri: qubesos\n flavor: install-iso-hpt630v1-legacy\n version: '4.2.3'\n qubesos-4.2.3-install-iso-hpt630v1-uefi-x86_64:\n distri: qubesos\n flavor: install-iso-hpt630v1-uefi\n version: '4.2.3'\n qubesos-4.2.3-install-iso-hpt630v2-legacy-x86_64:\n distri: qubesos\n flavor: install-iso-hpt630v2-legacy\n version: '4.2.3'\n qubesos-4.2.3-install-iso-hpt630v2-uefi-x86_64:\n distri: qubesos\n flavor: install-iso-hpt630v2-uefi\n version: '4.2.3'\n qubesos-4.2.3-install-iso-vp4670-legacy-x86_64:\n distri: qubesos\n flavor: install-iso-vp4670-legacy\n version: '4.2.3'\n qubesos-4.2.3-install-iso-vp4670-uefi-x86_64:\n distri: qubesos\n flavor: install-iso-vp4670-uefi\n version: '4.2.3'\nscenarios:\n x86_64:\n qubesos-4.2.3-install-iso-vp4670-uefi-x86_64:\n - installation:\n machine: vp4670\n #- aem-setup:\n # machine: vp4650\n #- aem-first-run:\n # machine: vp4650\n #- aem-second-run:\n # machine: vp4650\n qubesos-4.2.3-install-iso-hpt630v1-legacy-x86_64:\n - installation:\n machine: hpt630v1\n - aem-setup:\n machine: hpt630v1\n - aem-first-run:\n machine: hpt630v1\n - aem-second-run:\n machine: hpt630v1\n qubesos-4.2.3-install-iso-hpt630v1-uefi-x86_64:\n - installation:\n machine: hpt630v1\n - aem-setup:\n machine: hpt630v1\n - aem-first-run:\n machine: hpt630v1\n - aem-second-run:\n machine: hpt630v1\n qubesos-4.2.3-install-iso-hpt630v2-legacy-x86_64:\n - installation:\n machine: hpt630v2\n - aem-setup:\n machine: hpt630v2\n - aem-first-run:\n machine: hpt630v2\n - aem-second-run:\n machine: hpt630v2\n qubesos-4.2.3-install-iso-hpt630v2-uefi-x86_64:\n - installation:\n machine: hpt630v2\n - aem-setup:\n machine: hpt630v2\n - aem-first-run:\n machine: hpt630v2\n - aem-second-run:\n machine: hpt630v2\n qubesos-4.2.3-install-iso-optiplex-uefi-x86_64:\n - installation:\n machine: optiplex\n - aem-setup:\n machine: optiplex\n - aem-first-run:\n machine: optiplex\n - aem-second-run:\n machine: optiplex\n", + "template": "defaults:\n x86_64:\n machine: qemu\n priority: 70\nproducts:\n qubesos-4.2.3-install-iso-x86_64:\n distri: qubesos\n flavor: install-iso\n version: '4.2.3'\n qubesos-4.2.3-install-iso-iommu-x86_64:\n distri: qubesos\n flavor: install-iso-iommu\n version: '4.2.3'\n qubesos-4.2.3-install-iso-hw-x86_64:\n distri: qubesos\n flavor: install-iso-hw\n version: '4.2.3'\n qubesos-4.2.3-install-iso-optiplex-legacy-x86_64:\n distri: qubesos\n flavor: install-iso-optiplex-legacy\n version: '4.2.3'\n qubesos-4.2.3-install-iso-optiplex-uefi-x86_64:\n distri: qubesos\n flavor: install-iso-optiplex-uefi\n version: '4.2.3'\n qubesos-4.2.3-install-iso-vp4670-legacy-x86_64:\n distri: qubesos\n flavor: install-iso-vp4670-legacy\n version: '4.2.3'\n qubesos-4.2.3-install-iso-vp4670-uefi-x86_64:\n distri: qubesos\n flavor: install-iso-vp4670-uefi\n version: '4.2.3'\n qubesos-4.2.3-install-iso-hpt630v1-legacy-x86_64:\n distri: qubesos\n flavor: install-iso-hpt630v1-legacy\n version: '4.2.3'\n qubesos-4.2.3-install-iso-hpt630v1-uefi-x86_64:\n distri: qubesos\n flavor: install-iso-hpt630v1-uefi\n version: '4.2.3'\n qubesos-4.2.3-install-iso-hpt630v2-legacy-x86_64:\n distri: qubesos\n flavor: install-iso-hpt630v2-legacy\n version: '4.2.3'\n qubesos-4.2.3-install-iso-hpt630v2-uefi-x86_64:\n distri: qubesos\n flavor: install-iso-hpt630v2-uefi\n version: '4.2.3'\nscenarios:\n x86_64:\n qubesos-4.2.3-install-iso-optiplex-legacy-x86_64:\n - installation:\n machine: optiplex\n - aem-setup:\n machine: optiplex\n - aem-first-run:\n machine: optiplex\n - aem-second-run:\n machine: optiplex\n qubesos-4.2.3-install-iso-optiplex-uefi-x86_64:\n - installation:\n machine: optiplex\n - aem-setup:\n machine: optiplex\n - aem-first-run:\n machine: optiplex\n - aem-second-run:\n machine: optiplex\n qubesos-4.2.3-install-iso-vp4670-legacy-x86_64:\n - installation:\n machine: vp4670\n - aem-setup:\n machine: vp4670\n - aem-first-run:\n machine: vp4670\n - aem-second-run:\n machine: vp4670\n qubesos-4.2.3-install-iso-vp4670-uefi-x86_64:\n - installation:\n machine: vp4670\n - aem-setup:\n machine: vp4670\n - aem-first-run:\n machine: vp4670\n - aem-second-run:\n machine: vp4670\n qubesos-4.2.3-install-iso-hpt630v1-legacy-x86_64:\n - installation:\n machine: hpt630v1\n - aem-setup:\n machine: hpt630v1\n - aem-first-run:\n machine: hpt630v1\n - aem-second-run:\n machine: hpt630v1\n qubesos-4.2.3-install-iso-hpt630v1-uefi-x86_64:\n - installation:\n machine: hpt630v1\n - aem-setup:\n machine: hpt630v1\n - aem-first-run:\n machine: hpt630v1\n - aem-second-run:\n machine: hpt630v1\n qubesos-4.2.3-install-iso-hpt630v2-legacy-x86_64:\n - installation:\n machine: hpt630v2\n - aem-setup:\n machine: hpt630v2\n - aem-first-run:\n machine: hpt630v2\n - aem-second-run:\n machine: hpt630v2\n qubesos-4.2.3-install-iso-hpt630v2-uefi-x86_64:\n - installation:\n machine: hpt630v2\n - aem-setup:\n machine: hpt630v2\n - aem-first-run:\n machine: hpt630v2\n - aem-second-run:\n machine: hpt630v2\n", "group_name": "Qubes" } ], diff --git a/needles/aem_hw-bootloader-20250404.json b/needles/aem_hw-bootloader-20250404.json new file mode 100644 index 00000000..cf1ebc06 --- /dev/null +++ b/needles/aem_hw-bootloader-20250404.json @@ -0,0 +1,15 @@ +{ + "area": [ + { + "xpos": 8, + "ypos": 62, + "width": 226, + "height": 34, + "type": "match" + } + ], + "properties": [], + "tags": [ + "bootloader" + ] +} \ No newline at end of file diff --git a/needles/aem_hw-bootloader-20250404.png b/needles/aem_hw-bootloader-20250404.png new file mode 100644 index 00000000..312d811e Binary files /dev/null and b/needles/aem_hw-bootloader-20250404.png differ diff --git a/needles/aem_hw-bootloader-20250423.json b/needles/aem_hw-bootloader-20250423.json new file mode 100644 index 00000000..72a4a93c --- /dev/null +++ b/needles/aem_hw-bootloader-20250423.json @@ -0,0 +1,15 @@ +{ + "area": [ + { + "xpos": 12, + "ypos": 148, + "width": 358, + "height": 67, + "type": "match" + } + ], + "properties": [], + "tags": [ + "bootloader" + ] +} \ No newline at end of file diff --git a/needles/aem_hw-bootloader-20250423.png b/needles/aem_hw-bootloader-20250423.png new file mode 100644 index 00000000..ab5306c8 Binary files /dev/null and b/needles/aem_hw-bootloader-20250423.png differ diff --git a/needles/aem_hw-bootloader_with_aem-20250404.json b/needles/aem_hw-bootloader_with_aem-20250404.json new file mode 100644 index 00000000..e9b82cd1 --- /dev/null +++ b/needles/aem_hw-bootloader_with_aem-20250404.json @@ -0,0 +1,15 @@ +{ + "area": [ + { + "xpos": 5, + "ypos": 50, + "width": 227, + "height": 79, + "type": "match" + } + ], + "properties": [], + "tags": [ + "bootloader" + ] +} \ No newline at end of file diff --git a/needles/aem_hw-bootloader_with_aem-20250404.png b/needles/aem_hw-bootloader_with_aem-20250404.png new file mode 100644 index 00000000..12ff63b6 Binary files /dev/null and b/needles/aem_hw-bootloader_with_aem-20250404.png differ diff --git a/needles/aem_hw-dasharo_tpm12_clear_enable_activate-20250408.json b/needles/aem_hw-dasharo_tpm12_clear_enable_activate-20250408.json new file mode 100644 index 00000000..035c6275 --- /dev/null +++ b/needles/aem_hw-dasharo_tpm12_clear_enable_activate-20250408.json @@ -0,0 +1,15 @@ +{ + "area": [ + { + "xpos": 211, + "ypos": 279, + "width": 429, + "height": 38, + "type": "match" + } + ], + "properties": [], + "tags": [ + "dasharo_tpm12_clear_enable_activate" + ] +} \ No newline at end of file diff --git a/needles/aem_hw-dasharo_tpm12_clear_enable_activate-20250408.png b/needles/aem_hw-dasharo_tpm12_clear_enable_activate-20250408.png new file mode 100644 index 00000000..c6c4e8ba Binary files /dev/null and b/needles/aem_hw-dasharo_tpm12_clear_enable_activate-20250408.png differ diff --git a/needles/aem_hw-dasharo_tpm2_confirm_clear-20250313.json b/needles/aem_hw-dasharo_tpm2_confirm_clear-20250313.json index 3ced1ab7..09c96188 100644 --- a/needles/aem_hw-dasharo_tpm2_confirm_clear-20250313.json +++ b/needles/aem_hw-dasharo_tpm2_confirm_clear-20250313.json @@ -1,10 +1,10 @@ { "area": [ { - "xpos": 188, - "ypos": 253, - "width": 426, - "height": 71, + "xpos": 192, + "ypos": 263, + "width": 207, + "height": 34, "type": "match" } ], @@ -12,4 +12,4 @@ "tags": [ "dasharo_tpm2_confirm_clear" ] -} \ No newline at end of file +} diff --git a/needles/aem_hw-dasharo_tpm2_confirm_clear-20250408.json b/needles/aem_hw-dasharo_tpm2_confirm_clear-20250408.json new file mode 100644 index 00000000..678c8d35 --- /dev/null +++ b/needles/aem_hw-dasharo_tpm2_confirm_clear-20250408.json @@ -0,0 +1,15 @@ +{ + "area": [ + { + "xpos": 193, + "ypos": 319, + "width": 383, + "height": 35, + "type": "match" + } + ], + "properties": [], + "tags": [ + "dasharo_tpm2_confirm_clear" + ] +} \ No newline at end of file diff --git a/needles/aem_hw-dasharo_tpm2_confirm_clear-20250408.png b/needles/aem_hw-dasharo_tpm2_confirm_clear-20250408.png new file mode 100644 index 00000000..d0d5758c Binary files /dev/null and b/needles/aem_hw-dasharo_tpm2_confirm_clear-20250408.png differ diff --git a/needles/install_startup-bootloader-installer-20250403.json b/needles/install_startup-bootloader-installer-20250403.json new file mode 100644 index 00000000..b25fce99 --- /dev/null +++ b/needles/install_startup-bootloader-installer-20250403.json @@ -0,0 +1,15 @@ +{ + "area": [ + { + "xpos": 7, + "ypos": 49, + "width": 146, + "height": 80, + "type": "match" + } + ], + "properties": [], + "tags": [ + "bootloader-installer" + ] +} \ No newline at end of file diff --git a/needles/install_startup-bootloader-installer-20250403.png b/needles/install_startup-bootloader-installer-20250403.png new file mode 100644 index 00000000..a92bb498 Binary files /dev/null and b/needles/install_startup-bootloader-installer-20250403.png differ diff --git a/needles/install_startup-bootloader-installer-20250409.json b/needles/install_startup-bootloader-installer-20250409.json new file mode 100644 index 00000000..856728b6 --- /dev/null +++ b/needles/install_startup-bootloader-installer-20250409.json @@ -0,0 +1,15 @@ +{ + "area": [ + { + "xpos": 14, + "ypos": 147, + "width": 303, + "height": 94, + "type": "match" + } + ], + "properties": [], + "tags": [ + "bootloader-installer" + ] +} \ No newline at end of file diff --git a/needles/install_startup-bootloader-installer-20250409.png b/needles/install_startup-bootloader-installer-20250409.png new file mode 100644 index 00000000..5ecba6f4 Binary files /dev/null and b/needles/install_startup-bootloader-installer-20250409.png differ diff --git a/tests/aem_hw.pm b/tests/aem_hw.pm index affb46b4..2130fcd4 100644 --- a/tests/aem_hw.pm +++ b/tests/aem_hw.pm @@ -60,7 +60,8 @@ if (check_var('MACHINE', 'optiplex') or check_var('MACHINE', 'vp4670')) { } my $bios_kind; -if (check_var('MACHINE', 'optiplex') and check_var('OS_INSTALL_LEGACY', '1')) { +if ((check_var('MACHINE', 'optiplex') and check_var('OS_INSTALL_LEGACY', '1')) or + (check_var('MACHINE', 'vp4670') and check_var('OS_INSTALL_LEGACY', '1'))) { $bios_kind = 'seabios'; } elsif (check_var('MACHINE', 'supermicro')) { $bios_kind = 'aptio'; @@ -160,46 +161,64 @@ sub run { sub check_event_log_completeness { my ($path) = @_; + my $soft_fails = 0; + + my sub soft_assert_script_run { + my ($script) = @_; + my $res = script_run($script); + if ($res) { + $soft_fails++; + record_info("Event log error", "Command '" . $script . "' failed"); + } + return $res; + } + # check if log has all expected entries if ($drtm_kind eq 'skinit') { - assert_script_run('grep "SKINIT" ' . $path); - assert_script_run('grep "DLME entry offset" ' . $path); - assert_script_run('grep "DLME$" ' . $path); + soft_assert_script_run('grep "SKINIT" ' . $path); + soft_assert_script_run('grep "DLME entry offset" ' . $path); + soft_assert_script_run('grep "DLME$" ' . $path); } elsif ($drtm_kind eq 'txt') { # TXT uses event types instead of names, there are many more than these, # but their number and order varies between families, check just the # most important, common ones - assert_script_run('grep "Event Type: 0x402" ' . $path); # HASH_START - assert_script_run('grep "Event Type: 0x404" ' . $path); # MLE_HASH - assert_script_run('grep "Event Type: 0x410" ' . $path); # SINIT_PUBKEY_HASH + soft_assert_script_run('grep "Event Type: 0x402" ' . $path); # HASH_START + soft_assert_script_run('grep "Event Type: 0x404" ' . $path); # MLE_HASH + soft_assert_script_run('grep "Event Type: 0x410" ' . $path); # SINIT_PUBKEY_HASH } else { die "Unhandled DRTM kind run(): '$drtm_kind'!"; } # SLRT, type 0x502 with no `Event` information - assert_script_run('grep "Event Type: 0x502" -A5 ' . $path . ' | grep "Event: $"'); + soft_assert_script_run('grep "Event Type: 0x502" -A5 ' . $path . ' | grep "Event: $"'); if ($drtm_kind eq 'txt') { - assert_script_run('grep "Measured TXT OS-MLE data" ' . $path); + soft_assert_script_run('grep "Measured TXT OS-MLE data" ' . $path); } if (check_var('OS_INSTALL_LEGACY', '0')) { - assert_script_run('grep "Xen\'s command line" ' . $path); - assert_script_run('grep "MB module string" ' . $path); + soft_assert_script_run('grep "Xen\'s command line" ' . $path); + soft_assert_script_run('grep "MB module string" ' . $path); } else { # on legacy, the above entries are part of MBI that has type 0x502 and # no `Event`, which makes it the second such entry after SLRT - assert_script_run('[ $(grep "Event Type: 0x502" -A5 ' . $path . + soft_assert_script_run('[ $(grep "Event Type: 0x502" -A5 ' . $path . ' | grep "Event: $" -c) -eq 2 ]'); } - assert_script_run('grep "MB module$" ' . $path); + soft_assert_script_run('grep "MB module$" ' . $path); # check if PCRs match my $pcrs_str = script_output('ls /sys/class/tpm/tpm0/pcr-sha*/1[78] -1'); my @pcrs = split ' ', $pcrs_str; for my $pcr (@pcrs) { - assert_script_run("grep -wi \$(cat $pcr) " . $path); + my $res = soft_assert_script_run("grep -wi \$(cat $pcr) " . $path); + if ($res and check_var('MACHINE', 'optiplex') and $pcr =~ qr/17$/) { + record_info("ACM bug", "Previous error may be caused by bug in Intel ACM"); + $soft_fails--; + } } + + die "Event log incomplete or malformed" if $soft_fails; } sub clear_tpm { @@ -222,18 +241,31 @@ sub clear_tpm_seabios { send_key 'esc'; # enter TPM menu - assert_serial 'Select boot device:'; + assert_serial 't. TPM Configuration'; send_key 't'; - my $owned = assert_serial qr/Ownership has( not)? been taken/, 5; - if (!defined $owned) { - die "Failed to check TPM ownership status in TPM menu of SeaBIOS."; - } elsif ($owned =~ 'Ownership has not been taken') { - # exit TPM menu + my $menu = wait_serial qr/reboot the machine./, 5; + + # SeaBIOS spews ANSI Cursor Position code every second, after repeating the + # previously printed character. It so happens that it is often inserted in + # 'Clear ownership' line, which breaks parsing. Remove that one repeated + # character and control sequence to reliably match the line. + $menu =~ s/.\e\[\d+;\d+H//g; + + if (!($menu =~ qr/Ownership has( not)? been taken/)) { + # TPM 2.0 + send_key '1'; + # poor UX, selecting the option loops back to menu with no feedback + send_key 'esc'; + } elsif ($menu =~ 'Ownership has not been taken') { + # TPM 1.2 with ownership not taken, exit TPM menu send_key 'esc'; } else { - # reset the TPM, to allow taking ownership - assert_serial 'c. Clear ownership'; + # TPM 1.2 with ownership taken, reset the TPM to allow taking ownership + if (!($menu =~ qr/c. Clear ownership/)) { + # Simulate assert_serial output + die "Failed to match serial output against regexp /c. Clear ownership/"; + } send_key 'c'; assert_serial 'e. Enable the TPM'; send_key 'e'; @@ -416,16 +448,14 @@ sub clear_tpm_dasharo { send_key 'down'; sleep 1; save_screenshot; - # Dasharo BUG: https://github.com/Dasharo/dasharo-issues/issues/1091 - send_key 'ret'; # returns directly back to device manager - sleep 1; + send_key 'ret'; + assert_screen 'dasharo_tpm12_clear_enable_activate'; } else { save_screenshot; send_key 'ret'; assert_screen 'dasharo_tpm2_clearcontrol'; - # TODO: move this outside of conditional after Dasharo BUG is fixed - send_key('esc', wait_screen_change => 1); # go back to device manager } + send_key('esc', wait_screen_change => 1); # go back to device manager # save, return to main menu and reboot send_key('f10', wait_screen_change => 1); @@ -434,13 +464,9 @@ sub clear_tpm_dasharo { send_key('pgdn', wait_screen_change => 1); send_key('ret', wait_screen_change => 1); - # TODO: TPM1.2 should take the same path after Dasharo BUG is fixed - # TPM2 only - last match changed for TPM2, but not TPM1.2, so it can be used - if (not match_has_tag('dasharo_tpm12_operation')) { - # confirm request to clear TPM - assert_screen 'dasharo_tpm2_confirm_clear'; - send_key('f12'); - } + # confirm request to clear TPM + assert_screen 'dasharo_tpm2_confirm_clear'; + send_key('f12'); } sub setup_acm { diff --git a/tests/install_startup.pm b/tests/install_startup.pm index 0bad2791..1252fc0f 100644 --- a/tests/install_startup.pm +++ b/tests/install_startup.pm @@ -85,8 +85,10 @@ sub run { } } elsif (check_var('HEADS', '1')) { heads_boot_usb; - } elsif (check_var('MACHINE', 'optiplex') and check_var('OS_INSTALL_LEGACY', '1')) { - ipxe_boot('dasharo'); + } elsif ((check_var('MACHINE', 'optiplex') and check_var('OS_INSTALL_LEGACY', '1')) or + (check_var('MACHINE', 'vp4670') and check_var('OS_INSTALL_LEGACY', '1'))) { + seabios_boot(); + #ipxe_boot('dasharo'); } elsif (check_var('MACHINE', 'vp4670') or check_var('MACHINE', 'optiplex')) { my $ks_url = prepare_kickstart_config(); my $params = "inst.sshd inst.ks=$ks_url"; @@ -112,7 +114,7 @@ sub run { send_key_until_needlematch('dasharo_pikvm_bootdev', 'down'); send_key 'ret'; - assert_screen 'bootloader'; + assert_screen 'bootloader-installer'; grub_boot_with_kernel_parameters($params); } elsif (check_var('MACHINE', 'supermicro')) { # FIXME: use per-worker URLs, don't pollute global ones @@ -271,7 +273,8 @@ sub run { select_console('installation', await_console=>0); } - if (check_var("MACHINE", "hw7") or check_var("MACHINE", "hw12")) { + if (check_var("MACHINE", "hw7") or check_var("MACHINE", "hw12") or + check_var("MACHINE", "optiplex") or check_var("MACHINE", "vp4670")) { select_root_console(); # RTC battery not connected script_run("date -s @" . time()); @@ -287,17 +290,53 @@ sub grub_boot_with_kernel_parameters { send_key 'up'; # start editing it send_key 'e'; + # menu redraws with serial output take too long, some key presses get lost + # consider building Dasharo without serial redirection after SeaBIOS + sleep 1; # go to the line with kernel parameters send_key 'down'; + sleep 1; send_key 'down'; + sleep 1; send_key 'down'; + sleep 1; send_key 'end'; - # append them - type_string " $parameters"; + sleep 1; + # append them, somewhat slowly + type_string(" $parameters", max_interval => 150); # boot send_key 'f10'; } +sub seabios_boot { + assert_serial qr/Press ESC for boot menu./, 30; + send_key 'esc'; + + my $menu = wait_serial qr/TPM Configuration/, 5; + # SeaBIOS prints ANSI escape code every second (RTC interrupt), log the + # output for easier debugging if it happens while the menu is being printed + diag("SeaBIOS boot menu:\n" . $menu); + $menu =~ /(.)\. USB MSC Drive/; + if (!defined($1)) { + die "No USB MSC Drive detected"; + } + + diag("Booting entry " . $1); + send_key $1; + + my $ks_url = prepare_kickstart_config(); + my $params = "inst.sshd inst.ks=$ks_url"; + + # VP4670 has multiple network controllers, only use the first one + if (check_var('MACHINE', 'vp4670')) { + my $device_ip = get_var('QUBES_OS_HOST_IP'); + $params .= " ip=${device_ip}::192.168.10.1:255.255.255.0::enp1s0 bootdev=enp1s0"; + } + + assert_screen 'bootloader-installer'; + grub_boot_with_kernel_parameters($params); +} + sub ipxe_boot { # Values: # * dasharo: