mirror of
https://github.com/YunoHost/install_script.git
synced 2024-09-03 20:06:25 +02:00
Merge 453702f51f
into 0b060404fc
This commit is contained in:
commit
093b6cf6c7
8 changed files with 882 additions and 0 deletions
|
@ -1,5 +1,7 @@
|
|||
# YunoHost installation scripts
|
||||
|
||||
Forked version: some discussion available [here](https://forum.yunohost.org/t/building-a-new-image-for-raspberry-debian-jessie-fr-en/1101)
|
||||
|
||||
## Context
|
||||
|
||||
The script `install_yunohost` will install [YunoHost](https://yunohost.org/) on a Debian system.
|
||||
|
|
2
build_arm_image/.gitignore
vendored
Normal file
2
build_arm_image/.gitignore
vendored
Normal file
|
@ -0,0 +1,2 @@
|
|||
_build_arm_steps
|
||||
.*.swp
|
244
build_arm_image/01_create_sdcard.sh
Executable file
244
build_arm_image/01_create_sdcard.sh
Executable file
|
@ -0,0 +1,244 @@
|
|||
#!/bin/bash
|
||||
#
|
||||
# Create the sdcard on your PC with the latest debian raspbian.
|
||||
#
|
||||
# Usage:
|
||||
# ./01_create_sdcard.sh downloaded_debian_image.zip /dev/sdcard_device
|
||||
# ./01_create_sdcard.sh generated_yunohost.img /dev/sdcard_device
|
||||
#
|
||||
# HowTo:
|
||||
# find your sdcard device:
|
||||
# mount it first graphicaly
|
||||
# next issue a df -h look for something "/dev/mmcblk0p1"
|
||||
# create a totally new image:
|
||||
# delete _build_arm_steps/ which is the cache folder.
|
||||
# follows steps in README.md
|
||||
#
|
||||
# Status: functional
|
||||
# Licence: GPLv3
|
||||
# Author: sylvain303@github
|
||||
# SeeAlso:
|
||||
|
||||
# informations about Raspbian image:
|
||||
# Raspbian Jessie Lite Version: November 2015 Release date: 2015-11-21
|
||||
# version: SHA-1 of the .zip: 97888fcd9bfbbae2a359b0f1d199850852bf0104
|
||||
# Kernel version: 4.1
|
||||
# http://downloads.raspberrypi.org/raspbian/release_notes.txt
|
||||
|
||||
|
||||
# DOWNLOAD_URL used only for echo a message
|
||||
# SHA_DEBIAN_IMG_ZIP need to be updated to match your image
|
||||
DOWNLOAD_URL=https://www.raspberrypi.org/downloads/raspbian/
|
||||
SHA_DEBIAN_IMG_ZIP="6741a30d674d39246302a791f1b7b2b0c50ef9b7"
|
||||
|
||||
die() {
|
||||
echo "$*"
|
||||
exit 1
|
||||
}
|
||||
|
||||
# helper, test if a shell program exists in PATH
|
||||
test_tool() {
|
||||
local cmd=$1
|
||||
if type $cmd > /dev/null
|
||||
then
|
||||
# OK
|
||||
return 0
|
||||
else
|
||||
die "tool missing: $cmd"
|
||||
fi
|
||||
}
|
||||
|
||||
# skip if the file exists.
|
||||
# usage: skip_if _build_arm_steps/somefile && return 2
|
||||
skip_if() {
|
||||
if [[ -e "$1" ]]
|
||||
then
|
||||
echo "cached"
|
||||
return 0
|
||||
fi
|
||||
# echo -n "continue for $1"
|
||||
return 1
|
||||
}
|
||||
|
||||
sha_verify_zip() {
|
||||
local zip=$DEBIAN_IMG_ZIP
|
||||
|
||||
[[ -z "$zip" ]] && { echo "no zip refuse to run"; return 3; }
|
||||
|
||||
local out=_build_arm_steps/sha_verify_zip
|
||||
skip_if $out && return 2
|
||||
sha1sum $zip > $out
|
||||
# read only sha check hash
|
||||
local sha="$(sed -e 's/\(^[a-f0-9]\+\).*/\1/' $out)"
|
||||
if [[ "$sha" != "$SHA_DEBIAN_IMG_ZIP" ]]
|
||||
then
|
||||
die "NOK: '$sha' != '$SHA_DEBIAN_IMG_ZIP'"
|
||||
fi
|
||||
}
|
||||
|
||||
# unzip raspbian image in the cache folder
|
||||
unzip_img() {
|
||||
local img_filename=$(unzip -l $DEBIAN_IMG_ZIP | awk '/\.img$/ { print $4 }')
|
||||
if ! skip_if _build_arm_steps/$img_filename
|
||||
then
|
||||
unzip -o $DEBIAN_IMG_ZIP -d _build_arm_steps
|
||||
fi
|
||||
|
||||
# get extrated image filename from zip file
|
||||
DEBIAN_IMG="_build_arm_steps/$img_filename"
|
||||
}
|
||||
|
||||
# helper, try to guess top device name
|
||||
# /dev/sdp2 => /dev/sdp
|
||||
# /dev/mmcblk0p1 => /dev/mmcblk0
|
||||
# just some regexp, no smart thing
|
||||
get_top_device() {
|
||||
local device="$1"
|
||||
local regexp1='^/dev/sd[a-z]'
|
||||
local regexp2='^/dev/mmcblk[0-9]'
|
||||
|
||||
if [[ "$device" =~ $regexp1 ]]
|
||||
then
|
||||
#echo sd
|
||||
device="${device/[0-9]/}"
|
||||
elif [[ "$device" =~ $regexp2 ]]
|
||||
then
|
||||
#echo mmcblk
|
||||
device="${device/p[0-9]/}"
|
||||
fi
|
||||
|
||||
echo "$device"
|
||||
}
|
||||
|
||||
# helper, umount the sdcard partition if any
|
||||
umount_sdcard_partition() {
|
||||
[[ -z "$SDCARD" ]] && { echo '$SDCARD is empty refusing to run'; return; }
|
||||
local p
|
||||
# search and replace all occurence of / by .
|
||||
local pattern=${SDCARD////.}
|
||||
pattern=${pattern/p[0-9]/}
|
||||
for p in $(df | awk "/^$pattern/ { print \$1 }")
|
||||
do
|
||||
sudo umount $p
|
||||
done
|
||||
echo "done device for sdcard=${pattern//.//}"
|
||||
}
|
||||
|
||||
dd_to_sdcard() {
|
||||
[[ -z "$SDCARD" ]] && { echo '$SDCARD is empty refusing to run'; return; }
|
||||
# ensure that sdcard partitions are unmounted with umount_sdcard_partition
|
||||
echo "starting dd it will take some times…"
|
||||
sudo dd bs=16M if="$DEBIAN_IMG" of=$SDCARD
|
||||
sudo sync
|
||||
}
|
||||
|
||||
test_all_tools() {
|
||||
for t in $*
|
||||
do
|
||||
test_tool $t
|
||||
done
|
||||
}
|
||||
|
||||
# mount the .img so we can write on it before copying on the sdcard
|
||||
mount_loopback_img() {
|
||||
[[ -z "$DEBIAN_IMG" ]] && { echo '$DEBIAN_IMG is empty refusing to run'; return; }
|
||||
mkdir -p _build_arm_steps/mnt
|
||||
local dev_loop0=$(sudo losetup -f --show "$DEBIAN_IMG")
|
||||
local part_offset=$(sudo fdisk -l $dev_loop0 | awk '/Linux/ { print $2 }')
|
||||
# mount the ext4 partition at computed offset
|
||||
local dev_loop1=$(sudo losetup -f --show -o $((512 * $part_offset)) "$DEBIAN_IMG")
|
||||
sudo mount $dev_loop1 _build_arm_steps/mnt/
|
||||
}
|
||||
|
||||
umount_loopback_img() {
|
||||
# find mounted loopback
|
||||
local dev_loop1=$(mount | awk '/_build_arm_steps/ { print $1 }')
|
||||
# compute loop n-1
|
||||
local n=${dev_loop1#/dev/loop}
|
||||
local dev_loop0="/dev/loop$(($n - 1))"
|
||||
sudo umount _build_arm_steps/mnt
|
||||
sudo losetup -d $dev_loop1
|
||||
sudo losetup -d $dev_loop0
|
||||
}
|
||||
|
||||
# copy a local key for ssh without password later
|
||||
# having an ssh-key pair to remote connect on the raspi will be used by the next step
|
||||
add_ssh_key_to_img() {
|
||||
mount_loopback_img
|
||||
cd _build_arm_steps/mnt/home/pi/
|
||||
mkdir .ssh
|
||||
local ssh_key=$OLDPWD/_build_arm_steps/nopasskey
|
||||
# silently generate an ssh-key pair
|
||||
yes | ssh-keygen -q -t rsa -C "nopasskey-install" -N "" -f $ssh_key > /dev/null
|
||||
cp ${ssh_key}.pub .ssh/authorized_keys
|
||||
# remove some permissions
|
||||
chmod -R go= .ssh/
|
||||
# give to pi user id
|
||||
sudo chown -R --reference . .ssh
|
||||
# return to working folder
|
||||
cd - > /dev/null
|
||||
umount_loopback_img
|
||||
echo "ssh-key added"
|
||||
}
|
||||
|
||||
# functions call in that order, edit remove a long running step if already done or if
|
||||
# you want to skip it, step states are saved in folder _build_arm_steps and skipped automatically.
|
||||
# STEPS is modifiy in main() if argument1 is an .img and not a .zip
|
||||
STEPS="
|
||||
sha_verify_zip
|
||||
unzip_img
|
||||
add_ssh_key_to_img
|
||||
umount_sdcard_partition
|
||||
dd_to_sdcard"
|
||||
|
||||
# main wrapper, so the script can be sourced for debuging purpose or unittesting
|
||||
main() {
|
||||
# positional argument must be script argument.
|
||||
# init
|
||||
if [[ -z "$1" ]]
|
||||
then
|
||||
echo "argument 1 error: expecting raspbian image file.zip or an img"
|
||||
echo "can be downloaded here: $DOWNLOAD_URL"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
local regexp='\.img$'
|
||||
|
||||
# reading script argument
|
||||
DEBIAN_IMG_ZIP=$1
|
||||
if [[ "$1" =~ $regexp ]]
|
||||
then
|
||||
DEBIAN_IMG="$1"
|
||||
DEBIAN_IMG_ZIP=""
|
||||
# write image verbatim without modification
|
||||
STEPS="
|
||||
umount_sdcard_partition
|
||||
dd_to_sdcard"
|
||||
else
|
||||
[[ -f "$DEBIAN_IMG_ZIP" ]] || die "error raspbian image not found: '$DEBIAN_IMG_ZIP'"
|
||||
fi
|
||||
|
||||
SDCARD=$(get_top_device "$2")
|
||||
[[ -z "$SDCARD" ]] && die "argument 2 error: expecting sdcard_device"
|
||||
|
||||
test_all_tools dd sync sudo losetup ssh-keygen
|
||||
mkdir -p _build_arm_steps
|
||||
|
||||
# actions loop
|
||||
for s in $STEPS
|
||||
do
|
||||
echo -n "$s: "
|
||||
eval $s
|
||||
done
|
||||
}
|
||||
|
||||
# sourcing code detection, if code is sourced for debug purpose, main is not executed.
|
||||
[[ $0 != "$BASH_SOURCE" ]] && sourced=1 || sourced=0
|
||||
if [[ $sourced -eq 0 ]]
|
||||
then
|
||||
# pass positional argument as is
|
||||
main "$@"
|
||||
else
|
||||
# just print STEPS so I can copy/paste to call them interactivly
|
||||
echo $STEPS
|
||||
fi
|
252
build_arm_image/02_install_yunohost.sh
Executable file
252
build_arm_image/02_install_yunohost.sh
Executable file
|
@ -0,0 +1,252 @@
|
|||
#!/bin/bash
|
||||
#
|
||||
# Usage: ./02_install_yunohost.sh DHCP_IP_ADDRESS_OF_RASPBERRYPI
|
||||
#
|
||||
# Doc: See README.md
|
||||
#
|
||||
# STEPS:
|
||||
# 1. enlarge filesystem with raspi-config --expand-rootfs and reboot
|
||||
# 2. run install_yunohostv2 on the raspi
|
||||
# 3. install an yunohost-firstboot script and shutdown
|
||||
#
|
||||
# Status: functional
|
||||
# Licence: GPLv3
|
||||
# Author: sylvain303@github
|
||||
|
||||
# wrapper to use ssh with our nopasskey
|
||||
# Usage: sshpi "some remote commands"
|
||||
sshpi() {
|
||||
ssh -i _build_arm_steps/nopasskey pi@$PI_IP "$@"
|
||||
}
|
||||
|
||||
# harcoded test IP, you can change for yours for debuging. See main()
|
||||
PI_IP=192.168.1.2
|
||||
# the installer script is used localy, no git clone else where.
|
||||
YUNOHOST_INSTALL=../install_yunohostv2
|
||||
# the folder on the raspberrypi, where script are uploaded
|
||||
YUNOHOST_REMOTE_DIR=/tmp/install_yunohost
|
||||
# dummy password
|
||||
PASSROOT='Free_money?yunomakeit'
|
||||
|
||||
# used by main() See at the end.
|
||||
ask_root_pass() {
|
||||
echo "HINT: very good program to generate strong memorisable passwords: pwqgen"
|
||||
echo "HINT: sudo apt-get install passwdqc"
|
||||
echo -n "Enter a new root password for raspberrypi: "
|
||||
read PASSROOT
|
||||
}
|
||||
|
||||
# helper to "scp" a local script to the raspberrypi
|
||||
# Usage: scp_yunohost local_filename
|
||||
scp_yunohost() {
|
||||
if [[ -z "$1" ]]
|
||||
then
|
||||
echo "scp_yunohost: expect a local filename"
|
||||
return 1
|
||||
fi
|
||||
|
||||
if [[ ! -f "$1" ]]
|
||||
then
|
||||
echo "scp_yunohost: filename not found: '$1'"
|
||||
return 1
|
||||
fi
|
||||
|
||||
if [[ -z "$YUNOHOST_REMOTE_DIR" ]]
|
||||
then
|
||||
echo "scp_yunohost: error \$YUNOHOST_REMOTE_DIR is empty"
|
||||
return 1
|
||||
fi
|
||||
|
||||
local script="$1"
|
||||
local scriptb="$(basename $script)"
|
||||
|
||||
# no real scp, just wrap with sshpi
|
||||
cat "$script" | \
|
||||
sshpi "mkdir -p $YUNOHOST_REMOTE_DIR && \
|
||||
cat > $YUNOHOST_REMOTE_DIR/$scriptb && \
|
||||
chmod a+x $YUNOHOST_REMOTE_DIR/$scriptb
|
||||
"
|
||||
}
|
||||
|
||||
# helper, compute common remote_step script name so they can be skiped by do_step
|
||||
make_step_file() {
|
||||
local step_name="$1"
|
||||
local step_file="yuno_step_${step_name}.sh"
|
||||
echo $step_file
|
||||
}
|
||||
|
||||
# helper will create a local script and upload it to raspberrypi in $YUNOHOST_REMOTE_DIR
|
||||
# Usage: create_remote_script $FUNCNAME "shell commands…"
|
||||
create_remote_script() {
|
||||
local step_file=$(make_step_file "$1")
|
||||
local actions="$2"
|
||||
local dst="_build_arm_steps/$step_file"
|
||||
|
||||
echo '#!/bin/bash' > $dst
|
||||
echo "# $1" >> $dst
|
||||
echo "$actions" >> $dst
|
||||
scp_yunohost $dst
|
||||
|
||||
# the remote file on the raspi
|
||||
echo $YUNOHOST_REMOTE_DIR/$step_file
|
||||
}
|
||||
|
||||
# ======================= ACTIONS - remote actions steps to be performed on the raspberrypi.
|
||||
|
||||
init_sdcard_and_reboot() {
|
||||
local actions="
|
||||
# fix locale warning
|
||||
sudo sed -i -e '/\(en_US\|fr_FR\)\.UTF-8/ s/^# //' /etc/locale.gen
|
||||
sudo locale-gen
|
||||
# enlarge filesystem, we need more space to install yunohost
|
||||
sudo raspi-config --expand-rootfs
|
||||
echo 'rebooting raspberrypi…'
|
||||
sudo reboot
|
||||
"
|
||||
create_remote_script $FUNCNAME "$actions"
|
||||
}
|
||||
|
||||
install_yunohostv2_on_sdcard() {
|
||||
local actions="
|
||||
# change root password
|
||||
echo 'root:$PASSROOT' | sudo chpasswd
|
||||
# some packages
|
||||
sudo apt-get -y install git
|
||||
cat << ENDMSG
|
||||
!!!!!!!!!!!!!!!!!!!!!!! sdcard builder !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
|
||||
Launching unattended install_yunohostv2 which will take some time to run…
|
||||
You can watch using a new ssh connection to the raspberrypi.
|
||||
By example issuing those commands:
|
||||
cd $PWD
|
||||
source 02_install_yunohost.sh
|
||||
sshpi
|
||||
tail -f /var/log/yunohost-installation.log
|
||||
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
|
||||
ENDMSG
|
||||
# run yunohost installer unattended (scp previously with scp_yunohost)
|
||||
cd /tmp/install_yunohost && sudo ./install_yunohostv2 -a
|
||||
"
|
||||
create_remote_script $FUNCNAME "$actions"
|
||||
}
|
||||
|
||||
finalize_yunohost() {
|
||||
local actions="
|
||||
# uploaded modified or new config files to the raspberrypi
|
||||
cd /
|
||||
sudo tar xzf $YUNOHOST_REMOTE_DIR/etc.tgz
|
||||
# yunohost-firstboot is an helper to cleanup and resizefs with srinked sdcard
|
||||
# image
|
||||
sudo chmod a+x /etc/init.d/yunohost-firstboot
|
||||
sudo insserv /etc/init.d/yunohost-firstboot
|
||||
cat << ENDMSG
|
||||
=================================================================================
|
||||
We are going to shutdown the raspberrypi now.
|
||||
When it's done, the yunohost image is ready to be copied back on your comupter.
|
||||
* Unplug raspberrypi
|
||||
* remove the sdcard
|
||||
* Go to next step!
|
||||
=================================================================================
|
||||
ENDMSG
|
||||
# remove pi user, we will not be able to ssh connect anymore
|
||||
# sudo userdel pi
|
||||
sudo shutdown -h now
|
||||
"
|
||||
create_remote_script $FUNCNAME "$actions"
|
||||
}
|
||||
|
||||
reboot_pi() {
|
||||
echo "${FUNCNAME}…"
|
||||
sshpi "sudo reboot"
|
||||
}
|
||||
|
||||
# ======================= END ACTIONS
|
||||
|
||||
# helper, simply visualy wait for raspberrypi to come up for ssh
|
||||
# Usage: wait_raspberrypi || some_fail command
|
||||
wait_raspberrypi() {
|
||||
local max=30
|
||||
local n=1
|
||||
local up=false
|
||||
while [[ $n -le $max ]]
|
||||
do
|
||||
sleep 1
|
||||
# remove redirect to /dev/null to debug
|
||||
output=$(timeout 2 ssh -o "StrictHostKeyChecking=no" \
|
||||
-i _build_arm_steps/nopasskey pi@$PI_IP 'echo up' 2> /dev/null)
|
||||
echo -n .
|
||||
if [[ "$output" == 'up' ]]
|
||||
then
|
||||
up=true
|
||||
break
|
||||
fi
|
||||
n=$(($n + 1))
|
||||
done
|
||||
|
||||
if $up
|
||||
then
|
||||
echo up
|
||||
return 0
|
||||
else
|
||||
echo too_long
|
||||
echo "something goes wrong for your raspberrypi or the timeout it too short"
|
||||
echo "please retry"
|
||||
return 1
|
||||
fi
|
||||
}
|
||||
|
||||
# wrapper, execute a step script on the raspberrypi or skip it
|
||||
# Status: draft
|
||||
do_step() {
|
||||
local step=$1
|
||||
local step_file=$(make_step_file $step)
|
||||
local remote_step
|
||||
echo -n "$step: "
|
||||
# skip if script already there
|
||||
if [[ -e "_build_arm_steps/$step_file" ]]
|
||||
then
|
||||
echo "SKIPED"
|
||||
return 1
|
||||
else
|
||||
echo "RUNING"
|
||||
remote_step=$(eval $step)
|
||||
sshpi $remote_step
|
||||
return 0
|
||||
fi
|
||||
}
|
||||
|
||||
# main script code, wrapped inside a function, so the whole script can also be
|
||||
# sourced as a lib, for debug or unittesting purpose.
|
||||
main() {
|
||||
# you can comment the 2 lines, for debuging. Fix PI_IP with your dhcp IP.
|
||||
PI_IP=$1
|
||||
ask_root_pass
|
||||
|
||||
do_step init_sdcard_and_reboot
|
||||
|
||||
wait_raspberrypi || return 1
|
||||
|
||||
scp_yunohost $YUNOHOST_INSTALL
|
||||
NEED_REBOOT=false
|
||||
do_step install_yunohostv2_on_sdcard && { NEED_REBOOT=true; }
|
||||
|
||||
# backup the installation.log on the PC
|
||||
sshpi "cat /var/log/yunohost-installation.log" > \
|
||||
_build_arm_steps/yunohost-installation.log
|
||||
|
||||
$NEED_REBOOT && reboot_pi
|
||||
|
||||
wait_raspberrypi || return 1
|
||||
|
||||
# was ./intsall_arm.sh
|
||||
tar czf _build_arm_steps/etc.tgz etc
|
||||
scp_yunohost _build_arm_steps/etc.tgz
|
||||
do_step finalize_yunohost
|
||||
}
|
||||
|
||||
# sourcing code detection, if code is sourced for debug purpose, main is not executed.
|
||||
[[ $0 != "$BASH_SOURCE" ]] && sourced=1 || sourced=0
|
||||
if [[ $sourced -eq 0 ]]
|
||||
then
|
||||
# pass positional argument as is
|
||||
main "$@"
|
||||
fi
|
157
build_arm_image/03_copy_sdcard_to_img.sh
Executable file
157
build_arm_image/03_copy_sdcard_to_img.sh
Executable file
|
@ -0,0 +1,157 @@
|
|||
#!/bin/bash
|
||||
#
|
||||
# Create the image file from the sdcard
|
||||
#
|
||||
# Usage:
|
||||
# ./03_copy_sdcard_to_img.sh /dev/sdcard_device
|
||||
#
|
||||
# the resulting image will be stored in _build_arm_steps
|
||||
#
|
||||
# Status: prototype
|
||||
# Licence: GPLv3
|
||||
# Author: sylvain303@github
|
||||
|
||||
die() {
|
||||
echo "$*"
|
||||
exit 1
|
||||
}
|
||||
|
||||
# helper, test if a shell program exists in PATH
|
||||
test_tool() {
|
||||
local cmd=$1
|
||||
if type $cmd > /dev/null
|
||||
then
|
||||
# OK
|
||||
return 0
|
||||
else
|
||||
die "tool missing: $cmd"
|
||||
fi
|
||||
}
|
||||
|
||||
# helper, try to guess top device name
|
||||
# /dev/sdp2 => /dev/sdp
|
||||
# /dev/mmcblk0p1 => /dev/mmcblk0
|
||||
# just some regexp, no smart thing
|
||||
get_top_device() {
|
||||
local device="$1"
|
||||
local regexp1='^/dev/sd[a-z]'
|
||||
local regexp2='^/dev/mmcblk[0-9]'
|
||||
|
||||
if [[ "$device" =~ $regexp1 ]]
|
||||
then
|
||||
#echo sd
|
||||
device="${device/[0-9]/}"
|
||||
elif [[ "$device" =~ $regexp2 ]]
|
||||
then
|
||||
#echo mmcblk
|
||||
device="${device/p[0-9]/}"
|
||||
fi
|
||||
|
||||
echo "$device"
|
||||
}
|
||||
|
||||
# helper, umount the sdcard partition if any
|
||||
umount_sdcard_partition() {
|
||||
[[ -z "$SDCARD" ]] && { echo '$SDCARD is empty refusing to run'; return; }
|
||||
local p
|
||||
# search and replace all occurence of / by .
|
||||
local pattern=${SDCARD////.}
|
||||
pattern=${pattern/p[0-9]/}
|
||||
for p in $(df | awk "/^$pattern/ { print \$1 }")
|
||||
do
|
||||
sudo umount $p
|
||||
done
|
||||
echo "done device for sdcard=${pattern//.//}"
|
||||
}
|
||||
|
||||
dd_from_sdcard() {
|
||||
[[ -z "$SDCARD" ]] && { echo '$SDCARD is empty refusing to run'; return; }
|
||||
[[ -z "$OUTPUT_IMG" ]] && { echo '$OUTPUT_IMG is empty refusing to run'; return; }
|
||||
local count
|
||||
if [[ ! -z "$1" ]]
|
||||
then
|
||||
count="count=$1"
|
||||
fi
|
||||
# ensure that sdcard partitions are unmounted with umount_sdcard_partition
|
||||
sudo dd bs=16M if=$SDCARD of=_build_arm_steps/$OUTPUT_IMG $count
|
||||
}
|
||||
|
||||
test_all_tools() {
|
||||
for t in $*
|
||||
do
|
||||
test_tool $t
|
||||
done
|
||||
}
|
||||
|
||||
# debug, not used
|
||||
mount_sdcard_data_partition() {
|
||||
local part_data=2
|
||||
[[ ! -d _build_arm_steps/sdcard ]] && mkdir _build_arm_steps/sdcard
|
||||
sudo mount ${SDCARD}p2 _build_arm_steps/sdcard
|
||||
}
|
||||
|
||||
# prototype, not used. Wanna test if I can d.d only used part of the partion, and fix it back on the PC
|
||||
# not working yet, may be not achieved anyway…
|
||||
get_used_partition_size() {
|
||||
local start_offset=$(sudo fdisk -l /dev/mmcblk0 | awk '/Linux/ { print $2 * 512 }')
|
||||
local used=$(df -B1 _build_arm_steps/sdcard | awk '/dev.mmcblk0p2/ { print $3 }')
|
||||
|
||||
echo "start_offset=$start_offset"
|
||||
echo "used =$used"
|
||||
|
||||
local count=$(($start_offset + $used))
|
||||
echo "count =$count"
|
||||
local div=$(($count / (16 * 1048576) ))
|
||||
echo "16M =$(($count / (16 * 1048576) ))"
|
||||
echo "verif =$(( ($div + 1) * (16 * 1048576) ))"
|
||||
}
|
||||
|
||||
shrink_img() {
|
||||
echo "shrinking _build_arm_steps/$OUTPUT_IMG"
|
||||
sudo ./autosizer.sh _build_arm_steps/$OUTPUT_IMG
|
||||
}
|
||||
|
||||
# functions call in that order, edit remove a long running step if already done or if
|
||||
# you want to skip it, step states are saved in folder _build_arm_steps and skipped automatically.
|
||||
STEPS="
|
||||
umount_sdcard_partition
|
||||
dd_from_sdcard
|
||||
shrink_img"
|
||||
|
||||
# main wrapper, so the script can be sourced for debuging purpose or unittesting
|
||||
main() {
|
||||
# positional argument must be script argument.
|
||||
# init
|
||||
if [[ -z "$1" ]]
|
||||
then
|
||||
echo "argument 1 error: expecting sdcard_device"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
test_all_tools dd sync sudo losetup
|
||||
if [[ ! -d _build_arm_steps ]]
|
||||
then
|
||||
die "cannot find _build_arm_steps/ folder are you following build step?"
|
||||
fi
|
||||
# reading script argument
|
||||
SDCARD=$(get_top_device "$1")
|
||||
OUTPUT_IMG="$(date "+%Y-%m-%d")_yunohost_rasbian-jessie.img"
|
||||
|
||||
# actions loop
|
||||
for s in $STEPS
|
||||
do
|
||||
echo -n "$s: "
|
||||
eval $s
|
||||
done
|
||||
}
|
||||
|
||||
# sourcing code detection, if code is sourced for debug purpose, main is not executed.
|
||||
[[ $0 != "$BASH_SOURCE" ]] && sourced=1 || sourced=0
|
||||
if [[ $sourced -eq 0 ]]
|
||||
then
|
||||
# pass positional argument as is
|
||||
main "$@"
|
||||
else
|
||||
# just print STEPS so I can copy/paste to call them interactivly
|
||||
echo $STEPS
|
||||
fi
|
152
build_arm_image/README.md
Normal file
152
build_arm_image/README.md
Normal file
|
@ -0,0 +1,152 @@
|
|||
# Build your own yunohost image for Raspberry Pi
|
||||
|
||||
This folder contains helper scripts to build an arm image of yunohost for raspberry.
|
||||
The files here are for builder. They are not needed to install your yunohost, the purpose is to reproduce the .img.
|
||||
Of course you can try the step exlained here, and you will get a fresh yunohost at the end.
|
||||
|
||||
The folder etc/ structure maps debian OS folders, shell script here are helpers.
|
||||
Files in etc/ subfolders will be copied on the sdcard when installation is finished.
|
||||
|
||||
Those scripts are following the steps provided here: https://yunohost.org/#/build_arm_image
|
||||
|
||||
### Notes:
|
||||
|
||||
`01_create_sdcard.sh` can be used to copy raspbian image to a sdcard and stop here, without yunohost.
|
||||
An ssh key is added to remote access pi@raspbian account without passphrase.
|
||||
|
||||
Ex:
|
||||
```
|
||||
ssh -i _build_arm_steps/nopasskey pi@DHCP_IP
|
||||
```
|
||||
|
||||
Don't forget to at first: `sudo raspbi-config` + enlarge file-system to have full size sdcard for your raspberry.
|
||||
(also accomplished by: `sudo raspi-config --expand-rootfs`)
|
||||
Enjoy.
|
||||
|
||||
## License
|
||||
All the content here is distributed under [GPLv3](http://www.gnu.org/licenses/gpl-3.0.txt).
|
||||
|
||||
## See also
|
||||
* https://forum.yunohost.org/t/building-a-new-image-for-raspberry-debian-jessie-fr-en/1101/13 - discussion about building a new image for Raspberry Pi.
|
||||
* http://build.yunohost.org/ - some build here
|
||||
|
||||
## Files
|
||||
|
||||
Description of the files available here.
|
||||
|
||||
All step stripts are using your PC to store some files in the folder `_build_arm_steps/`. This folder will be created by `01_create_sdcard.sh`. You can wipe it, or remove selected script data form it, to redo a step.
|
||||
|
||||
All step scripts are designed to run in this folder on your PC:
|
||||
|
||||
~~~bash
|
||||
git clone this_repos
|
||||
cd path_to/build_arm_image/
|
||||
./01_create_sdcard.sh raspbian-jessie.zip /dev/mmcblk0
|
||||
# plug and boot raspberrypi
|
||||
./02_install_yunohost.sh 192.168.1.200
|
||||
# unplug raspberrypi and connect the sdcard back to the PC
|
||||
./03_copy_sdcard_to_img.sh /dev/mmcblk0
|
||||
~~~
|
||||
|
||||
### Steps
|
||||
|
||||
Scripts are prefixed by a number which is the order they must be ran.
|
||||
|
||||
#### 01_create_sdcard.sh
|
||||
|
||||
Create a bootable image for raspbian. You have to download the .zip of the raspbian image.
|
||||
([See:](https://www.raspberrypi.org/downloads/raspbian/)
|
||||
|
||||
This script embeds sudo call for using `dd` to copy the raw image to the sdcard.
|
||||
It will add an ssh key to `pi` default rasbian user in order to connect later to continue automated installation (See `02_install_yunohost.sh`)
|
||||
The pi user will be removed at the end (Not yet, See #4). The ssh key-pair is generated only for you, in `_build_arm_steps/`
|
||||
|
||||
Usage:
|
||||
|
||||
~~~
|
||||
./01_create_sdcard.sh image_rasbian.zip /dev/device_to_sdcard
|
||||
~~~
|
||||
|
||||
It takes some minutes to perform all the steps (~ 2m3.867s at last run). Be patient.
|
||||
|
||||
Use commend like `df` or `lsblk` to find the name of your sdcard device. The script is taking care of umonting the partition if any.
|
||||
It also guesses the disk's name if you gave a partition's name instead of entire disk device's name. i
|
||||
(ex: /dev/mmcblk0p2 --> /dev/mmcblk0)
|
||||
|
||||
BE CAREFULL not to wipe the wrong device!
|
||||
|
||||
#### 02_install_yunohost.sh
|
||||
|
||||
Should I say: you have to plug the new sdcard freshly created and boot the Raspberry PI pluged on the same network as your PC?
|
||||
|
||||
The Raspberry has hopefully booted and is displaying a console's prompt, which looks like:
|
||||
|
||||
~~~
|
||||
Raspbian GNU/Linux 8 raspberrypi tty1
|
||||
|
||||
raspberrypi login:
|
||||
~~~
|
||||
|
||||
If DHCP has done its job well, you also have an IP address on the Raspberry PI console screen:
|
||||
|
||||
~~~
|
||||
My IP address is 192.168.1.123
|
||||
~~~
|
||||
|
||||
Or what ever your DHCP is giving…
|
||||
|
||||
Run (on the PC, not the raspberry):
|
||||
|
||||
~~~bash
|
||||
./02_install_yunohost.sh 192.168.1.123
|
||||
~~~
|
||||
|
||||
This step is quite long. It took ~24min on my Raspberry. Be patient.
|
||||
A message will be displayed on the screen to explain how you can watch it if you want.
|
||||
|
||||
If you got ssh `Host key verification failed.`, to fix it then:
|
||||
|
||||
~~~bash
|
||||
rm _build_arm_steps/yuno_step*
|
||||
# retry
|
||||
./02_install_yunohost.sh 192.168.1.123
|
||||
~~~
|
||||
|
||||
#### 03_copy_sdcard_to_img.sh
|
||||
|
||||
When the build is finished, the Raspberry will shutdown. Unplug and insert the sdcard back in the computer.
|
||||
|
||||
~~~bash
|
||||
./03_copy_sdcard_to_img.sh /dev/sdcard_device
|
||||
~~~
|
||||
|
||||
This will ask your sudo password and `dd` the resulting img from the sdcard back to your PC.
|
||||
Stored in `_build_arm_steps/` folder. It takes arround 6min on my PC to copy an sdcard of 8G.
|
||||
|
||||
The image will be automaticly shrinked to its minimal size using autosizer.sh.
|
||||
|
||||
|
||||
#### test the image back
|
||||
|
||||
You can test the resutling image back again with `01_create_sdcard.sh`.
|
||||
|
||||
~~~bash
|
||||
./01_create_sdcard.sh _build_arm_steps/newly_created_image.img /dev/sdcard_device
|
||||
~~~
|
||||
|
||||
#### share
|
||||
|
||||
You can zip, bzip2, or…, and share your freshly created yunohost image on the [forum](https://forum.yunohost.org).
|
||||
|
||||
Enjoy!
|
||||
|
||||
### Helper
|
||||
|
||||
#### autosizer.sh
|
||||
|
||||
Used on your PC to compact the dd image you will copy back after the rapsbian has been built.
|
||||
This script requier root privilege to run and modify the local sdcard image.
|
||||
|
||||
|
||||
## See also
|
||||
* https://github.com/likeitneverwentaway/rpi_buildbot
|
46
build_arm_image/autosizer.sh
Executable file
46
build_arm_image/autosizer.sh
Executable file
|
@ -0,0 +1,46 @@
|
|||
#!/bin/bash
|
||||
# Automatic Image file resizer
|
||||
# Written by SirLagz
|
||||
#
|
||||
# got from: http://sirlagz.net/2013/03/10/script-automatic-rpi-image-downsizer/
|
||||
#
|
||||
# Usage: sudo autosizer.sh sdcard.img
|
||||
|
||||
strImgFile=$1
|
||||
|
||||
if [[ ! $(whoami) =~ "root" ]]; then
|
||||
echo ""
|
||||
echo "**********************************"
|
||||
echo "*** This should be run as root ***"
|
||||
echo "**********************************"
|
||||
echo ""
|
||||
exit
|
||||
fi
|
||||
|
||||
if [[ -z $strImgFile ]]; then
|
||||
echo "Usage: ./autosizer.sh <Image File>"
|
||||
exit
|
||||
fi
|
||||
|
||||
if [[ ! -e $strImgFile || ! $(file $strImgFile) =~ "DOS/MBR boot sector" ]]; then
|
||||
echo "Error : Not an image file, or file doesn't exist"
|
||||
exit
|
||||
fi
|
||||
|
||||
partinfo=`parted -m $strImgFile unit B print`
|
||||
partnumber=`echo "$partinfo" | grep ext4 | awk -F: ' { print $strImgFile } '`
|
||||
partstart=`echo "$partinfo" | grep ext4 | awk -F: ' { print substr($2,0,length($2)-1) } '`
|
||||
loopback=`losetup -f --show -o $partstart $strImgFile`
|
||||
e2fsck -f $loopback
|
||||
minsize=`resize2fs -P $loopback | awk -F': ' ' { print $2 } '`
|
||||
minsize=`echo $minsize+1000 | bc`
|
||||
resize2fs -p $loopback $minsize
|
||||
sleep 1
|
||||
losetup -d $loopback
|
||||
partnewsize=`echo "$minsize * 4096" | bc`
|
||||
newpartend=`echo "$partstart + $partnewsize" | bc`
|
||||
# TODO: 2 is probably $partnumber
|
||||
part1=`parted $strImgFile rm 2`
|
||||
part2=`parted $strImgFile unit B mkpart primary $partstart $newpartend`
|
||||
endresult=`parted -m $strImgFile unit B print free | tail -1 | awk -F: ' { print substr($2,0,length($2)-1) } '`
|
||||
truncate -s $endresult $strImgFile
|
27
build_arm_image/etc/init.d/yunohost-firstboot
Executable file
27
build_arm_image/etc/init.d/yunohost-firstboot
Executable file
|
@ -0,0 +1,27 @@
|
|||
#!/bin/sh
|
||||
### BEGIN INIT INFO
|
||||
# Provides: expand rootfs and Generates new ssh host keys on first boot
|
||||
# Required-Start: $remote_fs $syslog
|
||||
# Required-Stop: $remote_fs $syslog
|
||||
# Default-Start: 2 3 4 5
|
||||
# Default-Stop:
|
||||
# Short-Description: Generates new ssh host keys on first boot
|
||||
# Description: Generatesapt-get --purge clean new ssh host keys on $
|
||||
### END INIT INFO
|
||||
echo "Expanding rootfs ..."
|
||||
raspi-config --expand-rootfs
|
||||
echo "Generating new ssh keys ..."
|
||||
# Delete SSH keys
|
||||
rm -f /etc/ssh/ssh_host_*
|
||||
yes | ssh-keygen -f /etc/ssh/ssh_host_rsa_key -N '' -t rsa
|
||||
yes | ssh-keygen -f /etc/ssh/ssh_host_dsa_key -N '' -t dsa
|
||||
yes | ssh-keygen -f /etc/ssh/ssh_host_ecdsa_key -N '' -t ecdsa -b 521
|
||||
echo "Deleting logs ..."
|
||||
find /var/log -type f -exec echo > {} \;
|
||||
echo "Purging apt ..."
|
||||
apt-get --purge clean
|
||||
echo "Removing myself ..."
|
||||
insserv -r /etc/init.d/yunohost-firstboot
|
||||
rm -f /etc/init.d/yunohost-firstboot
|
||||
echo "Rebooting ..."
|
||||
reboot
|
Loading…
Add table
Reference in a new issue