1#!/bin/sh 2set -o errexit 3 4# The first argument is the shell script that initializes the variables: 5# sourceDir 6# outputDir 7# tmpDir 8# addBuildCompatibilityLibDir 9# systemPackages - lists of the hpkg packages copied/updated 10# repositories - all repository files 11# downloadDir 12# The following are only for image types: 13# installDir 14# isImage 15# imagePath 16# imageSize 17# imageLabel 18# resolvePackageDependencies 19# updateAllPackages 20# updateOnly 21# dontClearImage 22# isVMwareImage 23# 24# addattr 25# copyattr 26# getPackageDependencies 27# package 28# rc 29# rmAttrs 30# unzip 31# The following are only for image types: 32# bfsShell 33# fsShellCommand 34# makebootable 35# resattr 36# vmdkimage 37# The following is only for cd types: 38# generate_attribute_stores 39# isCD 40# 41if [ $# -gt 0 ]; then 42 . $1 43 shift 44fi 45 46if [ ! $isCD ]; then 47 # If the haiku image path is a symlink resolve it now (makebootable needs the 48 # path of the actual device path under Linux). 49 normalizedImagePath='' 50 if readlink -f "$imagePath" > /dev/null 2>&1 ; then 51 normalizedImagePath=$(readlink -f "$imagePath") 52 elif realpath "$imagePath" > /dev/null 2>&1 ; then 53 normalizedImagePath=$(realpath "$imagePath") 54 elif greadlink -f "$imagePath" > /dev/null 2>&1 ; then 55 normalizedImagePath=$(greadlink -f "$imagePath") 56 fi 57 if [ -n "$normalizedImagePath" ]; then 58 imagePath="$normalizedImagePath" 59 fi 60fi 61 62# this adds the build library dir to LD_LIBRARY_PATH 63eval "$addBuildCompatibilityLibDir" 64 65# map the shell commands 66if [ $isCD ]; then 67 outputDir=$tmpDir/cdsource 68 69 sPrefix= 70 tPrefix="$outputDir/" 71 cd=cd 72 scd=: 73 cp="$copyattr -d" 74 copyAttrs="$copyattr" 75 ln=ln 76 mkdir=mkdir 77 rm=rm 78elif [ $isImage ]; then 79 # If FIFOs are used for the communication with the FS shell, prepare them. 80 if $fsShellCommand --uses-fifos; then 81 fifoBasePath=/tmp/build_haiku_image-$$-fifo 82 toFSShellFifo=${fifoBasePath}-to-shell 83 fromFSShellFifo=${fifoBasePath}-from-shell 84 85 rm -f $toFSShellFifo $fromFSShellFifo 86 mkfifo $toFSShellFifo $fromFSShellFifo 87 88 # Open the FIFOs such that they are ready for the fsShellCommand. This 89 # also makes sure that they remain open until this script exits. When we 90 # exit while the FS shell is still running and waiting for commands, 91 # closing of our file descriptors will break the FIFOs and the FS shell 92 # will exit, too. 93 # Note: A bit of trickery is needed since opening one end blocks until 94 # someone opens the other end. 95 sleep 3<$fromFSShellFifo 1 & 96 exec 6>$fromFSShellFifo 3<$fromFSShellFifo 97 sleep 5<$toFSShellFifo 1 & 98 exec 4>$toFSShellFifo 5<$toFSShellFifo 99 100 # Remove the FIFO files again -- we have the open FDs, so they can 101 # still be used and this makes sure they won't hang around any further. 102 rm -f $toFSShellFifo $fromFSShellFifo 103 104 # Remap the fsShellCommand and bfsShell such that they don't inherit the 105 # wrong FDs. For both fsShellCommand and bfsShell FD 3 is the input from 106 # the respectively other program, FD 4 is the output to it. 107 actualFSShellCommand="$fsShellCommand" 108 actualBFSShell="$bfsShell" 109 110 fsShellCommandWrapper() 111 { 112 $actualFSShellCommand 5>&- 6>&- "$@" 113 } 114 115 bfsShellWrapper() 116 { 117 $actualBFSShell 3>&5 4<&6 "$@" 118 } 119 120 fsShellCommand=fsShellCommandWrapper 121 bfsShell=bfsShellWrapper 122 fi 123 124 # set up the other commands 125 sPrefix=: 126 tPrefix=/myfs/ 127 cd="$fsShellCommand cd" 128 scd="$fsShellCommand cd" 129 cp="$fsShellCommand cp -f" 130 copyAttrs="$fsShellCommand cp -a" 131 ln="$fsShellCommand ln" 132 mkdir="$fsShellCommand mkdir" 133 rm="$fsShellCommand rm" 134 mkindex="$fsShellCommand mkindex" 135else 136 sPrefix= 137 # TODO: This should come from the environment. 138 tPrefix="$installDir/" 139 cd=cd 140 scd=: 141 cp="$copyattr -d" 142 copyAttrs="$copyattr" 143 ln=ln 144 mkdir=mkdir 145 rm=rm 146 mkindex=mkindex 147fi 148 149 150is_in_list() 151{ 152 local element 153 for element in $2; do 154 if [ "$1" = "$element" ]; then 155 return 0 156 fi 157 done 158 return 1 159} 160 161 162extractFile() 163{ 164 # extractFile <archive> <directory> <extractedSubDir> 165 archiveFile=$1 166 targetExtractedDir=$2 167 extractedSubDir=$3 168 169 extractDir=$tmpDir/extract 170 $rmAttrs -rf "$extractDir" 171 mkdir -p "$extractDir" 172 173 case "$archiveFile" in 174 *.zip) 175 echo "Extracting $archiveFile ..." 176 $unzip -q -d "$extractDir" "$archiveFile" 177 ;; 178 *.tgz|*.tar.gz) 179 echo "Extracting $archiveFile ..." 180 tar -C "$extractDir" -xf "$archiveFile" 181 ;; 182 *.hpkg) 183 echo "Extracting $archiveFile ..." 184 if [ -n "$extractedSubDir" ]; then 185 $package extract -C "$extractDir" "$archiveFile" \ 186 "$extractedSubDir" 187 else 188 $package extract -C "$extractDir" "$archiveFile" 189 fi 190 ;; 191 *) 192 echo "Unhandled archive extension in build_haiku_image" \ 193 "extractFile()" 194 exit 1 195 ;; 196 esac 197 198 if [ -f $extractDir/.OptionalPackageDescription ]; then 199 cat $extractDir/.OptionalPackageDescription >> $copyrightsFile 200 echo >> $copyrightsFile 201 rm $extractDir/.OptionalPackageDescription 202 fi 203 204 $cp -r "${sPrefix}$extractDir/$extractedSubDir/." \ 205 "${tPrefix}$targetExtractedDir" 206 207 $rmAttrs -rf "$extractDir" 208} 209 210 211downloadFile() 212{ 213 url=$1 214 path=$2 215 216 if [ ! -f "$path" ]; then 217 wget -O "$path" "$url" 218 fi 219} 220 221 222packageFileName() 223{ 224 $package info -f "%fileName%" "$1" 225} 226 227 228mkdir -p $tmpDir 229copyrightsFile=$tmpDir/copyrights 230$rmAttrs -f $copyrightsFile 231 232if [ $isCD ]; then 233 # setup output dir 234 $rmAttrs -rf "$outputDir" 235 mkdir -p "$outputDir" 236fi 237 238# create the image and mount it 239if [ $isImage ]; then 240 echo 241 242 imageOffsetFlags= 243 if [ $isVMwareImage ]; then 244 imageOffsetFlags="--start-offset 65536" 245 fi 246 247 if [ ! $updateOnly ]; then 248 echo "Creating image ..." 249 250 imageFlags="-i${imageSize}M" 251 if [ ! "$dontClearImage" ]; then 252 imageFlags="$imageFlags -c" 253 fi 254 255 if [ $isVMwareImage ]; then 256 $vmdkimage -h 64k $imageFlags "$imagePath" 257 else 258 $createImage $imageFlags "$imagePath" 259 fi 260 261 $bfsShell --initialize $imageOffsetFlags "$imagePath" \ 262 "$imageLabel" "block_size 2048" 263 $makebootable $imageOffsetFlags "$imagePath" 264 fi 265 266 $bfsShell -n $imageOffsetFlags "$imagePath" > /dev/null & 267 sleep 1 268 269 # Close FDs 5 and 6. Those represent the pipe ends that are used by the 270 # FS shell. Closing them in the shell process makes sure an unexpected death 271 # of the FS shell causes writing to/reading from the other ends to fail 272 # immediately. 273 exec 5>&- 6>&- 274 275 # bail out, if mounting fails 276 $cd . 277fi 278 279 280# Clean out the old packages directory, if updating all packages. 281if [ -n "$updateAllPackages" ]; then 282 echo "Removing old packages ..." 283 $rm -rf "${tPrefix}system/packages" 284 $mkdir -p "${tPrefix}system/packages" 285fi 286 287 288echo "Populating image ..." 289while [ $# -gt 0 ]; do 290 . $1 291 shift 292done 293 294 295# resolve package dependencies 296if [ -n "$resolvePackageDependencies" ]; then 297 echo "Resolving package dependencies ..." 298 299 packageUrls=`$getPackageDependencies $repositories -- $systemPackages` 300 for packageUrl in $packageUrls; do 301 packageFileName=`basename $packageUrl` 302 packageFilePath="$downloadDir/$packageFileName" 303 downloadFile $packageUrl "$packageFilePath" 304 $cp "${sPrefix}$packageFilePath" "${tPrefix}system/packages" 305 systemPackages="$systemPackages $packageFilePath" 306 done 307fi 308 309 310# install default settings for packages 311for packageFile in $systemPackages; do 312 if $package list -p $packageFile | egrep '^settings/' > /dev/null; then 313 extractFile $packageFile system/settings settings 314 fi 315done 316 317 318# add the concatenated copyrights as an attribute to AboutSystem 319# TODO: That might not be necessary, when all third-party software everything 320# is packaged. Though we might not package everything. 321 322# if [ ! $updateOnly ]; then 323# if [ -f $copyrightsFile ]; then 324# copyrightAttrs=$tmpDir/copyrightAttrs 325# $rmAttrs -f $copyrightAttrs 326# touch $copyrightAttrs 327# $addattr -f $copyrightsFile COPYRIGHTS $copyrightAttrs 328# $copyAttrs ${sPrefix}$copyrightAttrs ${tPrefix}system/apps/AboutSystem 329# fi 330# fi 331 332if [ $isCD ]; then 333 # generate the attribute stores 334 echo "Generating attribute stores ..." 335 $generate_attribute_stores "$tPrefix" 336 337 echo "Copying boot image ..." 338 $cp "$cdBootFloppy" "$outputDir" 339 340 if [ $(which mkisofs) ]; then 341 # build the iso image using mkisofs 342 echo "Building CD image (mkisofs)..." 343 mkisofs -uid 0 -gid 0 -b `basename $cdBootFloppy` -R -V "$cdLabel" -o "$cdImagePath" "$tPrefix" 344 elif [ $(which genisoimage) ]; then 345 # build the iso image using genisoimage 346 echo "Building CD image (genisoimage)..." 347 echo "WARNING: genisoimage fallback has known problems with long filenames!" 348 echo " Please install mkisofs before making production releases!" 349 genisoimage -r -iso-level 4 -b `basename $cdBootFloppy` -V "$cdLabel" -o "$cdImagePath" "$tPrefix" 350 else 351 echo "you need mkisofs (preferred) or genisoimage to create a CD image." 352 exit 1 353 fi 354 355 # cleanup output dir 356 $rmAttrs -rf "$outputDir" 357fi 358 359# unmount 360if [ $isImage ]; then 361 echo "Unmounting ..." 362 $fsShellCommand sync 363 $fsShellCommand quit 364fi 365