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