summaryrefslogblamecommitdiff
path: root/adelie-build-cd
blob: f7d97a064ac1eb406ea422c26f5c4d80d106bf13 (plain) (tree)
1
2
3
4
5
6
7
8
            
 
      
                    
                 
                                

 


                             


























                                           
                                                   

                                                                                    
                

      
                                                     

                                                                               
                

      
                                                          

                                                                                             
                

      
                                                       

                                                     



                                                                                                 
                




         
                                                                                                                    
                                                                                        
                                         
                                           


                                                         

                     

                    
                               





                    
                                 


                    
                               


                     
                                

                    
                             


                       
                              
              






                                

                     
                    
              



         


                                                                      
      






                                                                         
                                      















                                                                                        
                     











                                                         


                                                                                                                
 




                                                                              


                                                
                          
                                                  

                                                
                                                                                       



                                           

                                                                       

                                            


                                                                  
 
                                                          

                                                                 





                                                                               

                                                                      


                                                                   
 



                                                                                                



                                                                            
                                                                 


                                                                       
 




                                                                                                      


                                                                         

                                                                                            

                                                          
                                                  
 
                                                                                               
 
                                                         


                                          


                                                           

                                                                                     
             

                                                                 








                                                                              
                                          

                                                                                       
                                                          


                                                        
                                                                     
                                      
                                 
                                  
                                                          


                                                                                                          
                                                                      


                                                                                                                    









                                                                             
                                                                         







                                             



                                                       














                                                    
                                                                      









                                                               
                                                              
                                                              
                                                           





                                         


                                                                               


                  
                                           
                                                                 





                                                
          


                                 
                                                                   


              
                             

                                   
                                                                  


                                                        

                                                                                                                                                                            

 











                              










                              







                              




                                                          
#!/bin/sh -e

set -e
def_arch=$(uname -m)
def_ver="1.0-rc1"
readonly PROGNAME=$(basename $0)


[ -z $ZSH_VERSION ] || set -y


warn() {
    printf '>>> '
    printf '\033[01;33mWARNING\033[00;39m '
    printf '>>> '
    printf '\033[01;33mWARNING\033[00;39m '
    printf '>>> '
    printf '\033[01;33mWARNING\033[00;39m '
    printf '>>> '
    printf '\033[01;33mWARNING\033[00;39m '
    printf '>>>\n'
}


fatal() {
    printf '>>> '
    printf '\033[01;31mERROR\033[00;39m '
    printf '>>> '
    printf '\033[01;31mERROR\033[00;39m '
    printf '>>> '
    printf '\033[01;31mERROR\033[00;39m '
    printf '>>> '
    printf '\033[01;31mERROR\033[00;39m '
    printf '>>>\n'
}


ensure_commands() {
    if ! command -v apk>/dev/null 2>/dev/null; then
	fatal
	printf 'You must have apk installed.  On Gentoo, see sys-devel/apk-tools.\n'
	exit 127
    fi

    if ! command -pv cpio>/dev/null 2>/dev/null; then
	fatal
	printf 'You must have cpio installed.  On Gentoo, see app-arch/cpio.\n'
	exit 127
    fi

    if ! command -v mksquashfs>/dev/null 2>/dev/null; then
	fatal
	printf 'You must have mksquashfs installed.  On Gentoo, see sys-fs/squashfs-tools.\n'
	exit 127
    fi

    if ! command -v xorriso>/dev/null 2>/dev/null; then
	fatal
	printf 'You must have xorriso installed:\n\n'
	printf '* cdrkit (Alpine, Gentoo) will not generate a usable PPC ISO.\n'
	printf '* wodim (Debian) will not generate a usable PPC64 ISO.\n'
	printf '* cdrtools (Schily) will overrun the PPC64 ISO and write junk to grubcore.img.\n'
	printf '\nSorry, but xorriso really is required.\n'
	exit 127
    fi
}


usage() {
    printf 'usage: %s [-a ARCH] [-f|--full] [-k|--kind KIND] [-p|--phase PHASE] [-v VERSION] [--help]\n\n' $PROGNAME
    printf 'Create an Adélie Linux CD image (.ISO) using the specified parameters.\n\n'
    printf 'Default ARCH: %s\n' $def_arch
    printf 'Default VERSION: %s\n' $def_ver
    printf 'Valid phases: clean install initrd iso all\n'
}

while [ -n "$1" ]; do
    case $1 in
	-a | --arch)
	    shift
	    readonly MY_ARCH=$1
	    ;;
	-h | --help)
	    usage
	    exit
	    ;;
	-f | --full)
	    readonly DO_FULL=full
	    ;;
	-k | --kind)
	    shift
	    readonly MY_KIND=$1
	    ;;
	-p | --phase)
	    shift
	    readonly MY_PHASE=$1
	    ;;
	-s | --sign)
	    readonly SIGN=yes
	    ;;
	-v | --version)
	    shift
	    readonly MY_VER=$1
	    ;;
	-c | --cache)
	    shift
	    readonly MY_CACHE=$1
	    ;;
	--no-cache)
	    unset def_cache
	    ;;
	*)
	    usage >&2
	    exit 127
	    ;;
    esac
    shift
done

[ -d /etc/apk/cache ] && def_cache=/etc/apk/cache
[ -z "${MY_ARCH}" -o "${MY_ARCH}" = "${def_arch}" ] || unset def_cache

set -a
readonly ARCH=${MY_ARCH:-$def_arch}
readonly KIND=${MY_KIND:-live}
readonly LDARCH=${LDARCH:-$ARCH}
readonly PHASE=${MY_PHASE:-all}
readonly VERSION=${MY_VER:-$def_ver}
readonly APKVER=${MY_APKVER:-$VERSION}
readonly URL=${MY_URL:-https://distfiles.adelielinux.org/adelie/$APKVER/}
readonly CACHE=${MY_CACHE:-$def_cache}
set +a

ensure_commands

header() {
	printf '\033[01;32m * \033[37m%s\033[00;39m\n' "$1"
}

header 'Adélie Linux CD Creation Tool'
printf '\n'

clean_dirs() {
	warn
	printf 'This will erase all files at the directories %s/cdroot-%s\n' `pwd` $ARCH
	printf '%s/initrd-%s and %s/squashroot-%s.\n\n' `pwd` $ARCH `pwd` $ARCH
	printf 'When you are ready, press RETURN.  To cancel, press Ctrl-C.\n'
	read dontcare

	rm -rf cdroot-$ARCH
	rm -rf initrd-$ARCH
	rm -rf squashroot-$ARCH
	mkdir cdroot-$ARCH
	mkdir initrd-$ARCH
	mkdir squashroot-$ARCH
}

install_pkgs() {
	header "Installing base system to squash root..."

	readonly PACKAGES="$(cat packages/base 2>/dev/null | tr '\n' ' ' || fatal 'No core packages specified')"
	readonly ARCH_PKGS="$(cat packages/arch/$ARCH 2>/dev/null | tr '\n' ' ' || echo '')"
	readonly KIND_PKGS="$(cat packages/kind/$KIND 2>/dev/null | tr '\n' ' ' || echo '')"

	mkdir -p squashroot-$ARCH/etc/apk
	cp -r keys squashroot-$ARCH/etc/apk/
	# Disable grub trigger.
	mkdir -p squashroot-$ARCH/etc/default
	printf "ADELIE_MANUAL_CONFIG=1\n" >> squashroot-$ARCH/etc/default/grub
	mkdir -p squashroot-$ARCH/dev
	mknod squashroot-$ARCH/dev/urandom c 1 9
	mkdir -p squashroot-$ARCH/usr/sbin
	apk --arch $ARCH \
		${CACHE:+--cache-dir "${CACHE}"} \
		-X "$URL/system/$EXTRA_MIRROR" \
		-X "$URL/user/$EXTRA_MIRROR" \
		-U --root squashroot-$ARCH --initdb add $PACKAGES $ARCH_PKGS $KIND_PKGS
}

make_structure() {
	mkdir -p squashroot-$ARCH/home/live
	cp squashroot-$ARCH/etc/skel/.zshrc squashroot-$ARCH/home/live/
	chown 1000:1000 squashroot-$ARCH/home/live/.zshrc
	mkdir squashroot-$ARCH/target
	mkdir -p squashroot-$ARCH/media/live
	for _runlevel in sysinit boot default shutdown; do
		mkdir -p squashroot-$ARCH/etc/runlevels/$_runlevel
	done

	echo 'adelie-live' > squashroot-$ARCH/etc/hostname
	echo 'mtab_is_file=no' > squashroot-$ARCH/etc/conf.d/mtab

	for siservice in udev udev-trigger lvmetad; do
		ln -s /etc/init.d/$siservice \
		   squashroot-$ARCH/etc/runlevels/sysinit/$siservice
	done

	for bootservice in root binfmt bootmisc fsck hostname hwclock keymaps \
	    localmount loopback modules mtab procfs sysctl sysfsconf \
	    termencoding tmpfiles.setup urandom; do
		ln -s /etc/init.d/$bootservice \
		   squashroot-$ARCH/etc/runlevels/boot/$bootservice
	done

	readonly BASE_SERVICES="$(cat services/base 2>/dev/null | tr '\n' ' ' || echo '')"
	readonly KIND_SERVICES="$(cat services/kind/$KIND 2>/dev/null | tr '\n' ' ' || echo '')"

	[ -z BASE_SERVICES ] || for base_service in $BASE_SERVICES; do
		ln -s /etc/init.d/$base_service \
			sqaushroot-$ARCH/etc/runlevels/default/$base_service
	done

	[ -z KIND_SERVICES ] || for service in $KIND_SERVICES; do
		ln -s /etc/init.d/$service \
			sqaushroot-$ARCH/etc/runlevels/default/$service
	done

	cat >squashroot-$ARCH/etc/fstab <<- FSTAB
		# Welcome to Adélie Linux.
		# This fstab(5) is for the live media only.  Do not edit or use for your installation.

		tmpfs	/tmp		tmpfs	defaults	0	1
		proc	/proc		proc	defaults	0	1
	FSTAB

	sed -i 's#/root:/bin/sh$#/root:/bin/zsh#' squashroot-$ARCH/etc/passwd
	echo 'live:x:1000:1000:Live User:/home/live:/bin/zsh' >> squashroot-$ARCH/etc/passwd
	echo 'live:x:1000:' >> squashroot-$ARCH/etc/group
	echo 'live::::::::' >> squashroot-$ARCH/etc/shadow
	chown 1000:1000 squashroot-$ARCH/home/live

	sed -i 's/pam_unix.so$/pam_unix.so nullok_secure/' squashroot-$ARCH/etc/pam.d/base-auth

	cat >squashroot-$ARCH/etc/resolv.conf <<- RESOLVE
		nameserver 2620:fe::fe
		nameserver 9.9.9.9
		nameserver 149.112.112.112
	RESOLVE

	cat >squashroot-$ARCH/etc/apk/repositories <<-REPOS
		https://distfiles.adelielinux.org/adelie/$APKVER/system/$EXTRA_MIRROR
		https://distfiles.adelielinux.org/adelie/$APKVER/user/$EXTRA_MIRROR
	REPOS
	# Saves first-sync on the media if a package is required.
	apk --root squashroot-$ARCH update

	cat >squashroot-$ARCH/etc/issue <<-ISSUE
		Welcome to Adélie Linux!
		You may log in as 'root' to install, or 'live' to play around.

		Have fun.

	ISSUE

	if test -n "${DO_FULL+full}"; then
		# This ensures we have documentation available on-disc, and to install.
		apk --arch $ARCH \
			${CACHE:+--cache-dir "${CACHE}"} \
			-X "$URL/system/$EXTRA_MIRROR" \
			-X "$URL/user/$EXTRA_MIRROR" \
			--root squashroot-$ARCH add docs
		readonly PACKAGES_DIR=squashroot-$ARCH/packages/$ARCH
		mkdir -p $PACKAGES_DIR
		# Fetch all APKs.
		apk --arch $ARCH \
			${CACHE:+--cache-dir "${CACHE}"} \
			-X "$URL/system/$EXTRA_MIRROR" \
			-X "$URL/user/$EXTRA_MIRROR" \
			--root squashroot-$ARCH fetch -o $PACKAGES_DIR $(apk --root squashroot-$ARCH info)
		# Sign the index using the signing key used by abuild.
		if test -n "${SIGN+doit}"; then
			apk index --description "$VERSION/$ARCH Live CD" -o .tmp.APKINDEX.tar.gz $PACKAGES_DIR/*.apk
			abuild-sign -q .tmp.APKINDEX.tar.gz
			mv .tmp.APKINDEX.tar.gz $PACKAGES_DIR/APKINDEX.tar.gz
		fi
	fi

	cp AdelieTux.icns cdroot-$ARCH/.VolumeIcon.icns
}

squash_it() {
	header 'Creating compressed file system image...'

	mksquashfs squashroot-$ARCH cdroot-$ARCH/$ARCH.squashfs -noappend
}

make_initrd() {
	header 'Creating initrd structure...'

	# mount points
	mkdir initrd-$ARCH/dev
	mkdir initrd-$ARCH/media
	for _rootdir in newroot lowerroot upperroot; do
		mkdir initrd-$ARCH/$_rootdir
		chmod 755 initrd-$ARCH/$_rootdir
	done
	mkdir initrd-$ARCH/proc
	mkdir initrd-$ARCH/sys

	# manual /dev nodes for initial udev startup
	mknod -m 600 initrd-$ARCH/dev/console c 5 1
	mknod -m 666 initrd-$ARCH/dev/null c 1 3
	mknod -m 666 initrd-$ARCH/dev/ptmx c 5 2
	mknod -m 666 initrd-$ARCH/dev/random c 1 8
	mknod -m 666 initrd-$ARCH/dev/tty c 5 0
	mknod -m 620 initrd-$ARCH/dev/tty1 c 4 1
	mknod -m 666 initrd-$ARCH/dev/urandom c 1 9
	mknod -m 666 initrd-$ARCH/dev/zero c 1 5

	# base
	mkdir initrd-$ARCH/lib
	cp squashroot-$ARCH/lib/ld-musl-$LDARCH.so.1 initrd-$ARCH/lib/
	cp squashroot-$ARCH/lib/libblkid.so.1 initrd-$ARCH/lib/
	cp squashroot-$ARCH/lib/libuuid.so.1 initrd-$ARCH/lib/

	# udev
	mkdir -p initrd-$ARCH/etc/udev
	mkdir initrd-$ARCH/run
	mkdir initrd-$ARCH/sbin
	cp squashroot-$ARCH/bin/udevadm initrd-$ARCH/sbin/
	cp squashroot-$ARCH/sbin/udevd initrd-$ARCH/sbin/
	cp squashroot-$ARCH/lib/libkmod.so.2 initrd-$ARCH/lib/
	cp squashroot-$ARCH/lib/liblzma.so.5 initrd-$ARCH/lib/
	cp squashroot-$ARCH/lib/libudev.so.1 initrd-$ARCH/lib/
	cp squashroot-$ARCH/lib/libz.so.1 initrd-$ARCH/lib/

	# init
	cp cdinit-$ARCH initrd-$ARCH/init

	header 'Compressing initrd...'

	(cd initrd-$ARCH; find . | cpio -H newc -o) > cdroot-$ARCH/initrd-$ARCH
	gzip -9 cdroot-$ARCH/initrd-$ARCH
	mv cdroot-$ARCH/initrd-$ARCH.gz cdroot-$ARCH/initrd-$ARCH
}

prepare_cdroot() {
	if test -f post/arch/$ARCH.sh; then
		header 'Running architecture-specific scripts...'
		sh post/arch/$ARCH.sh
	fi

	if test -f post/kind/$KIND.sh; then
		header "Running $KIND script..."
		sh post/kind/$KIND.sh
	fi

	header 'Adding kernel...'

	mv squashroot-$ARCH/boot/vmlinu* cdroot-$ARCH/bzImage-$ARCH
}

create_iso() {
	CD_VERSION="$VERSION"
	header 'Creating the CD...'

	readonly CD_PARAMS="$(cat iso-params-$ARCH | tr '\n' ' ')"
	CD_VERSION=$(echo $CD_VERSION | sed s/-alpha/a/)
	CD_VERSION=$(echo $CD_VERSION | sed s/-beta/b/)
	CD_VERSION=$(echo $CD_VERSION | sed s/-rc/rc/)
	mkdir -p out
	xorriso -as mkisofs -o out/adelie-${DO_FULL:-live}-$ARCH-$VERSION-$(date +%Y%m%d).iso -joliet -rational-rock -V "Adelie $CD_VERSION $ARCH" ${CD_PARAMS} cdroot-$ARCH
}

case $PHASE in
	clean)
		clean_dirs
		;;
	install)
		install_pkgs
		make_structure
		;;
	initrd)
		make_initrd
		;;
	iso)
		create_iso
		;;
	all)
		clean_dirs
		install_pkgs
		make_structure
		make_initrd
		squash_it
		prepare_cdroot
		create_iso
		;;
	all_but_iso)
		clean_dirs
		install_pkgs
		make_structure
		make_initrd
		squash_it
		prepare_cdroot
		;;
	*)
		fatal
		printf 'Unknown phase %s.  Stop.\n' $PHASE
		;;
esac