libreboot

my branch of libreboot
git clone git://git.hazbo.co.uk/libreboot.git
Log | Files | Refs | README

cros-kernel-install (6231B)


      1 #!/usr/bin/env bash
      2 
      3 # Copyright (C) 2016 Paul Kocialkowski <contact@paulk.fr>
      4 #
      5 # This program is free software: you can redistribute it and/or modify
      6 # it under the terms of the GNU General Public License as published by
      7 # the Free Software Foundation, either version 3 of the License, or
      8 # (at your option) any later version.
      9 #
     10 # This program is distributed in the hope that it will be useful,
     11 # but WITHOUT ANY WARRANTY; without even the implied warranty of
     12 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     13 # GNU General Public License for more details.
     14 #
     15 # You should have received a copy of the GNU General Public License
     16 # along with this program.  If not, see <http://www.gnu.org/licenses/>.
     17 
     18 SYS_BLOCK_PATH="/sys/class/block"
     19 DEV_PATH="/dev"
     20 DEVICE="device"
     21 VENDOR="vendor"
     22 MODEL="model"
     23 NAME="name"
     24 
     25 usage() {
     26 	printf 1>&2 '%s\n' "$executable [action] [storage] [kernel image|kernel modules]"
     27 
     28 	printf 1>&2 '\n%s\n' 'Actions:'
     29 	printf 1>&2 '%s\n' '  backup - Backup kernel image'
     30 	printf 1>&2 '%s\n' '  image - Install kernel image'
     31 	printf 1>&2 '%s\n' '  modules - Install kernel modules'
     32 
     33 	usage_storage
     34 
     35 	printf 1>&2 '\n%s\n' 'Environment variables:'
     36 	printf 1>&2 '%s\n' '  VBOOT_KEYS_PATH - Path to the vboot keys'
     37 	printf 1>&2 '%s\n' '  VBOOT_TOOLS_PATH - Path to vboot tools'
     38 }
     39 
     40 usage_storage() {
     41 	printf 1>&2 '\n%s\n' 'Storage:'
     42 
     43 	local nodes=$( ls "$SYS_BLOCK_PATH" )
     44 	local node_path
     45 	local name
     46 
     47 	for node in $nodes
     48 	do
     49 		node_path="$DEV_PATH/$node"
     50 		if ! [ -b "$node_path" ]
     51 		then
     52 			continue
     53 		fi
     54 
     55 		name=$( storage_name "$node_path" )
     56 		if [ -z "$name" ]
     57 		then
     58 			continue
     59 		fi
     60 
     61 		printf 1>&2 '%s\n' "  $node_path - $name"
     62 	done
     63 }
     64 
     65 storage_affect_confirm() {
     66 	local storage_path=$1
     67 
     68 	local name=$( storage_name "$storage_path" )
     69 	local confirm
     70 
     71 	printf '%s\n' 'This is going to affect the following storage:'
     72 	printf '%s\n' "  $storage_path - $name"
     73 	printf '%s' 'Press enter to confirm: '
     74 
     75 	read confirm
     76 }
     77 
     78 storage_name() {
     79 	local storage_path=$1
     80 
     81 	local node=$( basename "$storage_path" )
     82 	local vendor_path="$SYS_BLOCK_PATH/$node/$DEVICE/$VENDOR"
     83 	local model_path="$SYS_BLOCK_PATH/$node/$DEVICE/$MODEL"
     84 	local name_path="$SYS_BLOCK_PATH/$node/$DEVICE/$NAME"
     85 	local vendor
     86 	local name
     87 
     88 	if [ -f "$model_path" ]
     89 	then
     90 		name=$( cat "$model_path" )
     91 	elif [ -f "$name_path" ]
     92 	then
     93 		name=$( cat "$name_path" )
     94 	else
     95 		return 0
     96 	fi
     97 
     98 	name=$( printf '%s\n' "$name" | sed -e "s/^[[:space:]]*//;s/[[:space:]]*$//" )
     99 
    100 	if [ -f "$vendor_path" ]
    101 	then
    102 		vendor=$( cat "$vendor_path" )
    103 		vendor=$( printf '%s\n' "$vendor" | sed -e "s/^[[:space:]]*//;s/[[:space:]]*$//" )
    104 
    105 		name="$vendor $name"
    106 	fi
    107 
    108 	printf '%s\n' "$name"
    109 }
    110 
    111 storage_partition_path() {
    112 	local storage_path=$1
    113 	local index=$2
    114 
    115 	storage_partition_path="$storage_path$index"
    116 
    117 	if ! [ -b "$storage_partition_path" ]
    118 	then
    119 		storage_partition_path="$storage_path""p$index"
    120 	fi
    121 
    122 	if ! [ -b "$storage_partition_path" ]
    123 	then
    124 		return 1
    125 	fi
    126 
    127 	printf '%s\n' "$storage_partition_path"
    128 }
    129 
    130 storage_partition_mount_path() {
    131 	local storage_partition_path=$1
    132 
    133 	local storage_partition_mount_path=$( udisksctl info -b "$storage_partition_path"  | grep "MountPoints" | sed "s/.*MountPoints:[[:space:]]*\(.*\)/\1/g" )
    134 
    135 	printf '%s\n' "$storage_partition_mount_path"
    136 }
    137 
    138 storage_kernel_path() {
    139 	local storage_path=$1
    140 
    141 	cgpt find -t kernel "$storage_path" | head -n 1
    142 }
    143 
    144 storage_rootfs_path() {
    145 	local storage_path=$1
    146 
    147 	cgpt find -t rootfs "$storage_path" | head -n 1
    148 }
    149 
    150 backup() {
    151 	local storage_path=$1
    152 	local kernel_image_path=$2
    153 
    154 	local storage_kernel_path=$( storage_kernel_path "$storage_path" )
    155 
    156 	if [ -z "$storage_kernel_path" ]
    157 	then
    158 		printf 1>&2 '%s\n' "No kernel partition found on storage $storage_path"
    159 		return 1
    160 	fi
    161 
    162 	cat "$storage_kernel_path" > "$kernel_image_path"
    163 
    164 	printf '\n%s\n' "Backed up kernel image to $kernel_image_path"
    165 }
    166 
    167 image() {
    168 	local storage_path=$1
    169 	local kernel_image_path=$2
    170 
    171 	local storage_kernel_path=$( storage_kernel_path "$storage_path" )
    172 
    173 	if [ -z "$storage_kernel_path" ]
    174 	then
    175 		printf 1>&2 '%s\n' "No kernel partition found on storage $storage_path"
    176 		return 1
    177 	fi
    178 
    179 	storage_affect_confirm "$storage_path"
    180 
    181 	cat "$kernel_image_path" > "$storage_kernel_path"
    182 	sync
    183 
    184 	printf '\n%s\n' "Installed kernel image on storage $storage_path"
    185 }
    186 
    187 modules() {
    188 	local storage_path=$1
    189 	local kernel_modules_path=$2
    190 
    191 	local storage_rootfs_path=$( storage_rootfs_path "$storage_path" )
    192 
    193 	if [ -z "$storage_rootfs_path" ]
    194 	then
    195 		printf 1>&2 '%s\n' "No rootfs partition found on storage $storage_path"
    196 		return 1
    197 	fi
    198 
    199 	storage_affect_confirm "$storage_path"
    200 
    201 	# Partition may already be mounted.
    202 	udisksctl mount -b "$storage_rootfs_path" || true
    203 
    204 	storage_rootfs_mount_path=$( storage_partition_mount_path "$storage_rootfs_path" )
    205 
    206 	rsync -a --keep-dirlinks "$kernel_modules_path" "$storage_rootfs_mount_path/"
    207 	sync
    208 
    209 	udisksctl unmount -b "$storage_rootfs_path"
    210 
    211 	printf '\n%s\n' "Installed kernel modules on storage $storage_path"
    212 }
    213 
    214 requirements() {
    215 	local requirement
    216 	local requirement_path
    217 
    218 	for requirement in "$@"
    219 	do
    220 		requirement_path=$( which "$requirement" || true )
    221 
    222 		if [ -z "$requirement_path" ]
    223 		then
    224 			printf 1>&2 '%s\n' "Missing requirement: $requirement"
    225 			exit 1
    226 		fi
    227 	done
    228 }
    229 
    230 setup() {
    231 	root=$(readlink -f "$( dirname "$0" )" )
    232 	executable=$( basename "$0" )
    233 
    234 	if ! [ -z "$VBOOT_TOOLS_PATH" ]
    235 	then
    236 		PATH="$PATH:$VBOOT_TOOLS_PATH"
    237 	fi
    238 
    239 	if [ -z "$VBOOT_KEYS_PATH" ]
    240 	then
    241 		if ! [ -z "$VBOOT_TOOLS_PATH" ] && [ -d "$VBOOT_TOOLS_PATH/devkeys" ]
    242 		then
    243 			VBOOT_KEYS_PATH="$VBOOT_TOOLS_PATH/devkeys"
    244 		else
    245 			VBOOT_KEYS_PATH="/usr/share/vboot/devkeys"
    246 		fi
    247 	fi
    248 }
    249 
    250 cros_kernel_install() {
    251 	local action=$1
    252 	local storage_path=$2
    253 	local kernel_image_path=$3
    254 	local kernel_modules_path=$3
    255 
    256 	set -e
    257 
    258 	setup "$@"
    259 
    260 	if [ -z "$action" ] || [ -z "$storage_path" ] || [ -z "$kernel_image_path" ] || [ -z "$kernel_modules_path" ]
    261 	then
    262 		usage
    263 		exit 1
    264 	fi
    265 
    266 	case $action in
    267 		"backup")
    268 			requirements "cgpt"
    269 			backup "$storage_path" "$kernel_image_path"
    270 			;;
    271 		"image")
    272 			requirements "cgpt"
    273 			image "$storage_path" "$kernel_image_path"
    274 			;;
    275 		"modules")
    276 			requirements "cgpt"
    277 			modules "$storage_path" "$kernel_modules_path"
    278 			;;
    279 		*)
    280 			usage
    281 			exit 1
    282 			;;
    283 	esac
    284 }
    285 
    286 cros_kernel_install "$@"