[arch-releng] Automagic Profiles Loader

Jud jud at judfilm.net
Sun Apr 5 21:44:31 EDT 2009


On Sun, 5 Apr 2009 16:54:00 +0200
Dieter Plaetinck <dieter at plaetinck.be> wrote:

> On Mon, 6 Apr 2009 00:22:11 +1000
> Jud <jud at judfilm.net> wrote:
> 
> > This code is to be automatically run from a custom Arch Boot Media,
> > it will call aif with the best matching profile.
> > 
> > Comments and suggestions welcome.
> > 
> > #!/bin/bash
> > # Proof of Concept - Automagic Profiles Loader
> > #
> > # BASIC HARDWARE DETECT
> > #
> > 
> > # MAC address - output each device on separate line?; array?
> > mac=$(ifconfig -a | awk '/HWaddr/ {print $NF, $1}')
> > #echo $mac
> > 
> > # System Architecture - i686/x86_64
> > # could use CARCH?
> > arch=$(uname -m)
> > #echo $arch
> > 
> > # CPU Brand, Model Name, Processors, Sockets, GHz, Family, Model,
> > Stepping, Flags cpu=$(cat /proc/cpuinfo | awk '/^vendor_id/ {print
> > $NF; exit}')
> > #cpu=$(uname -i)
> > cpu2=$(cat /proc/cpuinfo | grep "model name" | awk '{ for (i=4;
> > i<=NF; i++) printf("%s ", $i); exit }')
> > #cpu2=$(uname -p)
> > cpu3=$(cat /proc/cpuinfo | grep -c processor)
> > cpu3a=$(cat /proc/cpuinfo | grep "cpu cores" | awk '/^cpu/ {print
> > $NF; exit}')
> > cpu4=$(cat /proc/cpuinfo | grep -c physical) # need a better
> > way; total sockets, ht?
> > cpu5=$(cat /proc/cpuinfo | grep MHz | awk '/^cpu/ {printf
> > ("%4.1f",$NF/1000); exit}')
> > cpu5=${cpu5}GHz
> > cpu6=$(cat /proc/cpuinfo | awk '/family/ {print $NF; exit}')
> > cpu7=$(cat /proc/cpuinfo | awk '/^model/ {print $NF; exit}')
> > cpu8=$(cat /proc/cpuinfo | awk '/^stepping/ {print $NF; exit}')
> > cpu9=$(cat /proc/cpuinfo | grep flags | awk ' { for (i=3; i<=NF;
> > i++) printf("%s ", $i);exit }')
> > #echo $cpu $cpu2 $cpu3 $cpu3a $cpu4 $cpu5 $cpu6 $cpu6a $cpu7 $cpu8
> > #echo $cpu9
> > 
> > # Mainboard Model Number, Chipset - need a much better way
> > mb=$(dmesg | grep RSDT | awk '/^ACPI/ {print $6, $7}')
> > #mb2=$(dmesg | grep RSDT)
> > mb2=$(lspci | grep "Host Bridge")
> > #echo $mb
> > #echo $mb2
> > 
> > # Total RAM - GB
> > mem=$(cat /proc/meminfo | awk '/^MemTotal/ {printf
> > ("%5.1f",$2/1048576)}') mem=${mem/.0/}GB
> > #echo $mem
> > 
> > # Hard Disk Capacity - GB
> > #hdd=$(fdisk -l | grep /dev/sda | awk '/^Disk/
> > {printf("%5.0f",$5/1000000000)}')
> > hdd=$(cat /proc/partitions | grep sda | awk '/sda/
> > {printf("%5.0f",$3/1000000); exit}')
> > if [[ ${hdd:2:1} =~[1-9] && ${#hdd} -ge 3 ]]; then
> > hdd2=$((${hdd:0:1}+1))$(echo "${hdd//[1-9]/0}" | sed 's/^.\{1\}//g')
> > else
> >  hdd2=$hdd
> > fi
> > hdd2=${hdd2}HD
> > #echo $hdd $hdd2
> > 
> > # Video Card Vendor - Others?
> > vga=$(lspci | grep VGA | tr "[:lower:]" "[:upper:]")
> > for i in ATI NVIDIA INTEL; do
> >   if [[ $vga == *${i}* ]]; then
> >     vga=$i
> >   fi
> > done
> > vga=VGA:$vga
> > #echo $vga
> > 
> > # VirtualMachine - Am I inside the Matrix?
> > for i in VBOX VMWARE XEN KVM; do
> >   vm=$(dmesg | grep -i -o ${i})
> >   if [[ $vm == *${i}* ]]; then
> >     vm=${i}; exit 0
> >   fi
> > done
> 
> is there anything wrong with running in a vm? what's your goal here?
> preventing your script to work when it's run in a vm?

No, nothing at all. My idea was to "know" as much about the system and
provide "hooks" for future use.

Another idea was to detect the current installed OS on the HDD and
provide hooks for the possibility of an automated install to create a
Dual/Multi Boot system.

> > testline="$mac $arch $cpu $cpu2 $cpu3 $cpu4 $cpu5 $cpu6 $cpu7 $cpu8
> > $cpu9 $mem $hdd2 $vga $vm"
> > #echo $testline
> > 
> > 
> > #
> > # PROFILE SELECTOR
> > #
> > 
> > #[ -r profiles ]
> > cat profiles | while read line; do
> >   # Skip Comments and Empty Lines
> >   [[ ${line:0:1} == "#" ]] && continue
> >   [[ -z "$line" ]] && continue
> > 
> >   # Profile Filename
> >   if [[ ${line:0:1} == "[" ]] ; then
> >     answer=$(echo ${line//[/} | cut -d] -f1-1); continue
> "$answer?" a name like "$profile" might make more sense here.
> 
> >   else
> >     # Profile Parameters
> >     line=$(echo "$line" | cut -d \# -f1-1 | sed 's/[ \t]*$//')
> >     result=""
> >     # Match Engine
> >     for each_name in $line; do
> >       if [[ $testline == *$each_name* ]]; then
> >         result=$(echo $result $each_name)
> >       fi
> >     done
> >     # Complete Match?
> >     if [[ $result == $line ]]; then
> >       echo "Loading Profile..."
> >       echo "aif -p automatic -c $answer"
> maybe you could actually call aif.  but hey that's just an idea :)
> Also I would not exit 0, but rather use the same exitcode as aif
> itself. can be useful.

The "success" part of the script was just to show it selected the
correct profile. My idea here is to have it run aif then send an email
report and automatically reboot. 

> >       exit 0
> >     fi
> >  fi
> > done
> > 
> > # End of File
> 
> I checked your sample config and it looks nice imho.
> So it's all blocks of [profilename] with "matching rules" below it
> right? 

Each line is a rule and it relates to a certain hardware configuration.
Each rule can be as many of the tests to try and uniquely identify the
system. The rule must match completely for the profile to be selected.
There can be multiple rules per profile. At the moment the matching
logic will only select the first complete rule, so generic type
profiles should be at the bottom of the file.

Filenames: This is still very much in the air, atm I have "profiles" and
not sure which directory it should live in. Any ideas, comments would be
appreciated. For each profiles filename what would be better $profile,
$profile.profile, $profile.aif, $profile.apl?

> I'm asking because I remember you said you wanted to be able to reboot
> automatically if aif exited successfully.  So I was thinking you could
> put such parameters like reboot_on_success in there.  (below the
> matching rules, on a per-profile basis). to make your code able to
> recognize what is a matching rule and what's an option you could maybe
> do like this (just an idea):
> [profilename]
> match matching rule 1
> match matching rule 2
> option variable value

I'd rather not have any options in the profiles file but never say
never.
 
> Also i would avoid caps as much as possible, it always make it
> easier in code if you can know you never need to convert between upper
> and lowercase.

Thanks, this stage of the development is like "throwing mud at the
wall". After trying to make it more robust and the obvious cleanups, I
need to work out how to make this autoload after grub and still have the
default options on the default boot media.

> PS: APL seems like a good name to me

Thanks.
 
> Dieter


More information about the arch-releng mailing list