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, commonPackages - lists of the hpkg packages copied/updated 10# (in "system" and "common" respectively) 11# repositories - all repository files 12# downloadDir 13# The following are only for image types: 14# installDir 15# isImage 16# imagePath 17# imageSize 18# imageLabel 19# resolvePackageDependencies 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 150extractFile() 151{ 152 # extractFile <archive> <directory> <extractedSubDir> 153 archiveFile=$1 154 targetExtractedDir=$2 155 extractedSubDir=$3 156 157 extractDir=$tmpDir/extract 158 $rmAttrs -rf "$extractDir" 159 mkdir -p "$extractDir" 160 161 case "$archiveFile" in 162 *.zip) 163 echo "Extracting $archiveFile ..." 164 $unzip -q -d "$extractDir" "$archiveFile" 165 ;; 166 *.tgz|*.tar.gz) 167 echo "Extracting $archiveFile ..." 168 tar -C "$extractDir" -xf "$archiveFile" 169 ;; 170 *.hpkg) 171 echo "Extracting $archiveFile ..." 172 if [ -n "$extractedSubDir" ]; then 173 $package extract -C "$extractDir" "$archiveFile" \ 174 "$extractedSubDir" 175 else 176 $package extract -C "$extractDir" "$archiveFile" 177 fi 178 ;; 179 *) 180 echo "Unhandled archive extension in build_haiku_image" \ 181 "extractFile()" 182 exit 1 183 ;; 184 esac 185 186 if [ -f $extractDir/.OptionalPackageDescription ]; then 187 cat $extractDir/.OptionalPackageDescription >> $copyrightsFile 188 echo >> $copyrightsFile 189 rm $extractDir/.OptionalPackageDescription 190 fi 191 192 $cp -r "${sPrefix}$extractDir/$extractedSubDir/." \ 193 "${tPrefix}$targetExtractedDir" 194 195 $rmAttrs -rf "$extractDir" 196} 197 198 199downloadFile() 200{ 201 url=$1 202 path=$2 203 204 if [ ! -f "$path" ]; then 205 wget -O "$path" "$url" 206 fi 207} 208 209 210mkdir -p $tmpDir 211copyrightsFile=$tmpDir/copyrights 212$rmAttrs -f $copyrightsFile 213 214if [ $isCD ]; then 215 # setup output dir 216 $rmAttrs -rf "$outputDir" 217 mkdir -p "$outputDir" 218fi 219 220# create the image and mount it 221if [ $isImage ]; then 222 echo 223 224 imageOffsetFlags= 225 if [ $isVMwareImage ]; then 226 imageOffsetFlags="--start-offset 65536" 227 fi 228 229 if [ ! $updateOnly ]; then 230 echo "Creating image ..." 231 232 imageFlags="-i${imageSize}M" 233 if [ ! "$dontClearImage" ]; then 234 imageFlags="$imageFlags -c" 235 fi 236 237 if [ $isVMwareImage ]; then 238 $vmdkimage -h 64k $imageFlags "$imagePath" 239 else 240 $createImage $imageFlags "$imagePath" 241 fi 242 243 $bfsShell --initialize $imageOffsetFlags "$imagePath" \ 244 "$imageLabel" "block_size 2048" 245 $makebootable $imageOffsetFlags "$imagePath" 246 fi 247 248 $bfsShell -n $imageOffsetFlags "$imagePath" > /dev/null & 249 sleep 1 250 251 # Close FDs 5 and 6. Those represent the pipe ends that are used by the 252 # FS shell. Closing them in the shell process makes sure an unexpected death 253 # of the FS shell causes writing to/reading from the other ends to fail 254 # immediately. 255 exec 5>&- 6>&- 256 257 # bail out, if mounting fails 258 $cd . 259fi 260 261echo "Populating image ..." 262while [ $# -gt 0 ]; do 263 . $1 264 shift 265done 266 267 268# resolve package dependencies 269if [ -n "$resolvePackageDependencies" ]; then 270 echo "Resolving package dependencies ..." 271 272 # additional packages for system 273 packageUrls=`$getPackageDependencies $repositories -- $systemPackages` 274 for packageUrl in $packageUrls; do 275 packageFileName=`basename $packageUrl` 276 packageFilePath="$downloadDir/$packageFileName" 277 downloadFile $packageUrl "$packageFilePath" 278 $cp "${sPrefix}$packageFilePath" "${tPrefix}system/packages" 279 systemPackages="$systemPackages $packageFilePath" 280 done 281 282 # additional packages for common 283 packageUrls=`$getPackageDependencies $repositories -- $systemPackages \ 284 $commonPackages` 285 for packageUrl in $packageUrls; do 286 packageFileName=`basename $packageUrl` 287 packageFilePath="$downloadDir/$packageFileName" 288 downloadFile $packageUrl "$packageFilePath" 289 $cp "${sPrefix}$packageFilePath" "${tPrefix}common/packages" 290 commonPackages="$commonPackages $packageFilePath" 291 done 292fi 293 294 295# install default settings for packages 296for packageFile in $systemPackages $commonPackages; do 297 if $package list -p $packageFile | egrep '^settings/' > /dev/null; then 298 extractFile $packageFile common/settings settings 299 fi 300done 301 302 303# add the concatenated copyrights as an attribute to AboutSystem 304# TODO: That might not be necessary, when all third-party software everything 305# is packaged. Though we might not package everything. 306 307# if [ ! $updateOnly ]; then 308# if [ -f $copyrightsFile ]; then 309# copyrightAttrs=$tmpDir/copyrightAttrs 310# $rmAttrs -f $copyrightAttrs 311# touch $copyrightAttrs 312# $addattr -f $copyrightsFile COPYRIGHTS $copyrightAttrs 313# $copyAttrs ${sPrefix}$copyrightAttrs ${tPrefix}system/apps/AboutSystem 314# fi 315# fi 316 317if [ $isCD ]; then 318 # generate the attribute stores 319 echo "Generating attribute stores ..." 320 $generate_attribute_stores "$tPrefix" 321 322 echo "Copying boot image ..." 323 $cp "$cdBootFloppy" "$outputDir" 324 325 if [ $(which mkisofs) ]; then 326 # build the iso image using mkisofs 327 echo "Building CD image (mkisofs)..." 328 mkisofs -uid 0 -gid 0 -b `basename $cdBootFloppy` -R -V "$cdLabel" -o "$cdImagePath" "$tPrefix" 329 elif [ $(which genisoimage) ]; then 330 # build the iso image using genisoimage 331 echo "Building CD image (genisoimage)..." 332 echo "WARNING: genisoimage fallback has known problems with long filenames!" 333 echo " Please install mkisofs before making production releases!" 334 genisoimage -r -iso-level 4 -b `basename $cdBootFloppy` -V "$cdLabel" -o "$cdImagePath" "$tPrefix" 335 else 336 echo "you need mkisofs (preferred) or genisoimage to create a CD image." 337 exit 1 338 fi 339 340 # cleanup output dir 341 $rmAttrs -rf "$outputDir" 342fi 343 344# unmount 345if [ $isImage ]; then 346 echo "Unmounting ..." 347 $fsShellCommand sync 348 $fsShellCommand quit 349fi 350