Bug 1218811 - autoyast pre-exec: sed substitution does not replace disk name in Partitioning section
Summary: autoyast pre-exec: sed substitution does not replace disk name in Partitionin...
Status: RESOLVED FIXED
Alias: None
Product: PUBLIC SUSE Linux Enterprise Server 15 SP5
Classification: openSUSE
Component: AutoYaST (show other bugs)
Version: unspecified
Hardware: x86-64 Other
: P5 - None : Normal
Target Milestone: ---
Assignee: E-mail List
QA Contact: AutoYaST Maintainers
URL:
Whiteboard:
Keywords:
Depends on:
Blocks:
 
Reported: 2024-01-15 12:54 UTC by Jaime Blasco
Modified: 2024-01-17 08:29 UTC (History)
1 user (show)

See Also:
Found By: ---
Services Priority:
Business Priority:
Blocker: ---
Marketing QA Status: ---
IT Deployment: ---


Attachments
autoinst.xml (52.96 KB, text/xml)
2024-01-15 12:54 UTC, Jaime Blasco
Details
y2logs (5.96 MB, application/octet-stream)
2024-01-15 13:25 UTC, Jaime Blasco
Details

Note You need to log in before you can comment on or make changes to this bug.
Description Jaime Blasco 2024-01-15 12:54:09 UTC
Created attachment 871876 [details]
autoinst.xml

Hello,

This is on SLES15 SP5 QU1. It seems there is a bug with the QU1 when algorithm selecting the ideal boot for the boot install. I did not have the issue with 15SP5 or 12SP5 

We have an 8-socket system (two chassis, each has a disk controller with one disk defined, both disks identical). The OS must be installed on the bottom chassis device. 
In the pre-exec section, I query the devices and find out the disk, either /dev/sda or /dev/sdb. This value is stored in $BOOT_DISK.

This value is then passed, using sed, to the partitioning section:

sed -i "s|^\([ \t]<device>\)__DISK__\(</device>\)|\1$BOOT_DISK\2|" /tmp/profile/modified.xml


The partitioning section shows:

<drive t="map">
      <device>__DISK__</device>

Unfortunately, this substitution is not working; basically, autoyast is ignoring the command during the installation. If I execute it manually on the same system, against the /tmp/profile/modified.xml, it does work. Later in the pre-exec section I'm using other sed commands for network configuration purposes. These are working.

Below I include the pre-exec section and the Partitioning one. If needed, I can attach the whole autoinst.xml.

<scripts>
    <pre-scripts config:type="list">
    <script>
      <filename>pre_exec.sh</filename>
      <notification>Executing pre_exec.sh...</notification>
      <interpreter>shell</interpreter>
      <source>
        <![CDATA[
          #!/bin/bash

          # Inital copy of /tmp/profile/autoinst.xml to /tmp/profile/modified.xml
          cp -p /tmp/profile/autoinst.xml /tmp/profile/modified.xml

          # Check if the product name is Compute Scale-up Server 3200
          system_product_name=$(dmidecode -s system-product-name)
          case "$system_product_name" in
                *"Compute Scale-up Server 3200"*)
                  echo "Suppoprted product name found: $system_product_name"  | tee -a /tmp/autoinst-pre-script.log
                  ;;
                *)
                  echo "Error: Unsupported product name found: $system_product_name"  | tee -a /tmp/autoinst-pre-script.log
                  result=1
                  exit 1
                  ;;
          esac
          
          # Select the LD on the controller in the base chassis.
          # Only controller SmartRAID Ultra 3258p-32i supported
          
          CONTROL_FILE=/tmp/profile/modified.xml
          NO_SOCKETS=$(lscpu | egrep Socket | awk '{print $2}')

          # If the system has 8 Sockets, its representation on lscpi output will include domain number
          # Need to adjust the regex in accordance with that
          if [[ $NO_SOCKETS -eq 4 ]]
          then
              SLOT_REGEX="0000:63:00.0" 
              
          elif [[ $NO_SOCKETS -eq 8 ]]
            then
              SLOT_REGEX="0000:63:00.0"
          fi
              
          BOOT_CTRL=$(lspci -v | egrep -A 1 "$SLOT_REGEX" | grep Adaptec |awk NR==2 | grep -oP '(?<=SmartRAID Ultra )[^ ]*')
          HOST_SCSI_CNL=$(lsscsi -v | egrep -i "$BOOT_CTRL" -A 1| egrep "$SLOT_REGEX" | grep -o -P '(?<=host).*(?=target)'| tr -d '/')
          BOOT_HOST_CTRL=$(cat /proc/scsi/scsi | grep -A2 "Host: scsi$HOST_SCSI_CNL"  | grep -i $BOOT_CTRL | awk '{print $4}')
          BOOT_HOST="scsi$HOST_SCSI_CNL"
          echo $BOOT_HOST | tee -a /tmp/autoinst-pre-script.log

          SA_DISK_NO=$(cat /proc/scsi/scsi | egrep -B1 "LOGICAL VOLUME" | grep "$BOOT_HOST" | grep "Lun: 00" | while read x1 dev x2 chan x3 id x4 lun; \
          do echo ${dev/scsi/}:${chan:1}:${id:1}:${lun:1}; done | while read device; \
          do ls -1 /sys/class/scsi_device/$device/device/block; done | tr '\n' '|' | sed 's/|$/\n/g'| wc -l)

          if [ $SA_DISK_NO="1" ]; then
            echo "One disk found; continue"  | tee -a /tmp/autoinst-pre-script.log
          else
            echo "`exit`"
          fi

          OS_INST_LUN=$(cat /proc/scsi/scsi | egrep -B1 "LOGICAL VOLUME" | grep ${BOOT_HOST} | grep "Lun: 00" | while read x1 dev x2 chan x3 id x4 lun; \
          do echo ${dev/scsi/}:${chan:1}:${id:1}:${lun:1}; done | while read device; \
          do ls -1 /sys/class/scsi_device/$device/device/block; done | tr '\n' '|' | sed 's/|$/\n/g')

          BOOT_DISK="/dev/$OS_INST_LUN"
          echo "Boot lun found $BOOT_DISK " | tee -a /tmp/autoinst-pre-script.log
          echo "Changing boot lun $BOOT_DISK in $CONTROL_FILE " | tee -a /tmp/autoinst-pre-script.log
                   
          sed -i "s|^\([ \t]<device>\)__DISK__\(</device>\)|\1$BOOT_DISK\2|" /tmp/profile/modified.xml

          # The Network information below is for the Miltpitas LAB, where depending on the chassis we need to assign
          # a different IP. For this purpose, we query for the Serial Number of the chassis.
          # If you want the network settings to be applied, replace IP, GW, ETH, DNS_1 as required to perform your
          # installation accordig to your LAB environment
                             
          IP_4s_bot=15.214.42.58
          IP_4s_top=15.214.42.188
          SN_bot=5UF2230700
          SN_top=5UF2230937
          IP_8s=15.214.42.58
          DNS_1=16.110.135.51
          GW=15.214.40.1
          ETH=eth1
          HOSTNAME_4S_bot=sd3200-4s-bot
          HOSTNAME_4S_top=sd3200-4s-top
          HOSTNAME_8S=sd3200-8s

          # cp /tmp/profile/autoinst.xml /tmp/profile/modified.xml
          NO_SOCKETS=$(lscpu | egrep Socket | awk '{print $2}')
          SN=`dmidecode -t baseboard | grep 'Serial Number:' |  awk '{print $3}'`
                    
          # In case of 4s, we check if bottom or top chassis
          echo "Starting with the network configuration..."  | tee -a /tmp/autoinst-pre-script.log
          if [[ $NO_SOCKETS -eq 4 ]]
          then
              echo "System is $NO_SOCKETS sockets configuration"  | tee -a /tmp/autoinst-pre-script.log
              echo " System with $SN found"  | tee -a /tmp/autoinst-pre-script.log
              #
              # Only setting Network parameters if SN is known.
              #
              if [[ $SN = $SN_bot ]]
              then
                  sed -i "s/\(<ipaddr>\)[^<>]*\(<\/ipaddr>\)/\1$IP_4s_bot\2/" $CONTROL_FILE
                  sed -i "s/\(<hostname>\)[^<>]*\(<\/hostname>\)/\1$HOSTNAME_4S_bot\2/" $CONTROL_FILE
                  sed -i "s/\(<gateway>\)[^<>]*\(<\/gateway>\)/\1$GW\2/" $CONTROL_FILE
                  sed -i "s/\(<nameserver>\)[^<>]*\(<\/nameserver>\)/\1$DNS_1\2/" $CONTROL_FILE
                  sed -i "/<ipaddr>.*<\/ipaddr>/{n;s/<name>.*<\/name>/<name>${ETH}<\/name>/}" $CONTROL_FILE
              elif [[ $SN = $SN_top ]]
                then
                    sed -i "s/\(<ipaddr>\)[^<>]*\(<\/ipaddr>\)/\1$IP_4s_top\2/" $CONTROL_FILE
                    sed -i "s/\(<hostname>\)[^<>]*\(<\/hostname>\)/\1$HOSTNAME_4S_top\2/" $CONTROL_FILE
                    sed -i "s/\(<gateway>\)[^<>]*\(<\/gateway>\)/\1$GW\2/" $CONTROL_FILE
                    sed -i "s/\(<nameserver>\)[^<>]*\(<\/nameserver>\)/\1$DNS_1\2/" $CONTROL_FILE
                    sed -i "/<ipaddr>.*<\/ipaddr>/{n;s/<name>.*<\/name>/<name>${ETH}<\/name>/}" $CONTROL_FILE
              else
                  echo "System is $NO_SOCKETS sockets configuration" | tee -a /tmp/autoinst-pre-script.log
                  echo "Serial Number not known. Network settings will not be applied" | tee -a /tmp/autoinst-pre-script.log
                  exit;
              fi 
          
          # query if 8-socket in the LAB
          #
          elif [[ $NO_SOCKETS -eq 8 ]] && ([[ $SN = $SN_bot ]] ||  [[ $SN = $SN_top ]])
          then
            echo "System is $NO_SOCKETS sockets configuration"  | tee -a /tmp/autoinst-pre-script.log
            sed -i "s/\(<ipaddr>\)[^<>]*\(<\/ipaddr>\)/\1$IP_8s\2/" $CONTROL_FILE
            sed -i "s/\(<hostname>\)[^<>]*\(<\/hostname>\)/\1$HOSTNAME_8S\2/" $CONTROL_FILE
            sed -i "s/\(<gateway>\)[^<>]*\(<\/gateway>\)/\1$GW\2/" $CONTROL_FILE
            sed -i "s/\(<nameserver>\)[^<>]*\(<\/nameserver>\)/\1$DNS_1\2/" $CONTROL_FILE
            sed -i "/<ipaddr>.*<\/ipaddr>/{n;s/<name>.*<\/name>/<name>${ETH}<\/name>/}" $CONTROL_FILE
          else
            echo "System is $NO_SOCKETS sockets configuration" | tee -a /tmp/autoinst-pre-script.log
            echo "Serial Number not known. Network settings will not be applied" | tee -a /tmp/autoinst-pre-script.log
            exit;
          fi
          cat /tmp/profile/modified.xml >> /tmp/autoinst-pre-script.log
          cp -p /tmp/profile/modified.xml /tmp/profile/autoinst.xml
        ]]>
      </source>
    </script>
  </pre-scripts>




  <partitioning t="list">
    <drive t="map">
      <disklabel>gpt</disklabel>
      <initialize config:type="boolean">true</initialize>
      <device>/dev/system</device>
      <enable_snapshots t="boolean">true</enable_snapshots>
      <partitions t="list">
        <partition t="map">
          <create t="boolean">true</create>
          <create_subvolumes t="boolean">true</create_subvolumes>
          <filesystem t="symbol">btrfs</filesystem>
          <format t="boolean">false</format>
          <lv_name>root</lv_name>
          <mount>/</mount>
          <mountby t="symbol">device</mountby>
          <pool t="boolean">false</pool>
          <quotas t="boolean">false</quotas>
          <resize t="boolean">false</resize>
          <size>272730423296</size>
          <stripes t="integer">1</stripes>
          <stripesize t="integer">0</stripesize>
          <subvolumes t="list">
            <subvolume t="map">
              <copy_on_write t="boolean">false</copy_on_write>
              <path>var</path>
            </subvolume>
            <subvolume t="map">
              <copy_on_write t="boolean">true</copy_on_write>
              <path>usr/local</path>
            </subvolume>
            <subvolume t="map">
              <copy_on_write t="boolean">true</copy_on_write>
              <path>tmp</path>
            </subvolume>
            <subvolume t="map">
              <copy_on_write t="boolean">true</copy_on_write>
              <path>srv</path>
            </subvolume>
            <subvolume t="map">
              <copy_on_write t="boolean">true</copy_on_write>
              <path>root</path>
            </subvolume>
            <subvolume t="map">
              <copy_on_write t="boolean">true</copy_on_write>
              <path>opt</path>
            </subvolume>
            <subvolume t="map">
              <copy_on_write t="boolean">true</copy_on_write>
              <path>home</path>
            </subvolume>
            <subvolume t="map">
              <copy_on_write t="boolean">true</copy_on_write>
              <path>boot/grub2/x86_64-efi</path>
            </subvolume>
            <subvolume t="map">
              <copy_on_write t="boolean">true</copy_on_write>
              <path>boot/grub2/i386-pc</path>
            </subvolume>
          </subvolumes>
          <subvolumes_prefix>@</subvolumes_prefix>
        </partition>
        <partition t="map">
          <create t="boolean">true</create>
          <filesystem t="symbol">swap</filesystem>
          <format t="boolean">false</format>
          <lv_name>swap</lv_name>
          <mount>swap</mount>
          <mountby t="symbol">device</mountby>
          <pool t="boolean">false</pool>
          <resize t="boolean">false</resize>
          <size>2147483648</size>
          <stripes t="integer">1</stripes>
          <stripesize t="integer">0</stripesize>
        </partition>
      </partitions>
      <pesize>4194304</pesize>
      <type t="symbol">CT_LVM</type>
    </drive>
    <drive t="map">
      <device>__DISK__</device>
      <!-- <device>ask</device> -->
      <skip_list config:type="list">
        <listentry>
          <!-- skip devices that use the usb-storage driver -->
          <skip_key>driver</skip_key>
          <skip_value>usb-storage</skip_value>
        </listentry>
        <listentry>
          <!-- skip devices that are smaller than 6251223384-->
          <skip_key>size_k</skip_key>
          <skip_value>7251223384</skip_value>
          <skip_if_less_than config:type="boolean">true</skip_if_less_than>
        </listentry>
      </skip_list>
      <partitions t="list">
        <partition t="map">
          <create t="boolean">true</create>
          <filesystem t="symbol">vfat</filesystem>
          <format t="boolean">true</format>
          <fstopt>utf8</fstopt>
          <mount>/boot/efi</mount>
          <mountby t="symbol">uuid</mountby>
          <partition_id t="integer">259</partition_id>
          <partition_nr t="integer">1</partition_nr>
          <resize t="boolean">false</resize>
          <size>524288000</size>
        </partition>
        <partition t="map">
          <create t="boolean">true</create>
          <format t="boolean">false</format>
          <lvm_group>system</lvm_group>
          <partition_id t="integer">142</partition_id>
          <partition_nr t="integer">2</partition_nr>
          <resize t="boolean">false</resize>
          <size>343597383680</size>
        </partition>
        <partition t="map">
          <create t="boolean">true</create>
          <format t="boolean">false</format>
          <partition_id t="integer">131</partition_id>
          <partition_nr t="integer">3</partition_nr>
          <resize t="boolean">false</resize>
          <size>max</size>
        </partition>
      </partitions>
      <type t="symbol">CT_DISK</type>
      <use>all</use>
    </drive>
   </partitioning>
Comment 1 Lukas Ocilka 2024-01-15 13:16:48 UTC
We need YaST logs for understanding the details of this issue. Please attach them into Bugzilla.

For more information, see https://en.opensuse.org/openSUSE:Report_a_YaST_bug or more generic https://en.opensuse.org/openSUSE:How_to_Write_a_Good_Bugreport
Comment 2 Jaime Blasco 2024-01-15 13:25:56 UTC
Created attachment 871877 [details]
y2logs
Comment 3 Stefan Hundhammer 2024-01-16 17:01:21 UTC
AFAICS your problem is a lot more trivial than you might think: That 'sed' line doesn't work at all. You are missing a '*' for repeated whitespace at the start of the line.

Original:

> sed -i "s|^\([ \t]<device>\)__DISK__\(</device>\)|\1$BOOT_DISK\2|" /tmp/profile/modified.xml


Should be:

> sed -i "s|^\([ \t]*<device>\)__DISK__\(</device>\)|\1$BOOT_DISK\2|" /tmp/profile/modified.xml


Because you want to match against the start of the line, then any number (!) of whitespace (blanks or tabs), then <device>.


I tried by extracting a little test script from the AutoYaST profile, and that didn't do anything:

> #!/bin/bash
> 
> PROFILE=ay.xml
> BOOT_DISK="/dev/OS_INST_LUN"
> echo "Boot lun found $BOOT_DISK " 
> echo "Changing boot lun $BOOT_DISK in $PROFILE" 
> 
> sed -e "s|^\([ \t]*<device>\)__DISK__\(</device>\)|\1$BOOT_DISK\2|" <$PROFILE >$PROFILE.new
> 
> diff -u $PROFILE $PROFILE.new


Then I tried on the command line with

> sed -n -e "s|^\([ \t]*<device>\)__DISK__\(</device>\)|\1$BOOT_DISK\2|p" ay.xml

Notice '-n' for "no output" and after the replacement expression 'p' for "print"; that way you see only the matching lines.


So please try with the changed regexp.
Comment 4 Stefan Hundhammer 2024-01-16 17:16:05 UTC
Also, you might consider restricting your 'sed' commands only to matching lines to begin with; that makes the regexp considerably simpler:

> sed -i "/^[ \t]*<device>.*<\/device>/s|__DISK__|$BOOT_DISK|p" ay.xml

Or even simpler:

> sed -i "/^[ \t]*<device>/s|__DISK__|$BOOT_DISK|p" ay.xml

The only downside is that your maching expression always has to use slashes, so if it contains one, you have to escape it with a backslash.

But if you simply use only the opening XML tag (which is almost certainly safe enough), that's a non-issue; and you don't have to take care to add the opening and closing tag again in the replacement expression:

  |\1$BOOT_DISK\2|

Just a thought. ;-)
Comment 5 Stefan Hundhammer 2024-01-16 17:17:53 UTC
Please let us know if changing your regexp solved the problem.
Comment 6 Stefan Hundhammer 2024-01-16 17:20:15 UTC
Oops: Without the trailing 'p', of course.


> sed -i "/^[ \t]*<device>.*<\/device>/s|__DISK__|$BOOT_DISK|" ay.xml
 
> sed -i "/^[ \t]*<device>/s|__DISK__|$BOOT_DISK|" ay.xml
Comment 7 Jaime Blasco 2024-01-17 08:24:23 UTC
how embarrassing!!! can't see the forest for the trees

believe it or not, at some point, there was a * in the sed command. :-)
I have just tried it on a system, just one lun available, and it worked...

What confuses me is that, this same expression worked on the installation console, executed manually. 

Anyway, thanks for your help, appreciate that. I'll give it a try on the larger system next week (not available now), but I do not expect any difference.

you can close the bug.

have a good day.
Comment 8 Stefan Hundhammer 2024-01-17 08:29:31 UTC
OK, good to hear. Nevermind the forest. ;-)