Advertisement
Guest User

pinet

a guest
Apr 20th, 2019
150
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 95.71 KB | None | 0 0
  1. #!/bin/bash
  2. # Part of PiNet https://github.com/PiNet/PiNet
  3. #
  4. # See LICENSE file for copyright and license details
  5.  
  6. version=1.2.10
  7.  
  8. #PiNet (Previously RaspberryPi-LTSP)
  9.  
  10. #Written by Andrew Mulholland, based off the fantastic work by vagrantc and alksig from the LTSP community
  11. #Initial guide available at http://cascadia.debian.net/trenza/Documentation/raspberrypi-ltsp-howto/
  12. #Spindle was used to figure out needed changes to generate Raspbian image https://github.com/asb/spindle
  13. #
  14. #PiNet is a utility for setting up and configuring a Linux Terminal Server Project (LTSP) network for Raspberry Pi's
  15.  
  16. #Constants
  17. #------------------------
  18. ConfigFileLoc=/etc/pinet
  19. Timeout=1
  20. PythonFunctions="/usr/local/bin/pinet_functions_python.py"
  21. PythonStart="python3"
  22. p="$PythonStart $PythonFunctions"
  23. RepositoryBase="https://github.com/PiNet/"
  24. RepositoryName="PiNet"
  25. BootRepositoryName="PiNet-Boot"
  26. RawRepositoryBase="https://raw.github.com/PiNet/"
  27. Repository="$RepositoryBase$RepositoryName"
  28. BootRepository="$RepositoryBase$BootRepositoryName"
  29. RawRepository="$RawRepositoryBase$RepositoryName"
  30. ReleaseBranch="jessie-stable" #Overwriten later on in SetupRepositories()
  31. ltspBase="/opt/ltsp/"
  32. cpuArch="armhf"
  33.  
  34.  
  35. #------------------------
  36.  
  37. SetupRepositories(){
  38. ReleaseChannel=$(echo "$ReleaseChannel" | tr '[:upper:]' '[:lower:]')
  39. case "$ReleaseChannel" in
  40. stable)
  41. ReleaseBranch="stable"
  42. ;;
  43.  
  44. beta)
  45. ReleaseBranch="beta"
  46. ;;
  47.  
  48. dev)
  49. ReleaseBranch="beta"
  50. ;;
  51.  
  52. alpha)
  53. ReleaseBranch="alpha"
  54. ;;
  55.  
  56. "custom:*")
  57. ReleaseBranch=${ReleaseChannel:7:channelLength}
  58. ;;
  59.  
  60. *)
  61. ReleaseBranch="stable"
  62. ;;
  63. esac
  64.  
  65. }
  66.  
  67. LegacyFixes() {
  68. #Runs a number of legacy code checks, making sure everything is configured correctly.
  69. if [ -d "/home/shared" ]; then
  70. CheckSharedFolderIntegrity
  71. fi
  72. CheckDesktopShortcut
  73. teacherSudoCheck
  74. CheckRaspberryPiUIMods
  75. ReplaceAnyTextOnLine /opt/ltsp/armhf/etc/lts.conf "NFS_HOME=/home" ""
  76. if [ -f "/etc/default/epoptes" ]; then
  77. ReplaceTextLine "/etc/default/epoptes" "SOCKET_GROUP=staff" "SOCKET_GROUP=teacher"
  78. fi
  79.  
  80. if [ ! -f "/opt/ltsp/armhf/usr/local/bin/pinet-screenshot.sh" ]; then
  81. AddScreenshot
  82. UpdateConfig NBDBuildNeeded true
  83. fi
  84.  
  85. if [ ! -f "/usr/local/bin/changePassword.sh" ]; then
  86. AddPasswordReset
  87. UpdateConfig NBDBuildNeeded true
  88. fi
  89. CheckPipSymbolicLinkBug
  90. local passwdVersion=$(cat /home/$SUDO_USER/Desktop/pinet-password.desktop | sed -n '2p')
  91. ReplaceAnyTextOnLine /opt/ltsp/armhf/etc/lts.conf REMOTE_APPS REMOTE_APPS=True
  92. exitcode=$?
  93. sed -i '/^[[:blank:]]*$/d' /opt/ltsp/armhf/etc/lts.conf
  94. if [ "$exitcode" = "1" ]; then
  95. UpdateConfig NBDBuildNeeded true
  96. fi
  97.  
  98. CheckDebianVersion
  99. CheckBackupScriptVersion
  100.  
  101. if [ -f "/usr/local/bin/pinet-functions-python.py" ]; then
  102. mv "/usr/local/bin/pinet-functions-python.py" "/usr/local/bin/pinet_functions_python.py"
  103. fi
  104.  
  105. # Make sure that all the required Python libraries are installed
  106. $PythonStart -c 'import feedparser' 2>/dev/null || (sudo apt-get install -y python3-feedparser )
  107. $PythonStart -c 'import requests' 2>/dev/null || (sudo apt-get install -y python3-requests )
  108. $PythonStart -c 'import netifaces' 2>/dev/null || (sudo apt-get install -y python3-netifaces )
  109.  
  110. if [ "$NBDBuildNeeded" = "true" ] && [ ! "$1" = "NoRecompress" ] ; then
  111. echo $"A required system update has been found. The Raspbian operating system will now be recompressed to apply this update"
  112. NBDRun
  113. else
  114. UpdateConfig NBDBuildNeeded false
  115. fi
  116. $p "checkStatsNotification"
  117.  
  118. }
  119.  
  120.  
  121. ConfigFileRead(){
  122. #Reads the config file and loads in data as variables
  123. #Taken from - http://wiki.bash-hackers.org/howto/conffile
  124. configfile_secured="/tmp/pinet-config"
  125.  
  126. if egrep -q -v '^#|^[^ ]*=[^;]*' "$ConfigFileLoc"; then
  127. # filter the original to a new file
  128. egrep '^#|^[^ ]*=[^;&]*' "$ConfigFileLoc" > "$configfile_secured"
  129. ConfigFileLoc="$configfile_secured"
  130. source "$ConfigFileLoc"
  131. else
  132. source "$ConfigFileLoc"
  133. fi
  134. }
  135.  
  136. ReplaceTextLine(){
  137. # ReplaceTextLine /textfile bob brian
  138. egrep -i "^$2" $1 >> /dev/null
  139. if [ $? = 0 ]; then
  140. sed -i "s/$2.*/$3/g" $1
  141. else
  142. echo "$3" >> $1
  143. fi
  144.  
  145. }
  146.  
  147. ReplaceAnyTextOnLine(){
  148. # ReplaceTextLine /textfile bob brian
  149. #REMEMBER!! The & symbol can't be in any of the strings as SED is using it for separating. Can change it if need be
  150. egrep -i "$2" $1 >> /dev/null
  151. if [ $? -eq 0 ]; then
  152. sed -i "s&.*$2.*&$3&g" $1
  153. return 0
  154. else
  155. echo "$3" >> $1
  156. return 1
  157. fi
  158.  
  159. }
  160.  
  161. UpdateConfig(){
  162. #Updates the PiNet config file with provided values
  163. #Example - UpdateConfig bob false
  164. local configName=$1
  165. local configValue=$2
  166. egrep -i "^$configName" $ConfigFileLoc >> /dev/null
  167. if [ $? = 0 ]; then
  168. sed -i "s/$configName.*/$configName=$configValue/g" $ConfigFileLoc
  169. else
  170. echo "$configName=$configValue" >> $ConfigFileLoc
  171. fi
  172. ConfigFileRead
  173. }
  174.  
  175.  
  176. gp(){
  177. #Part of the Python functions code. As Python functions uses a text file to communicate back and forth, this reads it and echos to console.
  178. if [ -f /tmp/ltsptmp ]; then
  179. echo $(head -n 1 /tmp/ltsptmp)
  180. fi
  181. }
  182.  
  183. installLTSP() {
  184. #Installs main packages required by LTSP
  185. apt-get update && apt-get upgrade -y
  186.  
  187. apt-get install -y ltsp-server qemu-user-static binfmt-support ldm-server sed git gnome-control-center nfs-kernel-server xml2 openssh-server inotify-tools bindfs
  188. exitstatus=$?
  189. if ! [ $exitstatus = 0 ]; then
  190. whiptail --title $"ERRORE!" --msgbox $"Nessuna connessione a Internet, oppure altro software e' gia' installato nel sistema! Per favore, aspetta 5-10 minuti o connettiti a Internet" 10 78
  191. exit 1
  192. fi
  193.  
  194. }
  195.  
  196.  
  197.  
  198. buildClient() {
  199. #Creates the custom config file needed to build Raspbian and grabs keychain. Then starts the build
  200.  
  201. wget http://archive.raspbian.org/raspbian.public.key -O - | gpg --import
  202. gpg --export 90FDDD2E >> /etc/ltsp/raspbian.public.key.gpg
  203.  
  204. rm /etc/ltsp/ltsp-raspbian.conf
  205.  
  206. cat <<EOF > /etc/ltsp/ltsp-raspbian.conf
  207. DEBOOTSTRAP_KEYRING=/etc/ltsp/raspbian.public.key.gpg
  208. DIST=jessie
  209. # For alternate raspbian mirrors, see: http://www.raspbian.org/RaspbianMirrors
  210. MIRROR=http://mirrordirector.raspbian.org/raspbian
  211. SECURITY_MIRROR=none
  212. UPDATES_MIRROR=none
  213. LOCALE="$LANG UTF-8"
  214. KERNEL_PACKAGES=linux-image-3.10-3-rpi
  215. EOF
  216.  
  217. VENDOR=Debian ltsp-build-client --arch armhf --config /etc/ltsp/ltsp-raspbian.conf
  218. }
  219.  
  220.  
  221.  
  222. OneTimeFixes(){
  223. #A number of one off fixes needed to be run
  224.  
  225. echo "/opt/ltsp *(ro,no_root_squash,async,no_subtree_check)" >> /etc/exports #sets up OS exporting for NFS
  226. echo "/home *(rw,sync,no_subtree_check)" >> /etc/exports #Sets up home folder exporting for NFS
  227.  
  228. mkdir /etc/skel/handin
  229.  
  230. echo '#!/bin/sh' >> /etc/network/if-up.d/tftpd-hpa #Script to make sure tftpd-hpa autostarts
  231. echo "service tftpd-hpa restart" >> /etc/network/if-up.d/tftpd-hpa
  232. chmod 755 /etc/network/if-up.d/tftpd-hpa
  233. service tftpd-hpa restart
  234. groupadd -g 628 pupil
  235. groupadd -g 629 teacher
  236.  
  237. }
  238.  
  239. configFixes() {
  240. #Configuration file changes required after the client is built. These are not once off as they reside inside the Raspberry Pi OS
  241.  
  242. sed -i -e 's,/bin/plymouth quit --retain-splash.*,/bin/plymouth quit --retain-splash || true,g' /opt/ltsp/armhf/etc/init.d/ltsp-client-core
  243. echo 'LTSP_FATCLIENT=true' >> /opt/ltsp/armhf/etc/lts.conf
  244. ReplaceAnyTextOnLine /opt/ltsp/armhf/etc/lts.conf REMOTE_APPS REMOTE_APPS=True
  245. DuplicateLTSConf
  246.  
  247. ltsp-chroot --arch armhf groupadd -g 628 pupil
  248. ltsp-chroot --arch armhf groupadd -g 629 teacher
  249. AddUdevRules
  250.  
  251. printf 'snd-bcm2835\n' >> /opt/ltsp/armhf/etc/modules
  252.  
  253. addSoundcardDefault
  254.  
  255. }
  256.  
  257. addSoundcardDefault(){
  258. #Adds the soundcard settings for Raspbian
  259. grep -q mmap_emul "/opt/ltsp/armhf/etc/asound.conf" > /dev/null 2>&1
  260. checkSound=$?
  261. if [ ! $checkSound = 1 ]; then
  262. cat <<\EOF1 > /opt/ltsp/armhf/etc/asound.conf
  263. pcm.!default {
  264. type hw;
  265. card 0;
  266. }
  267.  
  268. ctl.!default {
  269. type hw
  270. card 0
  271. }
  272.  
  273. EOF1
  274. return 1
  275. else
  276. return 0
  277.  
  278. fi
  279.  
  280. }
  281.  
  282. checkInternet(){
  283. #Checks if the internet is connected. Mainly passes off to CheckInternet Python programme in Python functions
  284. if [ ! "$CheckInternetConnection" = "false" ]; then
  285. $p CheckInternet $Timeout
  286. result=$(gp)
  287. return $result
  288. else
  289. return 0
  290. fi
  291.  
  292. }
  293.  
  294. checkInternetDetailed(){
  295. #Does a more detailed internet connection check than checkInternet, uses internetFullStatusCheck()
  296. if [ ! "$CheckInternetConnection" = "false" ]; then
  297. $p internetFullStatusCheck
  298. status=$(gp)
  299. return $status
  300. else
  301. return 0
  302. fi
  303. }
  304.  
  305. UpdateSD() {
  306. #Function for updating the SD card images
  307.  
  308. $p updateSD
  309. ConfigFileRead # Grab updated $NBDBuildNeeded
  310. if [ "$NBDBuildNeeded" = "true" ] && [ ! "$1" = "NoRecompress" ]; then
  311. echo $"A required system update has been found. The Raspbian operating system will now be recompressed to apply this update."
  312. NBDRun
  313. fi
  314. return
  315.  
  316. }
  317.  
  318. EnableNBDswap(){
  319. #Enables NBD swap system. Allows the Raspberry Pis to use NBD partition as swap
  320.  
  321. rm /etc/nbd-server/conf.d/swap.conf
  322. cat <<EOF > /etc/nbd-server/conf.d/swap.conf
  323. [swap]
  324. exportname = /tmp/nbd-swap/%s
  325. prerun = nbdswapd %s
  326. postrun = rm -f %s
  327. EOF
  328. service nbd-server restart
  329.  
  330. }
  331.  
  332.  
  333. FixRepo() {
  334. #Adds the repositories used by Raspbian. The public keys are included
  335.  
  336. # Adds PiNet repo
  337. echo "Adding PiNet repository key."
  338. echo deb http://apt.pinet.org.uk jessie main > /opt/ltsp/armhf/etc/apt/sources.list.d/pinet.list
  339. wget http://apt.pinet.org.uk/pinet.public.key -O /opt/ltsp/armhf/tmp/pinet.public.key
  340. sudo ltsp-chroot --arch armhf apt-key add /tmp/pinet.public.key
  341.  
  342. rm -rf /opt/ltsp/armhf/etc/apt/sources.list.d/raspi.list
  343. echo "Sto aggiungendo la chiave del repository della PiNet Foundation."
  344. echo "deb http://archive.raspberrypi.org/debian/ jessie main ui staging" > /opt/ltsp/armhf/etc/apt/sources.list.d/raspi.list
  345. ltsp-chroot --arch armhf apt-key add - <<EOF1
  346. -----BEGIN PGP PUBLIC KEY BLOCK-----
  347. Version: GnuPG v1.4.12 (GNU/Linux)
  348.  
  349. mQENBE/d7o8BCACrwqQacGJfn3tnMzGui6mv2lLxYbsOuy/+U4rqMmGEuo3h9m92
  350. 30E2EtypsoWczkBretzLUCFv+VUOxaA6sV9+puTqYGhhQZFuKUWcG7orf7QbZRuu
  351. TxsEUepW5lg7MExmAu1JJzqM0kMQX8fVyWVDkjchZ/is4q3BPOUCJbUJOsE+kK/6
  352. 8kW6nWdhwSAjfDh06bA5wvoXNjYoDdnSZyVdcYCPEJXEg5jfF/+nmiFKMZBraHwn
  353. eQsepr7rBXxNcEvDlSOPal11fg90KXpy7Umre1UcAZYJdQeWcHu7X5uoJx/MG5J8
  354. ic6CwYmDaShIFa92f8qmFcna05+lppk76fsnABEBAAG0IFJhc3BiZXJyeSBQaSBB
  355. cmNoaXZlIFNpZ25pbmcgS2V5iQE4BBMBAgAiBQJP3e6PAhsDBgsJCAcDAgYVCAIJ
  356. CgsEFgIDAQIeAQIXgAAKCRCCsSmSf6MwPk6vB/9pePB3IukU9WC9Bammh3mpQTvL
  357. OifbkzHkmAYxzjfK6D2I8pT0xMxy949+ThzJ7uL60p6T/32ED9DR3LHIMXZvKtuc
  358. mQnSiNDX03E2p7lIP/htoxW2hDP2n8cdlNdt0M9IjaWBppsbO7IrDppG2B1aRLni
  359. uD7v8bHRL2mKTtIDLX42Enl8aLAkJYgNWpZyPkDyOqamjijarIWjGEPCkaURF7g4
  360. d44HvYhpbLMOrz1m6N5Bzoa5+nq3lmifeiWKxioFXU+Hy5bhtAM6ljVb59hbD2ra
  361. X4+3LXC9oox2flmQnyqwoyfZqVgSQa0B41qEQo8t1bz6Q1Ti7fbMLThmbRHiuQEN
  362. BE/d7o8BCADNlVtBZU63fm79SjHh5AEKFs0C3kwa0mOhp9oas/haDggmhiXdzeD3
  363. 49JWz9ZTx+vlTq0s+I+nIR1a+q+GL+hxYt4HhxoA6vlDMegVfvZKzqTX9Nr2VqQa
  364. S4Kz3W5ULv81tw3WowK6i0L7pqDmvDqgm73mMbbxfHD0SyTt8+fk7qX6Ag2pZ4a9
  365. ZdJGxvASkh0McGpbYJhk1WYD+eh4fqH3IaeJi6xtNoRdc5YXuzILnp+KaJyPE5CR
  366. qUY5JibOD3qR7zDjP0ueP93jLqmoKltCdN5+yYEExtSwz5lXniiYOJp8LWFCgv5h
  367. m8aYXkcJS1xVV9Ltno23YvX5edw9QY4hABEBAAGJAR8EGAECAAkFAk/d7o8CGwwA
  368. CgkQgrEpkn+jMD5Figf/dIC1qtDMTbu5IsI5uZPX63xydaExQNYf98cq5H2fWF6O
  369. yVR7ERzA2w33hI0yZQrqO6pU9SRnHRxCFvGv6y+mXXXMRcmjZG7GiD6tQWeN/3wb
  370. EbAn5cg6CJ/Lk/BI4iRRfBX07LbYULCohlGkwBOkRo10T+Ld4vCCnBftCh5x2OtZ
  371. TOWRULxP36y2PLGVNF+q9pho98qx+RIxvpofQM/842ZycjPJvzgVQsW4LT91KYAE
  372. 4TVf6JjwUM6HZDoiNcX6d7zOhNfQihXTsniZZ6rky287htsWVDNkqOi5T3oTxWUo
  373. m++/7s3K3L0zWopdhMVcgg6Nt9gcjzqN1c0gy55L/g==
  374. =mNSj
  375. -----END PGP PUBLIC KEY BLOCK-----
  376. EOF1
  377.  
  378. ltsp-chroot --arch armhf debconf-set-selections <<SELEOF
  379. wolfram-engine shared/accepted-wolfram-eula boolean true
  380. SELEOF
  381. #Auto accepts wolfram eula
  382.  
  383. echo deb http://mirrordirector.raspbian.org/raspbian/ jessie main contrib non-free rpi > /opt/ltsp/armhf/etc/apt/sources.list
  384.  
  385. ltsp-chroot --arch armhf apt-get update
  386. #Fetches most recent package lists
  387.  
  388. }
  389.  
  390.  
  391. Finished() {
  392. #Function performing any actions that should happen after the boot image has been created
  393. whiptail --title $"Installazione Completata" --msgbox $"L'installazione del client è stata completata, un file boot.img è stato posizionato nella directory /root, scrivilo in una scheda SD" 16 78
  394. }
  395.  
  396.  
  397. RaspiTheme(){
  398. #Grabs a copy of the PiNet desktop/login theme and installs
  399.  
  400. rm -rf /tmp/pinet
  401. git clone --no-single-branch --depth 1 $Repository.git /tmp/pinet #Clones main repository, including boot files
  402. (cd "/tmp/pinet"; git checkout "$ReleaseBranch")
  403. cp -r /tmp/pinet/themes/raspi /opt/ltsp/armhf/usr/share/ldm/themes/raspi
  404. rm /opt/ltsp/armhf/etc/alternatives/ldm-theme
  405. ln -s /usr/share/ldm/themes/raspi /opt/ltsp/armhf/etc/alternatives/ldm-theme
  406. rm -rf /tmp/pinet
  407. cp /opt/ltsp/armhf/usr/share/ldm/themes/raspi/bg.png /opt/ltsp/armhf/usr/share/images/desktop-base/pinet.png
  408. sudo ltsp-chroot --arch armhf update-alternatives --install /usr/share/images/desktop-base/desktop-background desktop-background /usr/share/images/desktop-base/pinet.png 100
  409.  
  410. }
  411.  
  412.  
  413. NBDRun() {
  414. #Checks if it should be auto NBD compressing or not, if it should be, it recompresses the image
  415. ConfigFileRead
  416. if [ "$NBD" = "true" ]; then #If NBD is enabled on the system overall
  417. if [ "$NBDuse" = "true" ]; then #If temporarily NBD is disable
  418. echo "--------------------------------------------------------"
  419. echo $"Compressione dell'immagine, questo processo potrebbe durare 5 minuti"
  420. echo "--------------------------------------------------------"
  421. ltsp-update-image /opt/ltsp/armhf #If NBD is enabled, recompress the image
  422. UpdateConfig NBDBuildNeeded false
  423. else
  424. echo $"L'auto recomprissione del Raspbian OS è disabilitata. Per attivarla, avvia il comando NBD-recompress dall'altro menu"
  425. fi
  426. fi
  427.  
  428. }
  429.  
  430. NBDSetup() {
  431. #Setup function for NBD, asks user if they wish to use it, if not it defaults to NFS
  432.  
  433. whiptail --title $"Network technology" --yesno $"Sono disponibili 2 tecnologie di rete per PiNet. NBD e NFS. NBD utilizza la compressione che migliora drasticamente i tempi di caricamento delle applicazioni. Il compromesso è però dopo ogni modifica al sistema operativo, l'immagine deve essere ricompressa che può richiedere circa 5 minuti. NFS è più lento ma non ha bisogno di essere compresso, tutte le modifiche vengono eseguite dal vivo. In caso di dubbio, selezionare NBD." --yes-button "NBD" --no-button "NFS" 11 78
  434. exitstatus=$?
  435. if [ $exitstatus = 0 ]; then
  436. EnableNBD
  437. else
  438. UpdateConfig NBD false
  439. UpdateConfig NBDuse false
  440. UpdateConfig NBDBuildNeeded false
  441. ConfigFileRead
  442. fi
  443. }
  444.  
  445. EnableNBD() {
  446. /usr/sbin/ltsp-update-image --config-nbd /opt/ltsp/armhf
  447. service nbd-server restart
  448. UpdateConfig NBD true
  449. UpdateConfig NBDuse true
  450. UpdateConfig NBDBuildNeeded false
  451. ConfigFileRead
  452.  
  453. }
  454.  
  455. AddSoftware(){
  456. #All the software not included in normal base Debian that has been added to Raspbian normally by Spindle
  457.  
  458. #------------------------------------------------------------------------------------------
  459. #******************************************************************************************
  460.  
  461. $p installChrootSoftware
  462. return 0
  463.  
  464. }
  465.  
  466.  
  467. AddUdevRules(){
  468.  
  469. ltsp-chroot --arch armhf printf 'ATTRS{idVendor}=="0694", ATTRS{idProduct}=="0003", SUBSYSTEMS=="usb", ACTION=="add", MODE="0666", GROUP="plugdev"' >> /etc/udev/rules.d/40-scratch.rules
  470. ltsp-chroot --arch armhf printf "SUBSYSTEM==\"gpio*\", PROGRAM=\"/bin/sh -c 'chown -R root:pupil /sys/class/gpio && chmod -R 770 /sys/class/gpio; chown -R root:pupil /sys/devices/virtual/gpio && chmod -R 770 /sys/devices/virtual/gpio; chown -R root:pupil /sys/devices/platform/soc/*.gpio/gpio && chmod -R 770 /sys/devices/platform/soc/*.gpio/gpio'\"\n" > /etc/udev/rules.d/99-com.rules
  471. ltsp-chroot --arch armhf printf 'SUBSYSTEM=="input", GROUP="pupil", MODE="0660"\n' >> /etc/udev/rules.d/99-com.rules
  472. ltsp-chroot --arch armhf printf 'SUBSYSTEM=="i2c-dev", GROUP="pupil", MODE="0660"\n' >> /etc/udev/rules.d/99-com.rules
  473. ltsp-chroot --arch armhf printf 'SUBSYSTEM=="spidev", GROUP="pupil", MODE="0660"\n' >> /etc/udev/rules.d/99-com.rules
  474. ltsp-chroot --arch armhf printf 'SUBSYSTEM=="bcm2835-gpiomem", GROUP="pupil", MODE="0660"\n' >> /etc/udev/rules.d/99-com.rules
  475.  
  476. }
  477.  
  478. PiConfigFixes(){
  479. #Configuration changes to Raspberry Pi files, mostly to do with LXDE instead of Raspbian itself
  480.  
  481. ltsp-chroot --arch armhf sed /etc/xdg/lxsession/LXDE/desktop.conf -i -e "s|sNet/ThemeName.*|sNet/ThemeName=Mist|"
  482. ltsp-chroot --arch armhf sed /etc/xdg/openbox/LXDE/rc.xml -i -e \
  483. "s|<drawContents>yes</drawContents>|<drawContents>no</drawContents>|"
  484. ltsp-chroot --arch armhf apt-get install -y raspberrypi-artwork
  485. ltsp-chroot --arch armhf update-alternatives --install /usr/share/images/desktop-base/desktop-background desktop-background /usr/share/raspberrypi-artwork/raspberry-pi-logo.png 100
  486. ltsp-chroot --arch armhf PCMANFMCFG=/etc/xdg/pcmanfm/LXDE/pcmanfm.conf
  487. ltsp-chroot --arch armhf sed "$PCMANFMCFG" -i -e 's/^wallpaper_mode.*/wallpaper_mode=3/'
  488. ltsp-chroot --arch armhf sed "$PCMANFMCFG" -i -e 's/^desktop_bg.*/desktop_bg=#ffffff/'
  489. ltsp-chroot --arch armhf sed "$PCMANFMCFG" -i -e 's/^su_cmd.*/su_cmd=gksu %s/'
  490. }
  491.  
  492.  
  493. EpoptesInstaller() {
  494. #Installs Epoptes classroom managment software
  495. apt-get update
  496. apt-get install -y epoptes
  497. gpasswd -a root staff
  498. ltsp-chroot --arch armhf apt-get update
  499. ltsp-chroot --arch armhf apt-get install -y epoptes-client --no-install-recommends
  500. ltsp-chroot --arch armhf epoptes-client -c
  501. ReplaceTextLine "/etc/default/epoptes" "SOCKET_GROUP" "SOCKET_GROUP=teacher"
  502. }
  503.  
  504. EpoptesRun() {
  505. #Launches Epoptes classroom management software. Makes sure it is being run as the user, not as root.
  506. su -c "epoptes &" $SUDO_USER > /dev/null 2>&1 &
  507. }
  508.  
  509. fixGroups(){
  510. # Verify correct groups exist, then make sure all users are in correct groups.
  511. $p verifyCorrectGroupUsers
  512. ConfigFileRead
  513. if [ "$NBDBuildNeeded" = "true" ] && [ ! "$1" = "NoRecompress" ] ; then
  514. NBDRun
  515. whiptail --title $"Riavvio richiesto" --msgbox $"È stata apportata una modifica dell'ID di gruppo per correggere una mancata corrispondenza dell'ID. Questo non è nulla di cui preoccuparsi a meno che non si vedano più volte. Riavvia il tuo server PiNet il prima possibile." 9 78
  516. fi
  517. }
  518.  
  519.  
  520. fixGroupsSingle() {
  521. #Check a single user is in the correct groups
  522. $p verifyCorrectGroupSingleUser $1
  523. }
  524.  
  525.  
  526.  
  527. AddTeacher() {
  528. #Adds a new teacher user to the system
  529. whiptail --title $"Insegnante" --msgbox $"Gli insegnanti hanno pieno accesso amministrativo sul server (quindi possono eseguire PiNet), accesso completo in lettura / scrittura a tutte le cartelle condivise e al livello di insegnante di Epoptes (in modo da poter controllare i computer degli studenti)." 9 78
  530. username=$(SelectUser $"per aggiungere al gruppo degli insegnanti")
  531. if [ ! $username = 1 ]; then
  532. INIT=""
  533. AddUserToTeacher $username
  534. whiptail --title $"Successo!" --msgbox "L'utente $username è stato aggiunto al gruppo insegnanti." 8 78
  535. fi
  536. }
  537.  
  538. AddUserToTeacher() {
  539. #Adds the user to the teacher group
  540. usermod -a -G teacher $1
  541. AddDesktopShortcutToUser $1
  542. }
  543.  
  544. FixDesktopIcons(){
  545. #Adds all the correct desktop icons for PiNet
  546. rm -rf /etc/skel/Desktop
  547. cd /opt/ltsp/armhf/usr/share/applications
  548. mkdir /etc/skel/Desktop
  549. sudo cp -a scratch.desktop idle.desktop idle3.desktop lxterminal.desktop debian-reference-common.desktop wolfram-mathematica.desktop epiphany-browser.desktop wolfram-language.desktop sonic-pi.desktop minecraft-pi.desktop /etc/skel/Desktop
  550. cd /etc/skel
  551. wget "https://github.com/KenT2/python-games/tarball/master" -O python_games.tar.gz
  552. tar -xvf python_games.tar.gz
  553. mv KenT2-python-games* python_games
  554. chmod +x python_games/launcher.sh
  555. rm python_games.tar.gz
  556. cd /etc/skel/Desktop
  557. cat <<\EOF2 > python-games.desktop
  558. [Desktop Entry]
  559. Name=Python Games
  560. Comment=From http://inventwithpython.com/pygame/
  561. Exec=sh -c $HOME/python_games/launcher.sh
  562. Icon=/usr/share/pixmaps/python.xpm
  563. Terminal=false
  564. Type=Application
  565. Categories=Application;Games;
  566. StartupNotify=true
  567. EOF2
  568.  
  569. cut -d: -f1,3 /etc/passwd | egrep ':[0-9]{4}$' | cut -d: -f1 | while IFS= read -r user
  570. do
  571. mkdir /home/$user/Desktop
  572. cd /home/$user/Desktop/
  573. cp -R /etc/skel/Desktop/* /home/$user/Desktop/
  574. chown -R "$user" *
  575. cp -R /etc/skel/python_games /home/$user/python_games
  576.  
  577. done
  578.  
  579. AddScreenshot
  580. AddPasswordReset
  581.  
  582. }
  583.  
  584.  
  585. CollectWork(){
  586. #A work collection system. It grabs files from students "handin" folders, copies them to "submitted" folder on the server and changes their owner
  587. INIT="$SUDO_USER"
  588. USERHAND=$(whiptail --inputbox $"Immettere il nome utente dell'account utente su cui si desidera salvare il lavoro raccolto. Questo di solito è il nome del tuo account" 8 78 $INIT --title $"User selection" 3>&1 1>&2 2>&3)
  589.  
  590. exitstatus=$?
  591. if [ $exitstatus = 0 ]; then
  592. whiptail --title $"WARNING" --yesno $"The current submitted folder will be deleted, are you sure?" 8 78
  593. exitstatus=$?
  594. if [ $exitstatus = 0 ]; then
  595. rm -rf /home/"$USERHAND"/submitted
  596. mkdir /home/"$USERHAND"/submitted
  597. exitstatus=$?
  598. if [ $exitstatus = 0 ]; then
  599. if [ "$USERHAND" != "" ]; then
  600. cut -d: -f1,3 /etc/passwd | egrep ':[0-9]{4}$' | cut -d: -f1 | while IFS= read -r user
  601. do
  602. if groups "$user" | grep -q -E ' pupil(\s|$)'; then
  603. if [ -d "/home/$user/handin" ]; then
  604. echo $"l'utente $user ha una cartella di handin"
  605. cp -r "/home/$user/handin/" "/home/$USERHAND/submitted/$user/"
  606.  
  607. fi
  608.  
  609. else
  610. echo $"L'utente $user non ha una cartella di handin"
  611.  
  612. fi
  613. done
  614.  
  615. chown -R "$USERHAND" /home/"$USERHAND"/submitted
  616. whiptail --title $"Completato!" --msgbox $"I lavori degli studenti sono stati raccolti e sono accessibili in : /home/$USERHAND/submitted/" 8 78
  617. else
  618. whiptail --title $"ERRORE" --msgbox $"l'username non può essere uno spazio vuoto" 8 78
  619. fi
  620. else
  621. whiptail --title $"ERRORE" --msgbox $"L'utente $USERHAND non è stato trovato" 8 78
  622.  
  623. fi
  624. fi
  625. fi
  626.  
  627. }
  628.  
  629. CopyToUsers(){ #(Path-to-folder, path-in-home, skel? warning?)
  630. #Used to copy files out to every user, plus to the skel folder for new users
  631.  
  632. if [ $4 == "True" ]; then
  633. whiptail --title "ATTENZIONE" --yesno "Questo comporta copiare una cartella alla directory home, se esiste la cancello?" 8 78
  634. local delete=$?
  635. else
  636. local delete=0
  637. fi
  638. local CurrentFilepath=$1
  639. local NewFilepath=$2
  640. local filename=$(basename "$NewFilepath")
  641. cut -d: -f1,3 /etc/passwd | egrep ':[0-9]{4}$' | cut -d: -f1 | while IFS= read -r user
  642. do
  643. if [ $delete = 0 ] ; then
  644. rm -rf "/home/$user/$NewFilepath"
  645. fi
  646. mkdir -p "/home/$user/"$(dirname ${NewFilepath})
  647. cp -r "$CurrentFilepath" "/home/$user/$NewFilepath"
  648. chown -R "$user" "/home/$user/$NewFilepath"
  649.  
  650. done
  651. if [ $3 == "True" ]; then
  652. mkdir -p "/etc/skel/"$(dirname ${NewFilepath})
  653. cp -r "$CurrentFilepath" "/etc/skel/$NewFilepath"
  654. fi
  655. }
  656.  
  657. SudoMenu(){
  658. #Used to enable Sudo on pupil accounts
  659.  
  660. whiptail --title $"Accesso come amministratore" --yesno $"Vorresti che gli studenti avessero l'accesso al comando sudo?( Sudo equivalente all'esegui come amministratore dli windows) è abilitato di default in Raspbian, quindi disabilitarlo comporterebbe avere dei problemi con alcuni software. Abilitarlo potrebbe dare possibilità agli studenti di eludere le misure di sicurezza PiNet. Puoi cambiare idea più tardi nel submenu Gestisci Utenti." 13 78
  661. exitstatus=$?
  662. #
  663. #
  664. #
  665. #
  666.  
  667. #
  668. #
  669.  
  670. #
  671. #
  672.  
  673. #
  674. #
  675.  
  676. #
  677. # CANCELLAMI SONO ARRIVATO QUII! 20/4/2019
  678.  
  679. #
  680. #
  681.  
  682. #
  683. #
  684.  
  685. #
  686. #
  687.  
  688. #
  689. #
  690.  
  691. #
  692. #
  693.  
  694. #
  695. #
  696.  
  697.  
  698. rm -f /opt/ltsp/armhf/etc/sudoers.d/01pupil
  699. touch /opt/ltsp/armhf/etc/sudoers.d/01pupil
  700. chmod 440 /opt/ltsp/armhf/etc/sudoers.d/01pupil
  701. if [ $exitstatus = 0 ]; then
  702. echo '%pupil ALL=NOPASSWD: ALL' >> /opt/ltsp/armhf/etc/sudoers.d/01pupil
  703. fi
  704. echo '%pupil ALL = NOPASSWD: /sbin/shutdown' >> /opt/ltsp/armhf/etc/sudoers.d/01pupil
  705. echo '%pupil ALL = NOPASSWD: /sbin/reboot' >> /opt/ltsp/armhf/etc/sudoers.d/01pupil
  706. echo '%pupil ALL = NOPASSWD: /sbin/poweroff' >> /opt/ltsp/armhf/etc/sudoers.d/01pupil
  707. echo '%pupil ALL = NOPASSWD: /sbin/halt' >> /opt/ltsp/armhf/etc/sudoers.d/01pupil
  708. UpdateConfig NBDBuildNeeded true
  709. }
  710.  
  711.  
  712. fileSelect(){
  713. #Selects a folder using some BASH/Whiptail trickery
  714. results=$(whiptail --title $"Current location $(pwd)" --menu $"Select a folder. To select this folder, select ./ and to go up a folder, select ../ " 20 80 10 `for x in $(ls -pa | grep "/"); do echo $x "-"; done` 2>&1 >/dev/tty)
  715. exitstatus=$?
  716. if [ "$exitstatus" = "1" ]; then
  717. echo "The user canceled :( "
  718. return "1"
  719. else
  720. if [ "$results" = "./" ]; then
  721. location=$(pwd)
  722. echo $"chosen location is $location"
  723. else
  724. cd "$results"
  725. fileSelect
  726. fi
  727. fi
  728.  
  729. }
  730.  
  731. SingleFileSelect(){
  732. #Selects a folder using some BASH/Whiptail trickery
  733. results=$(whiptail --title $"Current location $(pwd)" --menu $"Select a folder. To select this folder, select ./ and to go up a folder, select ../ " 20 80 10 `echo "../ -"; for x in $(ls -p); do echo $x "-"; done` 2>&1 >/dev/tty)
  734. exitstatus=$?
  735. if [ "$exitstatus" = "1" ]; then
  736. echo "The user canceled :("
  737. return "1"
  738. else
  739. if [ -f "$results" ]; then
  740. location=$(pwd)/$results
  741. echo "$location"
  742. else
  743. cd "$results"
  744. SingleFileSelect
  745. fi
  746. fi
  747.  
  748. }
  749.  
  750. removeAnacronLines() {
  751. #Removes anacrontab lines which can cause issues. Used for backup scheduling
  752. sed --in-place '/PiNet.backup/d' /etc/anacrontab
  753. sed --in-place '/PiNet.backup/d' /etc/anacrontab
  754. sed --in-place '/PiNet.backup/d' /etc/anacrontab
  755.  
  756. }
  757.  
  758. createBackupScript(){
  759. #Adds the backup script to the system to auto backup user data
  760. rm -rf /usr/local/bin/pinet-backup.sh
  761.  
  762. echo '#!/bin/sh
  763. version=2
  764.  
  765. #PiNet backup utility script
  766.  
  767. ConfigFileLoc=/etc/pinet
  768. ConfigFileRead(){
  769. if egrep -q -v "^#|^[^ ]*=[^;]*" "$ConfigFileLoc"; then
  770. # filter the original to a new file
  771. egrep "^#|^[^ ]*=[^;&]*" "$ConfigFileLoc" > "$configfile_secured"
  772. ConfigFileLoc="$configfile_secured"
  773. source "$ConfigFileLoc"
  774. else
  775. source "$ConfigFileLoc"
  776. fi
  777. #echo config read
  778. }
  779.  
  780. ConfigFileRead
  781.  
  782. currentDate=`date +"%d-%m-%y"`
  783. currentTime=`date +"%H_%M"`
  784. if [ ! $backupLoc = "" ]; then
  785. LOCATION=$backupLoc
  786. if [ -d "$LOCATION" ]; then
  787. find "$LOCATION" -name "*PiNet-Users-Backup.tar.gz" -ctime +"$DELETETIME" | xargs rm -rf
  788. tar -zcvf "$LOCATION$currentDate--$currentTime--PiNet-Users-Backup.tar.gz" /home
  789. exitstatus=$?
  790. if [ $exitstatus = 0 ]; then
  791. logger -s "$currentDate $currentTime - Backup of users files was successful" 2>> /var/log/PiNet-backup.log
  792. else
  793. logger -s "$currentDate $currentTime - Backup failed with tar errorcode $exitstatus" 2>> /var/log/PiNet-backup.log
  794. fi
  795. else
  796. logger -s "$currentDate $currentTime - Backup folder unavailable!" 2>> /var/log/PiNet-backup.log
  797. fi
  798. else
  799. logger -s "$currentDate $currentTime - No backup location specified!" 2>> /var/log/PiNet-backup.log
  800. fi' >> /usr/local/bin/pinet-backup.sh
  801. chmod +x /usr/local/bin/pinet-backup.sh
  802. }
  803.  
  804. AddUsers(){
  805. #Add users to the system. Manually adds the user hash instead of using adduser
  806. username=$(whiptail --inputbox $"Enter new username" 8 78 $INIT --title $"Username" 3>&1 1>&2 2>&3)
  807. exitstatus=$?
  808. if [ "$exitstatus" = "0" ]; then
  809. password=$(whiptail --inputbox $"Enter new password" 8 78 $INIT --title $"Password" 3>&1 1>&2 2>&3)
  810. exitstatus=$?
  811. if [ "$exitstatus" = "0" ]; then
  812. egrep "^$username" /etc/passwd >/dev/null
  813. if [ $? -eq 0 ]; then
  814. whiptail --title "Error" --msgbox $"Username already exists!" 8 78
  815. else
  816. pass=$(perl -e 'print crypt($ARGV[0], "password")' $password)
  817. useradd -m -s /bin/bash -p $pass $username
  818. [ $? -eq 0 ] && echo $"$username has been added to system!" || echo $"Failed to add a user!"
  819. fixGroupsSingle $username
  820. whiptail --title $"Permission level" --yesno $"Is $username a pupil or a teacher? Teachers have a lot more permissions including write access to all shared folders, Epoptes teacher access and the ability to run PiNet control software." --yes-button $"Pupil" --no-button $"Teacher" 8 78 ############
  821. if [ ! $? -eq 0 ]; then
  822. AddUserToTeacher $username
  823. whiptail --title $"Success" --msgbox $"A new teacher user has been added to the system successfully with the name - $username" 8 78
  824. else
  825. whiptail --title $"Success" --msgbox $"A new student user has been added to the system successfully with the name - $username" 8 78
  826. fi
  827. fi
  828. whiptail --title $"Another user" --yesno $"Would you like to add another user?" 8 78
  829. if [ $? -eq 0 ]; then
  830. AddUsers
  831. fi
  832. fi
  833. fi
  834. }
  835.  
  836. RemoveUser(){
  837. #Removes user from list
  838. username=$(SelectUser "to remove.")
  839. if [ ! $username = 1 ]; then
  840. whiptail --title $"Are you sure?" --yesno $"Are you sure you want to delete $username and all $username's user files?" 8 78
  841. if [ $? -eq 0 ]; then
  842. userdel -rf $username
  843. whiptail --title $"Successful" --msgbox $"User successfully removed" 8 78
  844. fi
  845. fi
  846. whiptail --title $"Another user" --yesno $"Would you like to delete another user?" 8 78
  847. if [ $? -eq 0 ]; then
  848. RemoveUser
  849. fi
  850. }
  851.  
  852.  
  853. ChangeUserPassword(){
  854. #Change a users password
  855. username=$(SelectUser $"to change the password of.")
  856. if [ ! $username = 1 ]; then
  857. password=$(whiptail --inputbox $"Enter the new password" 8 78 $INIT --title $"Password" 3>&1 1>&2 2>&3)
  858. if ! [ "$password" = "" ]; then
  859. echo -e "$password\n$password" | passwd $username
  860. whiptail --title $"Successful" --msgbox $"Password successfully changed" 8 78
  861. else
  862. whiptail --title $"Error" --msgbox $"Password not valid" 8 78
  863. fi
  864. fi
  865. whiptail --title $"Another user" --yesno $"Would you like to change another users password?" 8 78
  866. if [ $? -eq 0 ]; then
  867. ChangeUserPassword
  868. fi
  869.  
  870.  
  871. }
  872.  
  873.  
  874. RestoreBackup() { #Currently incomplete
  875. whiptail --title $"Select backup" --msgbox $"Please select a backup file. They are normally the date, time followed by Raspi-Users-Backup.tar.gz" 8 78
  876.  
  877. }
  878.  
  879. SelectUser(){
  880. #Using some BASH/Whiptail magic, builds a list of users, formats it perfectly and hads it to whiptail
  881. users=$(cut -d: -f1,3 /etc/passwd | egrep ':[0-9]{4}$' | cut -d: -f1 | sort | awk -F':' '{ print $1"\na"}')
  882. user=$(whiptail --title $"Users" --menu $"Select a user $1" 16 78 5 $users --noitem 3>&1 1>&2 2>&3)
  883. if [ $? -eq 0 ]; then
  884. echo $user
  885. else
  886. echo 1
  887. fi
  888. }
  889.  
  890. TroubleShooter(){
  891. #PiNet troubleshooter - Needs some more answers built in
  892. whiptail --title $"Troubleshooter" --msgbox $"Welcome to PiNet troubleshooter. The troubleshooter goes over a few possible issues you may be having with your setup and offers advice. WARNING - This troubleshooter is experimental, feel free to open issue reports at $Repository/issues if you have any additional issues." 16 78
  893. whiptail --title $"Boot" --yesno $"Have you got as far as your Raspberry Pi starting up?" 8 78
  894. if [ $? -eq 0 ]; then
  895. whiptail --title $"Login screen" --yesno $"Have you got as far as the login screen displaying?" 8 78
  896. if [ $? -eq 0 ]; then
  897. whiptail --title $"Login screen" --yesno $"Are you having login issues?" 8 78
  898. if [ $? -eq 0 ]; then
  899. whiptail --title $"Login" --msgbox $"LDM (login screen) does not handle incorrect passwords very well. If you enter an incorrect set of credentials, it just restarts itself. Don't worry about this.
  900. If you are unsure about your password, remember you can easily change it in the Manage-users submenu" 16 78
  901. else
  902. whiptail --title $"USB drivers" --yesno $"Is your keyboard working?" 8 78
  903. if [ ! $? -eq 0 ]; then
  904. whiptail --title $"Kernel misaligned" --msgbox $"9/10 times, this means your kernels are misaligned. Basically there is a kernel on the SD card and as it boots and connects to the PiNet server, it loads the required additional modules (for stuff like USB) from the server. If the server has modules compiled for a more recent kernel, they are misaligned and don't work. To fix this, make sure you are running the most recent version of PiNet, also hit the update-sd option and reflash your SD card to see if that fixes it. If not, a patched set of boot files may not be available yet (they have to be prepared by hand). Best thing you can do is drop support an email and let them know that you are having keyboard/mouse issues. Visit http://pinet.org.uk/articles/support.html" 17 78
  905. else
  906. whiptail --title $"???" --msgbox $"I am not aware of any other issues in this area. Please create a support ticket at $Repository/issues" 8 78
  907. fi
  908. fi
  909. else
  910. resetAndCleanup
  911. whiptail --title $"Fixed?" --yesno $"Is it fixed now? I just reset some of the networking services." 8 78
  912. if [ ! $? -eq 0 ]; then
  913. whiptail --title $"Connection refused" --yesno $"Are you getting connection refused or connection timed out error?" 8 78
  914. if [ $? -eq 0 ]; then
  915. GetInternalIPAddress #Get the current main IP address
  916. whiptail --title $"Troubleshooter" --msgbox $"This is a common error, it occurs when the IP address of the server on the SD card is incorrect. Insert the SD card into a computer and open the cmdline.txt file. Find NBDRoot= (or NFSRoot=) and make sure the address that follows it is $IP If it isn't, change it so it is. If it is currently 1.1.1.1 the server was unable to get your current address when it created the SD card. If it is a different address, your server may have been assigned a new IP address. It would be a good idea to assign a static IP address to your server. Talk to your technician about this." 16 78
  917. else
  918. whiptail --title $"Giving up" --yesno $"Are you getting a number of 'giving up' errors?" 8 78
  919. if [ $? -eq 0 ]; then
  920. whiptail --title $"Giving up" --msgbox $"This usually means the Raspberry Pi isn't physically connected to the network, check the ethernet cable is correctly plugged in (wifi is not supported) and is connected to your main switch." 16 78
  921. else
  922. whiptail --title $"???" --msgbox $"I am not aware of any other issues in this area. Please create a support ticket at $Repository/issues" 8 78
  923. fi
  924. fi
  925. fi
  926. fi
  927. else
  928. whiptail --title $"SD card" --yesno $"Are you having issues with loading the files onto the SD card?" 8 78
  929. if [ $? -eq 0 ]; then
  930. whiptail --title $"Partitions" --yesno $"Are you having issues with there being 2-3 partitions on the SD card?" 8 78
  931. if [ $? -eq 0 ]; then
  932. whiptail --title $"Formating partitions" --msgbox $"When flashing Raspbian or another Raspberry Pi operating system onto SD cards, a number of partitions are created. PiNet only needs a single partition, the boot partition. This is usually a small (~50mb) partition which is formatted as fat32. If you wish to format the entire SD card (which if you are having issues, you may want to), please refer to the userguide section on formatting SD cards. " 16 78
  933. else
  934. whiptail --title $"???" --msgbox $"I am not aware of any other issues in this area. Please create a support ticket at $Repository/issues" 8 78
  935. fi
  936. else
  937. whiptail --title $"???" --msgbox $"I am not aware of any other issues in this area. Please create a support ticket at $Repository/issues" 8 78
  938. fi
  939. fi
  940. }
  941.  
  942.  
  943. DisplayUsers(){
  944. #Displays system users onto the terminal
  945. clear
  946. local TEACHER=$(cat /etc/group | grep --regex "^teacher:.*" | awk -F: '{print $4}')
  947. echo "-------------------"
  948. echo $"Current Linux users"
  949. echo "-------------------"
  950. cut -d: -f1,3 /etc/passwd | egrep ':[0-9]{4}$' | cut -d: -f1 | while IFS= read -r user
  951. do
  952. echo "$user"
  953. done
  954. echo "---------------"
  955. echo $"Current Linux users in the teacher group"
  956. echo "$TEACHER"
  957. echo "---------------"
  958. echo $"Press enter to continue"
  959. read
  960.  
  961. }
  962.  
  963. SetupSambaServer(){
  964. #Unused
  965. apt-get install samba libpam-smbpass -y
  966.  
  967.  
  968. }
  969.  
  970. SetupSambaPi(){
  971. #Unused
  972. mkdir /opt/ltsp/armhf/media/school-share
  973. ReplaceTextLine /opt/ltsp/armhf/etc/lts.conf FSTAB 'FSTAB_0="//server/School-Share /media/school-share cifs guest,uid=1000,iocharset=utf8 0 0"'
  974. echo "file:///media/school-share School-Share" >>/tmp/.gtk-bookmarks
  975. CopyToUsers /tmp/.gtk-bookmarks .gtk-bookmarks True False
  976. rm -rf /tmp/.gtk-bookmarks
  977.  
  978. }
  979.  
  980. AfterUpdate(){
  981. #Code run after a successful update on the BASH side, given that most update code is handled via Python
  982. ConfigFileRead
  983. whiptail --title $"Update complete" --msgbox $"The update succeeded. PiNet is now up to date on $ReleaseBranch." 8 78
  984. whiptail --title $"Update-all" --yesno $"After a software update it is recommended you do a system update. This will update all packages to their most recent version and add any new ones added in the update, do you want to?" 9 78
  985. exitstatus=$?
  986. if [ $exitstatus = 0 ]; then
  987. exec /bin/bash pinet Update-All
  988. exit
  989. else
  990. exec /bin/bash pinet
  991. exit
  992. fi
  993. }
  994.  
  995.  
  996. Updater(){
  997. #Main updater, most of it is handed by updatePiNet on the Python side or by AfterUpdate on BASH side
  998. $p updatePiNet
  999. exitstatus=$(gp)
  1000. if [ $exitstatus = 0 ] && [ "$1" = "IgnoreAfterUpdate" ]; then
  1001. if [ ! "$2" = "NoRestart" ]; then
  1002. whiptail --title $"Restarting PiNet" --msgbox $"Restarting PiNet to guarantee is running the correct branch version." 8 78
  1003. exec /bin/bash pinet
  1004. exit
  1005. fi
  1006.  
  1007. else
  1008. if [ $exitstatus = 0 ]; then
  1009. AfterUpdate
  1010. else
  1011. whiptail --title $"Update failed" --msgbox $"The auto update failed. This usually means you aren't connected to the internet" 8 78
  1012. exec /bin/bash pinet
  1013. fi
  1014. fi
  1015.  
  1016. }
  1017.  
  1018. VerifyPythonPackages(){
  1019. #Verify needed Python packages are installed. If not installed, install them.
  1020. $PythonStart -c 'import feedparser' 2>/dev/null || (sudo apt-get install -y python3-feedparser )
  1021. $PythonStart -c 'import requests' 2>/dev/null || (sudo apt-get install -y python3-requests )
  1022. $PythonStart -c 'import netifaces' 2>/dev/null || (sudo apt-get install -y python3-netifaces )
  1023. }
  1024.  
  1025.  
  1026. CheckReleases(){
  1027. #Checks if there is a new software release. Mainly uses CheckUpdate on Python side. Also runs sendStats.
  1028. $PythonStart -c 'import feedparser' 2>/dev/null || (sudo apt-get install -y python3-feedparser )
  1029. $PythonStart -c 'import requests' 2>/dev/null || (sudo apt-get install -y python3-requests )
  1030. $PythonStart -c 'import netifaces' 2>/dev/null || (sudo apt-get install -y python3-netifaces )
  1031. $p sendStats
  1032. $p CheckUpdate $version
  1033. exitstatus=$(gp)
  1034. #echo $exitstatus
  1035. if [ $exitstatus = 1 ]; then
  1036. AfterUpdate
  1037. fi
  1038.  
  1039. }
  1040.  
  1041. checkInstallLoc(){
  1042. #Checks PiNet is installed in the correct place (/usr/local/bin/pinet)
  1043. InstallLoc="${BASH_SOURCE[0]}"
  1044. if [ ! "$InstallLoc" = "/usr/local/bin/pinet" ]; then
  1045. mv $InstallLoc /usr/local/bin/pinet
  1046. exec /bin/bash pinet
  1047. fi
  1048. }
  1049.  
  1050. AddSambaUser(){
  1051. #Unused
  1052. whiptail --title "Samaba" --msgbox "Samba uses a seperate user system than Linux. It can though share users, but to add a new user to samba you must change your password. You can change it to the exact same thing as it was before and you only need to do this once." 10 78
  1053. whiptail --title "Samaba" --msgbox "Samba users will be able to edit the school-share folder available on all Raspberry Pis. It is not recommended to add students to this." 8 78
  1054. username=$(whiptail --inputbox "Enter the username to add to samaba" 8 78 $INIT --title "Username" 3>&1 1>&2 2>&3)
  1055. if [ $? -eq 0 ]; then
  1056. if ! [ "$username" = "" ]; then
  1057. egrep "^$username" /etc/passwd >/dev/null
  1058. if [ $? -eq 0 ]; then
  1059. smbpasswd -a "$username"
  1060. password=$(whiptail --inputbox "Please enter your password again, it must be correct!" 8 78 $INIT --title "Password" 3>&1 1>&2 2>&3)
  1061. if ! [ "$password" = "" ]; then
  1062. echo -e "$password\n$password" | passwd $username
  1063. whiptail --title "Successful" --msgbox "User added to Samba" 8 78
  1064. else
  1065. whiptail --title "Error" --msgbox "Password not valid" 8 78
  1066. fi
  1067. else
  1068. whiptail --title "Error" --msgbox "Username does not exist!" 8 78
  1069. fi
  1070. else
  1071. whiptail --title "Error" --msgbox "Username isn't valid" 8 78
  1072. fi
  1073. whiptail --title "Another user" --yesno "Would you like to add another Samaba user" 8 78
  1074. if [ $? -eq 0 ]; then
  1075. AddSambaUser
  1076. fi
  1077. fi
  1078.  
  1079. }
  1080.  
  1081.  
  1082. UpdateAll(){
  1083. #Does a full system update on the server and on the Raspberry Pi OS
  1084. checkInternet
  1085. if [ $? -eq 0 ]; then
  1086. apt-get update
  1087. apt-get upgrade -y
  1088. ltsp-chroot --arch armhf apt-get update
  1089. ltsp-chroot --arch armhf apt-get upgrade -y
  1090. AddSoftware
  1091. NBDRun
  1092. whiptail --title $"Update complete" --msgbox $"Updates are complete" 7 78
  1093. else
  1094. whiptail --title $"Error" --msgbox $"No internet connection, unable to update software..." 8 78
  1095. fi
  1096.  
  1097. }
  1098.  
  1099. SetupSharedStandalone() {
  1100. #Sets up shared folders. To use shared folders, extra line must be added to lts.conf file for Raspberry Pi
  1101. mkdir /home/shared > /dev/null 2>&1
  1102. sudo chown :teacher /home/shared
  1103. sudo chmod 775 /home/shared
  1104. ReplaceTextLine /opt/ltsp/armhf/etc/lts.conf LOCAL_APPS_EXTRAMOUNTS 'LOCAL_APPS_EXTRAMOUNTS=/home/shared'
  1105. DuplicateLTSConf
  1106.  
  1107. }
  1108.  
  1109. SetupShared(){
  1110. #User frontend for SetupSharedStandalone() for when it is not run directly
  1111. echo $"Setting up shared folders"
  1112. whiptail --title $"Setting up shared folders" --msgbox $"As this is the first time you are using shared folders, they must be configured. This may take a few minutes." 8 78
  1113. SetupSharedStandalone
  1114. NBDRun
  1115.  
  1116. }
  1117.  
  1118. CreateSharedFolder(){
  1119. #Create a new shared folder on the Raspberry Pis
  1120. mkdir /home/shared/$1
  1121. if [ ! $? -eq 0 ]; then
  1122. whiptail --title $"Error" --msgbox $"The shared folder at /home/shared/$1 could not be created. It may already exist." 8 78
  1123. return 1
  1124. else
  1125. chown root: /home/shared/$1
  1126. chmod 0700 /home/shared/$1
  1127. return 0
  1128. fi
  1129. }
  1130.  
  1131. RebuildGTKBookmarks(){
  1132. #Shared folders use GTK bookmarks to appear on the left hand side of the file manager, this rebuilds them for each edit (for example, when you create a new shared folder)
  1133. FILES=/home/shared/*
  1134. for f in $FILES
  1135. do
  1136. local FolderName=$(basename "$f")
  1137. echo "file://$f $FolderName" >> /tmp/.gtk-bookmarks
  1138. done
  1139. CopyToUsers /tmp/.gtk-bookmarks .gtk-bookmarks True False
  1140. rm -rf /tmp/.gtk-bookmarks
  1141. }
  1142.  
  1143. SelectSharedFolder(){
  1144. #Select a shared folder using some BASH/Whiptail magic
  1145. SFs=$(ls -1 /home/shared | awk -F':' '{ print $1"\na"}')
  1146. SF=$(whiptail --title "Shared-folders" --menu "Select a shared folder $1" 16 78 5 $SFs --noitem 3>&1 1>&2 2>&3)
  1147. if [ $? -eq 0 ]; then
  1148. echo $SF
  1149. else
  1150. echo 1
  1151. fi
  1152. }
  1153.  
  1154. CreateSharedFoldersDialog(){
  1155. #Main dialog for creating new shared folders. Checks if they are installed, if so, displays all current shared folders, then asks for name, then adds it as a bindfs mount for the Pis
  1156. whiptail --title $"Create shared folder" --yesno $"Shared folders are accessible on all the Raspberry Pis and appear on the left in the file manager. Would you like to add one?" 8 78
  1157. if [ $? -eq 0 ]; then
  1158. if [ ! -d /home/shared ]; then
  1159. SetupShared
  1160. fi
  1161. CheckSharedFolderIntegrity
  1162. clear
  1163. echo ""
  1164. echo "----------------------"
  1165. echo $"Current shared folders"
  1166. echo "----------------------"
  1167. echo ""
  1168. ls /home/shared -1
  1169. echo ""
  1170. echo $"Hit enter to continue"
  1171. read
  1172. FolderName=$(whiptail --inputbox $"Enter the name of the new shared folder" 8 78 --title $"Shared folder" 3>&1 1>&2 2>&3)
  1173. if [ $? -eq 0 ]; then
  1174. if ! [ "$FolderName" = "" ]; then
  1175. CreateSharedFolder "$FolderName"
  1176. if [ $? -eq 0 ]; then
  1177. whiptail --title $"Pupil write access" --yesno $"Should pupils have read/write access to this shared folder or just read access? (Default read only)" --yes-button $"Read" --no-button $"Read/Write" 8 78
  1178. if [ ! $? -eq 0 ]; then
  1179. ReplaceAnyTextOnLine /usr/local/bin/bindfs-mount "/home/shared/$FolderName" "bindfs -o perms=0775,force-group=pupil /home/shared/$FolderName /home/shared/$FolderName"
  1180. else
  1181. ReplaceAnyTextOnLine /usr/local/bin/bindfs-mount "/home/shared/$FolderName" "bindfs -o perms=0775,force-group=teacher /home/shared/$FolderName /home/shared/$FolderName"
  1182. fi
  1183. RebuildGTKBookmarks
  1184. service bindfs-mount restart
  1185. whiptail --title $"Complete" --msgbox $"The shared folder at /home/shared/$FolderName has been created! To access it reboot your Raspberry Pis." 8 78
  1186.  
  1187. fi
  1188. else
  1189. whiptail --title $"Error" --msgbox $"Folder name can not be blank!" 8 78
  1190. fi
  1191. fi
  1192. fi
  1193.  
  1194.  
  1195. }
  1196.  
  1197. RemoveSharedFolder(){
  1198. #Used to remove shared folders. Involves removing the GTK bookmark, then removing the bindfs mount. Finally the actual folder is deleted
  1199. whiptail --title $"Warning!" --yesno $"Warning! If you delete a shared folder, you must reboot all Raspberry Pis currently on as they may get confused. Would you like to continue?" 8 78
  1200. if [ $? -eq 0 ]; then
  1201. toDelete=$(SelectSharedFolder "to remove.")
  1202. if [ ! $toDelete = 1 ]; then
  1203. whiptail --title $"Are you sure?" --yesno $"Are you sure you want to permanently delete /home/shared/$toDelete ?" 8 78
  1204. if [ $? -eq 0 ]; then
  1205. RebuildGTKBookmarks
  1206. ReplaceAnyTextOnLine /usr/local/bin/bindfs-mount $"/home/shared/$toDelete" ""
  1207. if [ $? -eq 0 ]; then
  1208. service bindfs-mount restart
  1209. rm -rf "/home/shared/$toDelete"
  1210. whiptail --title $"Success" --msgbox $"The folder /home/shared/$toDelete has been successfully deleted." 8 78
  1211. else
  1212. service bindfs-mount restart
  1213. whiptail --title $"Error" --msgbox $"There was an issue removing the mount from /usr/local/bin/bindfs-mount... Please try again." 8 78
  1214. fi
  1215. fi
  1216. fi
  1217. fi
  1218. }
  1219.  
  1220. SharedFolderPerm(){
  1221. #Used to change permission level of a shared folder. Perhaps switch from pupil read only to pupil read/write
  1222.  
  1223. if [ "$1" = "" ]; then
  1224. FolderName=$(SelectSharedFolder "to edit.")
  1225. else
  1226. FolderName=$1
  1227. fi
  1228. if [ ! $FolderName = 1 ]; then
  1229. whiptail --title $"Pupil write access" --yesno $"Should $FolderName be Read/Write access for students or read only?" --yes-button $"Read" --no-button $"Read/Write" 8 78
  1230. if [ ! $? -eq 0 ]; then
  1231. ReplaceAnyTextOnLine /usr/local/bin/bindfs-mount "/home/shared/$FolderName" "bindfs -o perms=0775,force-group=pupil /home/shared/$FolderName /home/shared/$FolderName"
  1232. service bindfs-mount restart
  1233. whiptail --title $"Complete" --msgbox $"Permissions change complete, students now have read/write access in /home/shared/$FolderName" 8 78
  1234. else
  1235. ReplaceAnyTextOnLine /usr/local/bin/bindfs-mount "/home/shared/$FolderName" "bindfs -o perms=0775,force-group=teacher /home/shared/$FolderName /home/shared/$FolderName"
  1236. service bindfs-mount restart
  1237. whiptail --title $"Complete" --msgbox $"Permissions change complete, students now have read only access in /home/shared/$FolderName" 8 78
  1238. fi
  1239. fi
  1240. }
  1241.  
  1242. DisplaySharedFolders(){
  1243. #List all the shared folders in /home/shared
  1244. clear
  1245. echo ""
  1246. echo "----------------------"
  1247. echo $"Current shared folders"
  1248. echo "----------------------"
  1249. echo ""
  1250. ls /home/shared -1
  1251. echo ""
  1252. echo $"Hit enter to continue"
  1253. read
  1254. }
  1255.  
  1256.  
  1257. CheckSharedFolderIntegrity(){
  1258. #Checks the permissions and everything for shared folders lines up with that that is on the Raspberry Pis. If not, it will ask you to clarify what it should be
  1259. if [ ! -f /etc/init.d/bindfs-mount ]; then
  1260. service stop bindfs-mount > /dev/null 2>&1
  1261. addSharedFolderScript
  1262. fi
  1263. touch /usr/local/bin/bindfs-mount
  1264. inFile=$(grep "bindfs" /usr/local/bin/bindfs-mount | wc -l)
  1265. inFolder=$(ls -1 /home/shared | wc -l)
  1266. if [ ! "$inFile" = "$inFolder" ]; then
  1267. whiptail --title $"Invalid shared folder permissions" --msgbox $"Warning - Your shared folder permissions are invalid. This may be because you imported shared folders from a previous system. You must reselect the correct permission level for each folder now." 9 78
  1268. for i in 1 2 3 4 5 6 7 8 9 10
  1269. do
  1270. ReplaceAnyTextOnLine /usr/local/bin/bindfs-mount "/home/shared/" ""
  1271. done
  1272. sed -i '/^[[:blank:]]*$/d' /usr/local/bin/bindfs-mount
  1273.  
  1274. for f in $(ls -1 "/home/shared/")
  1275. do
  1276. SharedFolderPerm $f
  1277. chown :root "/home/shared/$f"
  1278. done
  1279. SetupShared
  1280. fi
  1281.  
  1282. }
  1283.  
  1284. addSharedFolderScript() {
  1285. #Adds the bindfs script which auto mounts the correct bind points and removes them when required (using stop)
  1286.  
  1287. rm -rf /etc/init.d/bindfs-mount
  1288.  
  1289. cat <<EOF1 >> /etc/init.d/bindfs-mount
  1290. #!/bin/bash
  1291. #Version=01
  1292. ### BEGIN INIT INFO
  1293. # Provides: Bindfs-mounts
  1294. # Required-Start: \$syslog \$remote_fs
  1295. # Required-Stop: \$syslog \$remote_fs
  1296. # Should-Start: \$local_fs
  1297. # Should-Stop: \$local_fs
  1298. # Default-Start: 2 3 4 5
  1299. # Default-Stop: 0 1 6
  1300. # Short-Description: Bindfs mounts for PiNet
  1301. # Description: The shared folder Bindfs mounts for PiNet
  1302. ### END INIT INFO
  1303.  
  1304. start() {
  1305. bash /usr/local/bin/bindfs-mount
  1306. }
  1307.  
  1308. stop() {
  1309. for i in \$(ls -1 /home/shared)
  1310. do
  1311. umount -l /home/shared/\$i > /dev/null 2>&1
  1312. done
  1313. }
  1314.  
  1315.  
  1316. restart() {
  1317. stop
  1318. start
  1319. }
  1320.  
  1321. case "\$1" in
  1322. start)
  1323. start
  1324. ;;
  1325. stop)
  1326. stop
  1327. ;;
  1328. restart)
  1329. restart
  1330. ;;
  1331. *)
  1332. echo "Usage: {start|stop|restart}"
  1333. exit 1
  1334. ;;
  1335. esac
  1336. exit
  1337.  
  1338. EOF1
  1339. chmod 755 /etc/init.d/bindfs-mount
  1340. update-rc.d bindfs-mount defaults
  1341. touch /usr/local/bin/bindfs-mount
  1342. service bindfs-mount restart > /dev/null 2>&1
  1343.  
  1344. }
  1345.  
  1346.  
  1347. CheckOS(){
  1348. #Check the correct operating system is being used. Ubuntu is recommended and Debian is no longer supported.
  1349. OS=$(lsb_release -si)
  1350. if [ ! $OS == "Ubuntu" ]; then
  1351. if [ $OS == "Debian" ]; then
  1352. whiptail --title $"WARNING!!" --msgbox $"Debian is no longer officially supported by PiNet! Please use Ubuntu 14.04 or later. Mileage may vary with Debian and PiNet..." 8 78
  1353. else
  1354. whiptail --title $"WARNING!!" --msgbox $"I don't recognise this operating system. Please use Ubuntu 14.04 or later. Mileage will vary greatly with other distributions and no support will be provided." 8 78
  1355. fi
  1356. fi
  1357. }
  1358.  
  1359. CheckTerminalSize(){
  1360. #Resizes the terminal to the correct size for the menus
  1361. eval `resize`
  1362. if [ "$LINES" -le "28" ]; then
  1363. a='\e[8;28;'
  1364. b='t'
  1365. printf "$a$COLUMNS$b"
  1366. fi
  1367. eval `resize`
  1368. if [ "$COLUMNS" -le "90" ]; then
  1369. a='\e[8;'
  1370. b=';90t'
  1371. printf "$a$LINES$b"
  1372. fi
  1373. sleep 0.5 # Time to allow the terminal to resize.
  1374. }
  1375.  
  1376. listStatus(){
  1377. #Displays a status of the PiNet. Includes a status of all logged in users
  1378.  
  1379. while true; do
  1380. dpkg-query -s epoptes > /dev/null 2>&1
  1381. if [ $? -eq 0 ]; then
  1382. local EPOPTES="True"
  1383. else
  1384. local EPOPTES="False"
  1385. fi
  1386. local TEACHER=$(cat /etc/group | grep --regex "^teacher:.*" | awk -F: '{print $4}')
  1387. local RAM=$(top -bn1 | awk '/Mem/ { mem = $5 / $3 * 100 }; END { print mem }')
  1388. local CPU=$(bc <<< "scale=0; $(top -bn 1 | awk '{print $9}' | tail -n +8 | awk '{s+=$1} END {print s}') / $(grep -c ^processor /proc/cpuinfo)")
  1389. clear
  1390.  
  1391. GetInternalIPAddress
  1392. echo " PiNet System Status"
  1393. echo "---------------------------------------------------"
  1394. echo "Current version - $version"
  1395. echo "Server IP address - $IP"
  1396. echo "---------------------------------------------------"
  1397. echo "Been running version $version since - $(stat -c %y /usr/local/bin/pinet | cut -d ' ' -f1)"
  1398. echo "Piboot folder last updated - $(stat -c %y /home/$SUDO_USER/PiBoot | cut -d ' ' -f1)"
  1399. echo "Last system-wide update (update-all) - $(stat -c %y /var/lib/apt/periodic/update-success-stamp | cut -d ' ' -f1)"
  1400. echo "----------------"
  1401. echo "Hard Drive Usage (may be inaccurate)"
  1402. echo "----------------"
  1403. echo "Total space - $(df -h | sed -n 2p | awk '{print $2}')"
  1404. echo "Used space - $(df -h | sed -n 2p | awk '{print $3}')"
  1405. echo "Free space - $(df -h | sed -n 2p | awk '{print $4}')"
  1406. echo "-----"
  1407. echo "Other"
  1408. echo "-----"
  1409. echo "CPU usage - $CPU%"
  1410. #echo "RAM usage - $(free -tom | grep 'Total:' | awk '{print $4}')MB / $(free -tom | grep 'Total:' | awk '{print $2}')MB"
  1411. echo "Epoptes installed - $EPOPTES"
  1412. echo "Teacher members - $TEACHER"
  1413. echo "-----------------------"
  1414. echo "Current active users"
  1415. echo "-----------------------"
  1416. netstat -tnpa | grep ESTABLISHED.*sshd | awk '{ print $5 " - " $8 } '
  1417. echo ""
  1418. echo "Hit enter to return to the main menu"
  1419. read -t 2
  1420. if [ $? -eq 0 ]; then
  1421. break
  1422. fi
  1423. done
  1424.  
  1425. }
  1426.  
  1427. CheckDesktopShortcut(){
  1428. #Checks if the PiNet desktop shortcut exists. If not it adds it
  1429. checkInternet
  1430. if [ $? -eq 0 ]; then
  1431. AddDesktopShortcutToUser $SUDO_USER
  1432.  
  1433. if [ ! -f "/usr/share/pixmaps/pinet-icon.png" ] || [ ! -f "/opt/ltsp/armhf/usr/share/pixmaps/pinet-icon.png" ]; then
  1434. wget $RawRepository/$ReleaseBranch/images/pinet-icon.png -O /tmp/pinet-icon.png
  1435. cp /tmp/pinet-icon.png /usr/share/pixmaps/pinet-icon.png
  1436. cp /tmp/pinet-icon.png /opt/ltsp/armhf/usr/share/pixmaps/pinet-icon.png
  1437. UpdateConfig NBDBuildNeeded true
  1438. fi
  1439.  
  1440. fi
  1441. }
  1442.  
  1443. AddDesktopShortcutToUser() {
  1444. #Adds desltop shortcut for PiNet if needed
  1445.  
  1446. if [ ! -f "/home/$1/Desktop/pinet.desktop" ]; then
  1447. cat <<EOF1 >> /home/$1/Desktop/pinet.desktop
  1448. [Desktop Entry]
  1449. Version=3.0
  1450. Name=PiNet
  1451. Comment=PiNet Control Panel
  1452. Exec=sudo bash pinet
  1453. Icon=/usr/share/pixmaps/pinet-icon.png
  1454. Terminal=true
  1455. Type=Application
  1456. Categories=Utility;Application;
  1457. EOF1
  1458. chmod +x "/home/$1/Desktop/pinet.desktop"
  1459. chown "$1" "/home/$1/Desktop/pinet.desktop"
  1460. fi
  1461.  
  1462. if [ ! -f "/opt/ltsp/armhf/usr/local/bin/pinet" ]; then
  1463. echo "ltsp-remoteapps gnome-terminal -x sh -c 'sudo bash pinet'" > /opt/ltsp/armhf/usr/local/bin/pinet
  1464. UpdateConfig NBDBuildNeeded true
  1465. fi
  1466.  
  1467. }
  1468.  
  1469.  
  1470. teacherSudoCheck() {
  1471. #Checks if teachers have auto sudo (as in, no password asked each time). If not, it enables it (but requires a log out and in again to apply)
  1472. if [ ! -f "/etc/sudoers.d/01staff" ]; then
  1473. rm -f /etc/sudoers.d/01staff
  1474. touch /etc/sudoers.d/01staff
  1475. chmod 440 /etc/sudoers.d/01staff
  1476. echo '%teacher ALL=NOPASSWD: ALL' >> /etc/sudoers.d/01staff
  1477. fi
  1478. }
  1479.  
  1480.  
  1481. resetAndCleanup(){
  1482. #Resets the NBD server. Can sometimes help fix weird issues.
  1483. service nfs-kernel-server restart
  1484. sudo DEBIAN_FRONTEND=noninteractive dpkg-reconfigure nbd-server
  1485. sudo service nbd-server restart
  1486.  
  1487. }
  1488.  
  1489. AddPasswordReset(){
  1490. #Adds the password reset utility to the desktop of new users
  1491. wget $RawRepository/$ReleaseBranch/Scripts/changePassword.sh -O /tmp/changePassword.sh
  1492. wget $RawRepository/$ReleaseBranch/images/pinet-change-password.png -O /tmp/pinet-change-password.png
  1493. cp /tmp/pinet-change-password.png /opt/ltsp/armhf/usr/share/pixmaps/pinet-change-password.png
  1494. cp /tmp/changePassword.sh /usr/local/bin/changePassword.sh
  1495. cut -d: -f1,3 /etc/passwd | egrep ':[0-9]{4}$' | cut -d: -f1 | while IFS= read -r user
  1496. do
  1497. AddPasswordResetDesktop $user
  1498. done
  1499.  
  1500. if [ ! -f "/etc/skel/Desktop/pinet-password.desktop" ]; then
  1501. cat <<EOF1 >> /etc/skel/Desktop/pinet-password.desktop
  1502. [Desktop Entry]
  1503. Version=1.1
  1504. Name=Change Password
  1505. Comment=Change password
  1506. Exec=ltsp-remoteapps bash changePassword.sh
  1507. Icon=/usr/share/pixmaps/pinet-change-password.png
  1508. Terminal=false
  1509. Type=Application
  1510. Categories=Utility;Application;
  1511.  
  1512. EOF1
  1513. fi
  1514.  
  1515. }
  1516.  
  1517. AddPasswordResetDesktop(){
  1518. #Adds the password reset utility to the desktop of existing users with help of AddPasswordReset
  1519. if [ ! -f "/home/$1/Desktop/pinet-password.desktop" ]; then
  1520. cat <<EOF1 >> /home/$1/Desktop/pinet-password.desktop
  1521. [Desktop Entry]
  1522. Version=1.1
  1523. Name=Change Password
  1524. Comment=Change password
  1525. Exec=ltsp-remoteapps bash changePassword.sh
  1526. Icon=/usr/share/pixmaps/pinet-change-password.png
  1527. Terminal=false
  1528. Type=Application
  1529. Categories=Utility;Application;
  1530.  
  1531. EOF1
  1532. chown "$1" "/home/$1/Desktop/pinet-password.desktop"
  1533. fi
  1534.  
  1535. }
  1536.  
  1537. AddScreenshot(){
  1538. #Adds the screenshot utility to the desktop of new users
  1539. wget $RawRepository/$ReleaseBranch/Scripts/pinet-screenshot.sh -O /tmp/pinet-screenshot.sh
  1540. wget $RawRepository/$ReleaseBranch/images/pinet-screenshot.png -O /tmp/pinet-screenshot.png
  1541. cp /tmp/pinet-screenshot.png /opt/ltsp/armhf/usr/share/pixmaps/pinet-screenshot.png
  1542. cp /tmp/pinet-screenshot.sh /opt/ltsp/armhf/usr/local/bin/pinet-screenshot.sh
  1543. chmod +x /opt/ltsp/armhf/usr/local/bin/pinet-screenshot.sh
  1544. cut -d: -f1,3 /etc/passwd | egrep ':[0-9]{4}$' | cut -d: -f1 | while IFS= read -r user
  1545. do
  1546. AddScreenshotDesktop $user
  1547. done
  1548.  
  1549. if [ ! -f "/etc/skel/Desktop/pinet-screenshot.desktop" ]; then
  1550. cat <<EOF1 >> /etc/skel/Desktop/pinet-screenshot.desktop
  1551. [Desktop Entry]
  1552. Version=1.0
  1553. Name=Take Screenshot
  1554. Comment=Take Screenshot
  1555. Exec=bash pinet-screenshot.sh
  1556. Icon=/usr/share/pixmaps/pinet-screenshot.png
  1557. Terminal=false
  1558. Type=Application
  1559. Categories=Utility;Application;
  1560.  
  1561. EOF1
  1562. fi
  1563.  
  1564. }
  1565.  
  1566. AddScreenshotDesktop(){
  1567. #Adds the screenshot utility to the desktop of existing users with help of AddScreenshot
  1568. if [ ! -f "/home/$1/Desktop/pinet-screenshot.desktop" ]; then
  1569. cat <<EOF1 >> /home/$1/Desktop/pinet-screenshot.desktop
  1570. [Desktop Entry]
  1571. Version=1.0
  1572. Name=Take Screenshot
  1573. Comment=Take Screenshot
  1574. Exec=bash pinet-screenshot.sh
  1575. Icon=/usr/share/pixmaps/pinet-screenshot.png
  1576. Terminal=false
  1577. Type=Application
  1578. Categories=Utility;Application;
  1579.  
  1580. EOF1
  1581. chown "$1" "/home/$1/Desktop/pinet-screenshot.desktop"
  1582. fi
  1583.  
  1584.  
  1585. }
  1586.  
  1587. CreateMoveBackup() {
  1588. #Create a full backup of all users and groups data for moving to a clean system
  1589. whiptail --title $"Warning" --yesno $"This process is only designed to move user files to a completely fresh Ubuntu install in which PiNet is not installed. Please make sure to verify all user data is imported correctly on the new PiNet server. Visit http://PiNet.org.uk/manage-users/migration.html for full instructions. Are you sure you want to proceed?" 11 78
  1590. if [ $? -eq 0 ]; then
  1591. mkdir /root/move/
  1592. export UGIDLIMIT=1000
  1593. awk -v LIMIT=$UGIDLIMIT -F: '($3>=LIMIT) && ($3!=65534)' /etc/passwd > /root/move/passwd.mig
  1594. awk -v LIMIT=$UGIDLIMIT -F: '($3>=LIMIT) && ($3!=65534)' /etc/group > /root/move/group.mig
  1595. awk -v LIMIT=$UGIDLIMIT -F: '($3>=LIMIT) && ($3!=65534) {print $1}' /etc/passwd | tee - |egrep -f - /etc/shadow > /root/move/shadow.mig
  1596. cp /etc/gshadow /root/move/gshadow.mig
  1597. rm /home/$SUDO_USER/toMove.tar.gz # Remove previous toMove.tar.gz file in case is already one there.
  1598. tar -zcvpf /root/move/home.tar.gz /home
  1599. tar -zcvpf /home/$SUDO_USER/toMove.tar.gz /root/move
  1600. chown $SUDO_USER /home/$SUDO_USER/toMove.tar.gz
  1601. rm -rf /root/move/
  1602. whiptail --title $"Complete" --msgbox $"The process is now complete. A zipped file called toMove.tar.gz has been saved in /home/$SUDO_USER/toMove.tar.gz. Please copy this to /home/youruser/toMove.tar.gz on the new server (via a pendrive for example) then run PiNet and select yes when asked about importing users." 11 78
  1603. fi
  1604. }
  1605.  
  1606. CheckRestoreMoveBackup(){
  1607. #Checks if LTSP is already installed as importing user data with a server already running PiNet can cause issues..
  1608. if [ -f /home/$SUDO_USER/toMove.tar.gz ]; then
  1609. if [ -d /opt/ltsp ]; then
  1610. whiptail --title $"WARNING!!" --yesno $"PiNet may already be installed! It is highly recommended against importing users with a previous PiNet install. You have been warned! Would you like to import them anyway?" 10 78
  1611. if [ $? -eq 0 ]; then
  1612. RestoreMoveBackup
  1613. fi
  1614. else
  1615. RestoreMoveBackup
  1616. fi
  1617.  
  1618. else
  1619.  
  1620. whiptail --title $"Error" --msgbox $"The zipped file of user data can't be found at /home/$SUDO_USER/toMove.tar.gz." 8 78
  1621. fi
  1622. }
  1623.  
  1624. RestoreMoveBackup() {
  1625. #Restore full backup of all users and group data
  1626. whiptail --title $"Warning" --yesno $"Importing should only be performed on a completely fresh Ubuntu install. PiNet or Raspi-LTSP must not already be installed. Make sure to manually check all files have copied correctly. Do you want to proceed?" 10 78
  1627. if [ $? -eq 0 ]; then
  1628. if [ -f /home/$SUDO_USER/toMove.tar.gz ]; then
  1629. $p importMigration "/home/$SUDO_USER/toMove.tar.gz"
  1630. UpdateConfig "ImportedUsers" "true"
  1631. return 0
  1632. else
  1633. whiptail --title $"Import failed" --yesno $"The user import has failed, /home/$SUDO_USER/toMove.tar.gz wasn't found? Are you sure you copied it to that location? Would you like to try again?" 9 78
  1634. if [ $? -eq 0 ]; then
  1635. RestoreMoveBackup
  1636. else
  1637. exit
  1638. fi
  1639. fi
  1640. else
  1641. exit
  1642. fi
  1643.  
  1644. }
  1645.  
  1646. InstallScratchGPIO(){
  1647. #Installs ScratchGPIO 5 by manually pushing an install script to each user
  1648. whiptail --title $"Note" --msgbox $"ScratchGPIO can't be directly installed, each user must install it. A desktop shortcut has been added to each user account called \"Install ScratchGPIO\". Get each student to run this the first time they want to use the software." 10 78
  1649. rm -rf /tmp/isgh7.sh
  1650. rm -rf /opt/ltsp/armhf/usr/local/bin/isgh5.sh
  1651. rm -rf /opt/ltsp/armhf/usr/local/bin/scratchSudo.sh
  1652. rm -rf /opt/ltsp/armhf/usr/local/bin/isgh7.sh
  1653. wget http://bit.ly/1wxrqdp -O /tmp/isgh7.sh
  1654. cp /tmp/isgh7.sh /opt/ltsp/armhf/usr/local/bin/isgh7.sh
  1655. echo "bash /usr/local/bin/isgh7.sh \$SUDO_USER" > /opt/ltsp/armhf/usr/local/bin/scratchSudo.sh
  1656. cut -d: -f1,3 /etc/passwd | egrep ':[0-9]{4}$' | cut -d: -f1 | while IFS= read -r user
  1657. do
  1658. if [ ! -f "/home/$user/Desktop/Install-scratchGPIO.desktop" ]; then
  1659. cat <<EOF1 > /home/$user/Desktop/Install-scratchGPIO.desktop
  1660. [Desktop Entry]
  1661. Version=1.0
  1662. Name=Install ScratchGPIO
  1663. Comment=Install ScratchGPIO
  1664. Exec=sudo bash /usr/local/bin/scratchSudo.sh
  1665. Icon=scratch
  1666. Terminal=true
  1667. Type=Application
  1668. Categories=Utility;Application;
  1669.  
  1670. EOF1
  1671. chown "$user" "/home/$user/Desktop/Install-scratchGPIO.desktop"
  1672. fi
  1673. done
  1674.  
  1675. if [ ! -f " /etc/skel/Desktop/Install-scratchGPIO.desktop" ]; then
  1676. cat <<EOF1 > /etc/skel/Desktop/Install-scratchGPIO.desktop
  1677. [Desktop Entry]
  1678. Version=1.0
  1679. Name=Install ScratchGPIO
  1680. Comment=Install ScratchGPIO
  1681. Exec=sudo bash /usr/local/bin/scratchSudo.sh
  1682. Icon=scratch
  1683. Terminal=true
  1684. Type=Application
  1685. Categories=Utility;Application;
  1686. EOF1
  1687. fi
  1688.  
  1689.  
  1690.  
  1691. }
  1692.  
  1693. FirstTimeImportUsers(){
  1694. #Asks user if they want to import users on the first startup of PiNet
  1695. if [ ! -f /home/$SUDO_USER/Desktop/lxterminal.desktop ]; then
  1696. whiptail --title $"Importing users" --defaultno --yesno $"Would you like to import user data from a previous PiNet (or Raspi-LTSP) server? This can only be done now on installation. If in doubt, select no." 8 78
  1697. if [ $? -eq 0 ]; then
  1698. RestoreMoveBackup
  1699. fi
  1700. fi
  1701. }
  1702.  
  1703. DisableI2C_SPI(){
  1704. #Disables both I2C and SPI to allow the pins to be used as general purpose IO
  1705. if [ ! -f /opt/ltsp/armhf/etc/modprobe.d/raspi-blacklist.conf ]; then
  1706. echo "blacklist spi-bcm2708
  1707. blacklist i2c-bcm2708 " > /opt/ltsp/armhf/etc/modprobe.d/raspi-blacklist.conf
  1708. UpdateConfig NBDBuildNeeded true
  1709. fi
  1710. }
  1711.  
  1712. DisableSPI(){
  1713. #Disables SPI (and enables I2C) to allow the SPI pins to be used as general purpose IO
  1714. echo "blacklist spi-bcm2708" > /opt/ltsp/armhf/etc/modprobe.d/raspi-blacklist.conf
  1715. UpdateConfig NBDBuildNeeded true
  1716. }
  1717.  
  1718. InstallBlueJ(){
  1719. #Install BlueJ java IDE. Part of AddSoftware
  1720. rm -rf /tmp/bluej-314a.deb
  1721. rm -rf /opt/ltsp/armhf/tmp/bluej-314a.deb
  1722. wget http://bluej.org/download/files/bluej-314a.deb -O /tmp/bluej-314a.deb
  1723. cp /tmp/bluej-314a.deb /opt/ltsp/armhf/tmp/bluej-314a.deb
  1724. ltsp-chroot --arch armhf dpkg -i /tmp/bluej-314a.deb
  1725. }
  1726.  
  1727. checkPythonFunctionsInstalled(){
  1728. #Checks the vital Python functions file is installed on the system. If not, it goes and downloads it from the web
  1729. if [ ! -f $PythonFunctions ]; then
  1730. wget $RawRepository/$ReleaseBranch/Scripts/pinet_functions_python.py -O $PythonFunctions
  1731. if [ ! $? -eq 0 ]; then
  1732. whiptail --title $"Error!" --msgbox $"I am sorry, there has been a critical error with pinet. A required library file could not be acquired. PiNet is unable to function without this library. This may be because you are not connected to the internet or there may be another problem. Please manually download the file from http://bit.ly/pinet-fn and copy it to $PythonFunctions. If the issue persists, please contact support at http://PiNet.org.uk/support.html" 16 78
  1733. rm -rf $PythonFunctions
  1734. exit
  1735. fi
  1736. fi
  1737.  
  1738. }
  1739.  
  1740. checkKernelFileUpdateWeb(){
  1741. #Checks the web to see if the SD cards need updated with new kernel files
  1742. $p checkKernelFileUpdateWeb
  1743. KernelV=$(gp)
  1744. if [ $KernelV = "1" ]; then
  1745. current=$(head -n 1 /home/$SUDO_USER/PiBoot/version.txt)
  1746. newVersion=$(head -n 1 /tmp/kernelVersion.txt)
  1747. whiptail --title $"Kernel file update" --yesno $"An important update is available for the Raspberry Pi kernel files (files on the SD cards). If you upgrade, PiNet will attempt to load these new files onto your SD cards on boot up. This update is highly recommended. You currently are using version $current and the most up to date version is $newVersion. Would you like to proceed with an automatic update of the boot files and your server?" 12 78
  1748. if [ $? -eq 0 ]; then
  1749. whiptail --title $"Auto reboot" --msgbox $"Your Raspberry Pis will attempt to auto update their SD cards (by grabbing the version from the server) on next reboot. They will do this in the background and reboot when the update is complete **without warning**." 9 78
  1750. installKernelUpdater ""
  1751. UpdateSD
  1752. UpdateAll
  1753. fi
  1754. fi
  1755.  
  1756.  
  1757. }
  1758.  
  1759. checkKernelUpdater(){
  1760. #Runs the installKernelUpdater
  1761. installKernelUpdater $1
  1762.  
  1763. }
  1764.  
  1765. installKernelUpdater(){
  1766. #Downloads new kernel files if required
  1767. local compress=$1
  1768. $p checkKernelUpdater
  1769. exitstatus=$(gp)
  1770. if [ "$exitstatus" = "1" ]; then
  1771. if [ "$compress" = "NBD" ]; then
  1772. echo "----------------------------------------------------------------------------------------------"
  1773. echo $"An update for the kernel update program has been detected, this will be applied automatically"
  1774. echo "----------------------------------------------------------------------------------------------"
  1775. NBDRun
  1776. fi
  1777. fi
  1778.  
  1779. }
  1780.  
  1781. CheckRaspberryPiUIMods(){
  1782.  
  1783. if [ ! -f "/opt/ltsp/armhf/etc/xdg/pcmanfm/LXDE-pi/desktop-items-0.conf" ]; then
  1784. InstallRaspberryPiUIMods
  1785. UpdateConfig NBDBuildNeeded true
  1786. return
  1787. fi
  1788.  
  1789.  
  1790. $p checkIfFileContainsString "/opt/ltsp/armhf/etc/xdg/pcmanfm/LXDE-pi/pcmanfm.conf" "raspberrypi-artwork"
  1791. exitstatus=$(gp)
  1792. if [ "$exitstatus" = "1" ]; then
  1793. InstallRaspberryPiUIMods
  1794. UpdateConfig NBDBuildNeeded true
  1795. else
  1796. $p checkIfFileContainsString "/opt/ltsp/armhf/etc/xdg/pcmanfm/LXDE-pi/desktop-items-0.conf" "raspberrypi-artwork"
  1797. exitstatus=$(gp)
  1798. if [ "$exitstatus" = "1" ]; then
  1799. InstallRaspberryPiUIMods
  1800. UpdateConfig NBDBuildNeeded true
  1801. fi
  1802. fi
  1803.  
  1804. }
  1805.  
  1806. FixUIConfigFile(){
  1807. if [ $1 == "System" ]; then
  1808. $p replaceLineOrAdd /opt/ltsp/armhf/etc/xdg/pcmanfm/LXDE-pi/$2 wallpaper_mode= wallpaper_mode=stretch
  1809. $p replaceLineOrAdd /opt/ltsp/armhf/etc/xdg/pcmanfm/LXDE-pi/$2 wallpaper= wallpaper=/etc/alternatives/desktop-background
  1810. $p replaceLineOrAdd /opt/ltsp/armhf/etc/xdg/pcmanfm/LXDE-pi/$2 side_pane_mode= side_pane_mode=1
  1811. $p replaceLineOrAdd /opt/ltsp/armhf/etc/xdg/pcmanfm/LXDE-pi/$2 desktop_shadow= desktop_shadow=#000000
  1812. $p replaceLineOrAdd /opt/ltsp/armhf/etc/xdg/pcmanfm/LXDE-pi/$2 desktop_fg= desktop_fg=#ffffff
  1813. else
  1814. $p replaceLineOrAdd /home/$3/.config/pcmanfm/LXDE-pi/$2 wallpaper_mode= wallpaper_mode=stretch
  1815. $p replaceLineOrAdd /home/$3/.config/pcmanfm/LXDE-pi/$2 wallpaper= wallpaper=/etc/alternatives/desktop-background
  1816. $p replaceLineOrAdd /home/$3/.config/pcmanfm/LXDE-pi/$2 side_pane_mode= side_pane_mode=1
  1817. $p replaceLineOrAdd /home/$3/.config/pcmanfm/LXDE-pi/$2 desktop_shadow= desktop_shadow=#000000
  1818. $p replaceLineOrAdd /home/$3/.config/pcmanfm/LXDE-pi/$2 desktop_fg= desktop_fg=#ffffff
  1819. fi
  1820. }
  1821.  
  1822. CheckRaspberryPiUIModsAllUsers(){
  1823. cut -d: -f1,3 /etc/passwd | egrep ':[0-9]{4}$' | cut -d: -f1 | while IFS= read -r user #Gets all users
  1824. do
  1825. if [ -f "/home/$user/.config/pcmanfm/LXDE-pi/desktop-items-0.conf" ]; then
  1826. FixUIConfigFile "User" "pcmanfm.conf" $user
  1827. FixUIConfigFile "User" "desktop-items-0.conf" $user
  1828.  
  1829. #$p replaceLineOrAdd /home/$user/.config/pcmanfm/LXDE-pi/desktop-items-0.conf wallpaper_mode= wallpaper_mode=stretch
  1830. #$p replaceLineOrAdd /home/$user/.config/pcmanfm/LXDE-pi/desktop-items-0.conf wallpaper= wallpaper=/etc/alternatives/desktop-background
  1831. #$p replaceLineOrAdd /home/$user/.config/pcmanfm/LXDE-pi/desktop-items-0.conf side_pane_mode= side_pane_mode=1
  1832. fi
  1833. done
  1834. $p resetThemeCacheForAllUsers
  1835. }
  1836.  
  1837. InstallRaspberryPiUIMods(){
  1838. #Fixes the mistakes made in the wallpaper setting of RaspberryPi-UI-Mods
  1839. #ltsp-chroot apt-get update
  1840. #ltsp-chroot apt-get -o Dpkg::Options::="--force-confnew" install -y raspberrypi-ui-mods
  1841. FixUIConfigFile "System" "pcmanfm.conf"
  1842. FixUIConfigFile "System" "desktop-items-0.conf"
  1843. CheckRaspberryPiUIModsAllUsers
  1844. }
  1845.  
  1846. ChooseReleaseChannelOld(){
  1847. whiptail --title $"Release channels" --yesno --yes-button $"Stable" --no-button $"Development" $"Would you like to use the stable or development (dev) software update channels? Stable is recommended. Do not use the development (dev) channels in a production environment (for example a school) as stability is not guaranteed. " 10 78
  1848. if [ $? -eq 0 ]; then
  1849. UpdateConfig ReleaseChannel "Stable"
  1850. else
  1851. UpdateConfig ReleaseChannel "Dev"
  1852. fi
  1853. SetupRepositories
  1854. if [ $1 = "Restart" ]; then
  1855. exec /bin/bash pinet
  1856. exit
  1857. fi
  1858. }
  1859.  
  1860. ChooseReleaseChannel(){
  1861. # Select a release channel (branch) for PiNet to use for software updates etc.
  1862. $p "selectReleaseChannel"
  1863. exitstatus=$(gp)
  1864. SetupRepositories
  1865. if [ $1 = "Restart" ]; then
  1866. if [ "$exitstatus" = "1" ]; then
  1867. # Invalidate previous package version caches to force them to be redownloaded
  1868. rm "/opt/PiNet/pinet-package-versions.txt"
  1869. rm "/opt/PiNet/PiBootBackup/apt_version.txt"
  1870.  
  1871. # If the release channel has changed, restart PiNet software to check for updates etc
  1872. Updater
  1873. else
  1874. Menu
  1875. fi
  1876. else
  1877. Updater "IgnoreAfterUpdate" "$1"
  1878. fi
  1879.  
  1880. }
  1881. GroupCheck(){
  1882. #Checks if all users permissions are correct in groups. Front end for fixGroups
  1883. whiptail --title $"Groupcheck" --msgbox $"Group-check goes through each user account checking it is assigned the correct groups. It also resets UI configuration. It can take a number of minutes if you have a large amount of users." 9 78
  1884. fixGroups
  1885. CheckRaspberryPiUIModsAllUsers
  1886. whiptail --title $"Complete" --msgbox $"All user groups have been checked and if need be, corrected." 8 78
  1887. }
  1888.  
  1889. CheckForRaspiLTSP(){
  1890. #Checks if Raspi-LTSP is installed and warns the user if it is.
  1891. if [ -f /etc/raspi-ltsp ]; then
  1892. whiptail --title $"Raspi-LTSP found!" --msgbox $"A previous Raspi-LTSP installation has been found! PiNet and Raspi-LTSP can not be installed at the same time! Please reinstall Ubuntu then run PiNet." 9 78
  1893. echo $"Raspi-LTSP configuration file found at /etc/raspi-ltsp"
  1894. exit
  1895. else
  1896. if [ -d /opt/raspiLTSP ]; then
  1897. whiptail --title $"Raspi-LTSP found!" --msgbox $"A previous Raspi-LTSP installation has been found! PiNet and Raspi-LTSP can not be installed at the same time! Please reinstall Ubuntu then run PiNet." 9 78
  1898. echo $"Raspi-LTSP configuration folder found at /opt/raspiLTSP"
  1899. exit
  1900. fi
  1901. fi
  1902. }
  1903.  
  1904.  
  1905. ImportUsersFromCSV(){
  1906. whiptail --title $"Import from CSV" --yesno $"PiNet supports importing users from a CSV file. Many user management systems can export a CSV file with usernames and passwords (or just usernames). The required format is 1st column is username and 2nd coloum is password. If the password column is left blank, a default password you select will be used. Would you like to continue?" 11 78
  1907. if [ $? -eq 0 ]; then
  1908. whiptail --title $"Select CSV" --msgbox $"Please now select your CSV file." 9 78
  1909. cd /home/$SUDO_USER
  1910. local fileLoc=$(SingleFileSelect)
  1911. if [ ! fileLoc = "The user canceled :(" ]; then
  1912. password=$(whiptail --inputbox $"Enter a default password to use if am unable to find one." 8 78 --title $"Password" 3>&1 1>&2 2>&3)
  1913. if [ password = "" ]; then
  1914. whiptail --title $"Error" --msgbox $"Default password box can't be left blank!" 9 78
  1915. else
  1916. $p importFromCSV $fileLoc $password
  1917. fi
  1918. fi
  1919. fi
  1920. }
  1921.  
  1922. DeleteUsersFromCSV(){
  1923. whiptail --title $"Delete from CSV" --yesno $"PiNet supports batch deleting users from a CSV file. The required format is 1st column is username. All other colums are ignored. Would you like to continue?" 11 78
  1924. if [ $? -eq 0 ]; then
  1925. whiptail --title $"Select CSV" --msgbox $"Please now select your CSV file." 9 78
  1926. cd /home/$SUDO_USER
  1927. fileLoc=$(SingleFileSelect)
  1928. if [ ! fileLoc = "The user canceled :(" ]; then
  1929. $p usersCSVDelete $fileLoc False
  1930. fi
  1931. fi
  1932. }
  1933.  
  1934. CheckInstallSuccess(){
  1935. if [ -d "/opt/ltsp/armhf/debootstrap" ]; then
  1936. whiptail --title $"Installation error" --msgbox $"An issue with your PiNet installation has been detected! The Raspbian operating system is missing or failed to install correctly. This most commonly is caused by school internet filters blocking software repositories or the internet connection failing in the middle of installation. At this stage it is highly recommended attempting a full (including Ubuntu) reinstall with if possible, a different internet connection. If that fails, contact support http://pinet.org.uk/articles/support.html" 14 78
  1937. echo $"You may wish to check the PiNet logs to help diagnose the issue. They can be found at /var/log/pinet.log."
  1938. exit
  1939.  
  1940. else
  1941. $p verifyChrootIntegrity
  1942. fi
  1943. }
  1944.  
  1945. CreatePartitionTable() {
  1946. #Directly borrowed from Spindle - https://github.com/asb/spindle/blob/master/wheezy-stage0
  1947. sudo parted $1 <<EOF
  1948. unit b
  1949. mklabel msdos
  1950. mkpart primary fat32 $(expr 4 \* 1024 \* 1024) $(expr 60 \* 1024 \* 1024 - 1)
  1951. print
  1952. quit
  1953. EOF
  1954. }
  1955. CreateSDCardImageFile(){
  1956. fileName="/tmp/pinet.img"
  1957. dd if=/dev/zero of=$fileName bs=512 count=208845
  1958. create_partition_table $fileName
  1959. sudo mkdosfs -n PINET -S 512 -s 16 -v $fileName
  1960. mkdir /mnt/sdimage
  1961. mount $fileName /mnt/sdimage
  1962. cp -r /home/$SUDO_USER/PiBoot/* /mnt/sdimage/
  1963. umount /mnt/sdimage
  1964. rm -r /mnt/sdimage
  1965. mv $fileName /home/$SUDO_USER/pinetSDImage.img
  1966. }
  1967.  
  1968. CheckPipSymbolicLinkBug(){
  1969. #Checks and fixes the pip3-2 symbolic link bug added in PiNet 1.1.1 and fixed in PiNet 1.1.4
  1970. #if [ ! -h "/opt/ltsp/armhf/usr/bin/pip3" ] || [ ! -f "/opt/ltsp/armhf/usr/bin/pip3" ]; then
  1971. # ltsp-chroot apt-get purge -y python3-pip
  1972. # ltsp-chroot apt-get install -y python3-pip
  1973. # ltsp-chroot --arch armhf ln -sf /usr/bin/pip-3.2 /usr/bin/pip3
  1974. # UpdateConfig NBDBuildNeeded true
  1975. #fi
  1976. echo ""
  1977. }
  1978.  
  1979. CheckDebianVersion(){
  1980. $p checkDebianVersion
  1981. exitstatus=$(gp)
  1982. if [ "$exitstatus" = "1" ]; then
  1983. RebuildOS
  1984. fi
  1985.  
  1986. }
  1987.  
  1988. CheckBackupScriptVersion(){
  1989. if [ -f "/usr/local/bin/pinet-backup.sh" ]; then
  1990. thirdLineCheck="if [ ! \$backupLoc = \"\" ]; then"
  1991. currentThirdLine=$(sed '3q;d' /usr/local/bin/pinet-backup.sh)
  1992. if [ "$thirdLineCheck" == "$currentThirdLine" ]; then
  1993. createBackupScript
  1994. fi
  1995. fi
  1996.  
  1997. }
  1998.  
  1999. DuplicateLTSConf(){
  2000. #Duplicate the lts.conf from /opt/ltsp/armhf/etc/lts.conf to /var/lib/tftpboot/ltsp/armhf/lts.conf
  2001. cp /opt/ltsp/armhf/etc/lts.conf /var/lib/tftpboot/ltsp/armhf/lts.conf
  2002.  
  2003. }
  2004.  
  2005. WheezyJessieUpgradePartTwo(){
  2006. ChooseReleaseChannel "NoRestart"
  2007. exec /bin/bash pinet "Wheezy-upgrade-part-three"
  2008. exit
  2009. }
  2010.  
  2011. WheezyJessieUpgradePartThree(){
  2012. # Delete old pinet-functions-python.py file (has been replaced by pinet_functions_pinet.py and start OS rebuild.
  2013. rm /usr/local/bin/pinet-functions-python.py
  2014. RebuildOS
  2015. $p resetThemeCacheForAllUsers
  2016. #UpdateAll
  2017. }
  2018.  
  2019. GetInternalIPAddress(){
  2020. # Gets the current internal IP address and sets the $IP variable to it.
  2021. $p getInternalIPAddress
  2022. IP=$(gp)
  2023. }
  2024.  
  2025. #***************************************************************************************************
  2026. backupDeleteTime(){
  2027. MENUEPT=$(whiptail --menu $"How long would you like to store backups? Note this only runs when a backup runs." --nocancel 20 85 10 \
  2028. "Ten-Days" $"Backups will be kept for 10 days then deleted" \
  2029. "Thirty-Days" $"Backups will be kept for 30 days then deleted" \
  2030. "Ninety-Days" $"Backups will be kept for 90 days then deleted" \
  2031. "Forever" $"I will delete my backups manually" \
  2032. 3>&1 1>&2 2>&3)
  2033.  
  2034. case "$MENUEPT" in
  2035. Ten-Days)
  2036. DELETETIME=10
  2037. ;;
  2038. Thirty-Days)
  2039. DELETETIME=30
  2040. ;;
  2041. Ninety-Days)
  2042. DELETETIME=90
  2043. ;;
  2044. Forever)
  2045. DELETETIME=9999
  2046. ;;
  2047. *)
  2048. removeAnacronLines
  2049. rm -rf /usr/local/bin/pinet-backup.sh
  2050. Menu
  2051. ;;
  2052.  
  2053. esac
  2054. }
  2055.  
  2056.  
  2057. #***************************************************************************************************
  2058. backupFrequency(){
  2059. MENUEPT=$(whiptail --menu $"How often should PiNet create a backup?" --nocancel 20 85 10 \
  2060. "Every-day" $"Will create a new backup every day" \
  2061. "Twice-weekly" $"Will create a backup on Tuesday and Thursday" \
  2062. "Once-a-week" $"Will create a backup every Friday" \
  2063. 3>&1 1>&2 2>&3)
  2064.  
  2065. case "$MENUEPT" in
  2066. Every-day)
  2067. removeAnacronLines
  2068. echo "1 15 PiNet.backup1 /bin/sh /usr/local/bin/pinet-backup.sh" >> /etc/anacrontab
  2069.  
  2070. ;;
  2071. Twice-weekly)
  2072. removeAnacronLines
  2073. echo "3 15 PiNet.backup1 /bin/sh /usr/local/bin/pinet-backup.sh" >> /etc/anacrontab
  2074. ;;
  2075. Once-a-week)
  2076. removeAnacronLines
  2077. echo "1 15 PiNet.backup1 /bin/sh /usr/local/bin/pinet-backup.sh" >> /etc/anacrontab
  2078. ;;
  2079. *)
  2080. removeAnacronLines
  2081. rm -rf /usr/local/bin/pinet-backup.sh
  2082. Menu
  2083. ;;
  2084.  
  2085. esac
  2086. }
  2087.  
  2088.  
  2089.  
  2090. #***************************************************************************************************
  2091. OtherMenu() {
  2092.  
  2093. MENUEPT=$(whiptail --title $"Other Submenu" --cancel-button $"Main Menu" --ok-button $"Select" --menu $"What would you like to do?" 20 85 10 \
  2094. "Refresh-System" $"Refreshes network services. Useful if having boot issues" \
  2095. "Custom-config" $"Customise the config.txt file on the SD cards." \
  2096. "NBD-recompress" $"Force an NBD compress if changes are made outside PiNet" \
  2097. "NBD-compress-disable" $"Disable auto NBD recompression after every change" \
  2098. "NBD-compress-enable" $"Enable auto NBD recompression after every change (default)" \
  2099. "Export-users" $"Export all user data for migrating to new PiNet server" \
  2100. "Change-release-channel" $"Change your current update channel to dev or stable" \
  2101. "Edit-Information" $"Edit information attached to the PiNet server" \
  2102. "Full-Install" $"Full install of PiNet server" \
  2103. 3>&1 1>&2 2>&3)
  2104.  
  2105. #<<COMMENT1
  2106. #if [$MENUOPT -eq 0]; then
  2107. case "$MENUEPT" in
  2108. Collect-work)
  2109. CollectWork
  2110. Menu
  2111. ;;
  2112. NBD-compress-disable)
  2113. UpdateConfig NBDuse false
  2114. ConfigFileRead
  2115. Menu
  2116. ;;
  2117. NBD-compress-enable)
  2118. UpdateConfig NBDuse true
  2119. ConfigFileRead
  2120. Menu
  2121. ;;
  2122. Custom-config)
  2123. $p "customConfig"
  2124. ConfigFileRead
  2125. if [ "$NBDBuildNeeded" = "true" ]; then
  2126. NBDRun
  2127. fi
  2128. Menu
  2129. ;;
  2130. NBD-recompress)
  2131. local CurrentNBD=$NBDuse
  2132. UpdateConfig NBDuse true
  2133. NBDRun
  2134. UpdateConfig NBDuse $CurrentNBD
  2135. ConfigFileRead
  2136. Menu
  2137. ;;
  2138. Refresh-System)
  2139. resetAndCleanup
  2140. Menu
  2141. ;;
  2142. Export-users)
  2143. CreateMoveBackup
  2144. Menu
  2145. ;;
  2146. Edit-Information)
  2147. $p "askExtraStatsInfo"
  2148. Menu
  2149. ;;
  2150. Change-release-channel)
  2151. ChooseReleaseChannel "Restart"
  2152. ;;
  2153. Full-Install)
  2154. if [ -d /opt/ltsp/armhf ]; then
  2155. whiptail --title $"Error" --yesno $"An LTSP install has been detected.. Not recommended to continue. Should PiNet continue?" 8 78
  2156. exitstatus=$?
  2157. if [ $exitstatus = 0 ]; then
  2158. echo ""
  2159. else
  2160. Menu
  2161. fi
  2162. fi
  2163. FullInstall
  2164. Menu
  2165. ;;
  2166. *)
  2167. Menu
  2168. ;;
  2169.  
  2170. esac
  2171.  
  2172. } #***************************************************************************************************
  2173.  
  2174. SharedFolderMenu() {
  2175.  
  2176. MENUEPT=$(whiptail --title $"Shared folders" --cancel-button $"Main Menu" --ok-button $"Select" --menu $"What would you like to do?" 20 85 10 \
  2177. "Create-Shared-Folder" $"Create a new shared folder" \
  2178. "Remove-Shared-Folder" $"Remove a shared folder" \
  2179. "Change-Permissions" $"Changes shared folder permissions" \
  2180. "Display-Shared-Folders" $"Display a list of all shared folders" \
  2181. "Add-Teacher" $"Add a new account to the teacher group" \
  2182. 3>&1 1>&2 2>&3)
  2183.  
  2184. case "$MENUEPT" in
  2185. Create-Shared-Folder)
  2186. CreateSharedFoldersDialog
  2187. Menu
  2188. ;;
  2189. Remove-Shared-Folder)
  2190. RemoveSharedFolder
  2191. Menu
  2192. ;;
  2193. Change-Permissions)
  2194. SharedFolderPerm
  2195. Menu
  2196. ;;
  2197. Display-Shared-Folders)
  2198. DisplaySharedFolders
  2199. ;;
  2200. Add-Teacher)
  2201. AddTeacher
  2202. Menu
  2203. ;;
  2204. *)
  2205. Menu
  2206. ;;
  2207.  
  2208. esac
  2209.  
  2210. } #***************************************************************************************************
  2211.  
  2212. EpoptesMenu() {
  2213.  
  2214. MENUEPT=$(whiptail --title $"Epoptes Submenu" --cancel-button $"Main Menu" --ok-button $"Select" --menu $"Epoptes classroom management software is a free, open source and easy to use computer lab management and monitoring tool. What would you like to do?" 20 80 10 \
  2215. "Install-Epoptes" $"Install Epoptes onto the server and Raspberry Pis" \
  2216. "Epoptes-launch" $"Launches Epoptes, it must be installed first though" \
  2217. "Add-Teacher" $"Add a new account to the teacher group" \
  2218. "Remove-epoptes" $"Uninstall Epoptes from the server and Raspberry Pis" \
  2219. 3>&1 1>&2 2>&3)
  2220.  
  2221. case "$MENUEPT" in
  2222. Install-Epoptes)
  2223. checkInternet
  2224. if [ $? -eq 0 ]; then
  2225. whiptail --title $"Epoptes install" --yesno $"I am now going to install Epoptes classroom management software on the server and Raspberry Pis. Would you like to continue?" 8 78
  2226. if [ $? -eq 0 ];then
  2227.  
  2228. EpoptesInstaller
  2229. NBDRun
  2230. fi
  2231. else
  2232. whiptail --title $"Error" --msgbox $"No internet connection, unable to proceed..." 8 78
  2233. fi
  2234. Menu
  2235. ;;
  2236. Epoptes-launch)
  2237. EpoptesRun
  2238. Menu
  2239. ;;
  2240. Add-Teacher)
  2241. AddTeacher
  2242. Menu
  2243. ;;
  2244. Remove-epoptes)
  2245. ltsp-chroot --arch armhf apt-get remove -y epoptes-client
  2246. ltsp-chroot --arch armhf apt-get -y autoremove
  2247. NBDRun
  2248. whiptail --title $"Epoptes" --msgbox $"Epoptes has been removed from the pi image" 16 78
  2249. Menu
  2250. ;;
  2251. *)
  2252. Menu
  2253. ;;
  2254.  
  2255. esac
  2256. }
  2257.  
  2258. #***************************************************************************************************
  2259. ##### WIP ##########################
  2260. BackupMenu() {
  2261.  
  2262. MENUEPT=$(whiptail --title $"Backup Submenu" --cancel-button $"Main Menu" --ok-button $"Select" --menu $"What would you like to do?" 20 80 10 \
  2263. "Configure-backup" $"Configure and enable backups. Also use to make changes" \
  2264. "Disable-backup" $"Disables backup daemon, old backups will not be deleted" \
  2265. "Display-Logs" $"Displays logs for the backup daemon, check these regularly!" \
  2266. 3>&1 1>&2 2>&3)
  2267.  
  2268. #<<COMMENT1
  2269. #if [$MENUOPT -eq 0]; then
  2270. case "$MENUEPT" in
  2271. Configure-backup)
  2272. whiptail --title $"Select Location" --msgbox $"Select the location where you wish to save the backups. An external hard drive is highly recommended! Even a large (16gb+) pendrive should be sufficient. In Linux external drives are attached in /media so you will start there. Do not save backups on the same hard drive as the /home folder!" 12 78
  2273. cd /media
  2274. fileSelect
  2275. exit=$?
  2276. if [ "$exit" = "1" ]; then
  2277. Menu
  2278. else
  2279. $p setConfigParameter backupLoc "$location/"
  2280. backupFrequency
  2281. backupDeleteTime
  2282. createBackupScript
  2283. currentDate=`date +"%d-%m-%y"`
  2284. currentTime=`date +"%H:%M"`
  2285. logger -s "$currentDate $currentTime - Backup configured. Folder chosen is $location" 2>> /var/log/PiNet-backup.log
  2286. whiptail --title $"Backup setup" --msgbox $"The backup is now configured, the logs can be viewed at any time by checking /var/log/PiNet-backup.log" 12 78
  2287. fi
  2288. Menu
  2289. ;;
  2290. Disable-backup)
  2291. rm -rf /usr/local/bin/pinet-backup.sh
  2292. removeAnacronLines
  2293. currentDate=`date +"%d-%m-%y"`
  2294. currentTime=`date +"%H:%M"`
  2295. logger -s "$currentDate $currentTime - Backup disabled from PiNet" 2>> /var/log/PiNet-backup.log
  2296. whiptail --title $"Backup disabled" --msgbox $"The backup daemon has now been disabled, no more backups will be performed till it is enabled again with Configure-backup. All old backups have been kept." 12 78
  2297. Menu
  2298. ;;
  2299. Display-Logs)
  2300. clear
  2301. echo "-------------------"
  2302. echo $"PiNet log file"
  2303. echo "-------------------"
  2304. echo " "
  2305. echo "$(cat /var/log/PiNet-backup.log)"
  2306. echo " "
  2307. echo $"Hit enter to continue"
  2308. read
  2309. Menu
  2310. ;;
  2311. *)
  2312. Menu
  2313. ;;
  2314.  
  2315. esac
  2316.  
  2317. }
  2318.  
  2319. ##### WIP ##########################
  2320.  
  2321. #***************************************************************************************************
  2322. UserGroups() {
  2323.  
  2324. MENUEPT=$(whiptail --title $"Manage-users Submenu" --cancel-button $"Main Menu" --ok-button $"Select" --menu $"What would you like to do?" 20 80 11 \
  2325. "Add-user" $"Add a new Linux user" \
  2326. "Remove-user" $"Remove a Linux user" \
  2327. "Change-password" $"Change password of a user" \
  2328. "Display-users" $"List all the users on the system" \
  2329. "Add-teacher" $"Add user to the staff permission group" \
  2330. "Import-Users" $"Import usernames and passwords from a CSV file" \
  2331. "Delete-Batch" $"Batch delete users from a CSV file" \
  2332. "Change-Sudo" $"Change student sudo permissions. Used for GPIO access" \
  2333. "Group-check" $"Checks all users are in the correct system groups" \
  2334. "Export-users" $"Export all user data for migrating to new PiNet server" \
  2335. 3>&1 1>&2 2>&3)
  2336.  
  2337. case "$MENUEPT" in
  2338. Add-user)
  2339. AddUsers
  2340. Menu
  2341. ;;
  2342. Remove-user)
  2343. RemoveUser
  2344. Menu
  2345. ;;
  2346. Change-password)
  2347. ChangeUserPassword
  2348. Menu
  2349. ;;
  2350. Display-users)
  2351. DisplayUsers
  2352. ;;
  2353. Group-check)
  2354. GroupCheck
  2355. Menu
  2356. ;;
  2357. Add-teacher)
  2358. AddTeacher
  2359. Menu
  2360. ;;
  2361. Import-Users)
  2362. ImportUsersFromCSV
  2363. ;;
  2364. Delete-Batch)
  2365. DeleteUsersFromCSV
  2366. ;;
  2367. Graphics-fix)
  2368. fixGroups
  2369. Menu
  2370. ;;
  2371. Change-Sudo)
  2372. SudoMenu
  2373. if [ "$NBDBuildNeeded" = "true" ]; then
  2374. NBDRun
  2375. fi
  2376. Menu
  2377. ;;
  2378.  
  2379. Remove-Samab-user)
  2380. user=$(whiptail --inputbox "Enter the username of the user you wish to remove from Samba" 8 78 $INIT --title "Samba" 3>&1 1>&2 2>&3)
  2381. pdbedit -u "$user" -xl
  2382. whiptail --title "Samba" --msgbox 'User has been removed from samba. ' 12 78
  2383. Menu
  2384. ;;
  2385. Export-users)
  2386. CreateMoveBackup
  2387. Menu
  2388. ;;
  2389. *)
  2390. Menu
  2391. ;;
  2392.  
  2393. esac
  2394. } #***************************************************************************************************
  2395.  
  2396.  
  2397. FullInstall(){
  2398. checkInternetDetailed
  2399. if [ $? -eq 0 ]; then
  2400. ConfigFileRead
  2401. if [ "$ImportedUsers" = "" ]; then
  2402. FirstTimeImportUsers
  2403. fi
  2404. if [ "$ReleaseChannel" = "" ]; then
  2405. ChooseReleaseChannel 1
  2406. fi
  2407. $p initialInstallSoftwareList
  2408. whiptail --title $"Full Install" --msgbox $"A full install will take around 1-2 hours depending on your Internet speed. There will be a number of options to select at the end so do not close this terminal until the install has completed!" 10 78
  2409. installLTSP #Installs LTSP and other packages required to build an Raspberry Pi OS
  2410. buildClient #Creates config file to build Raspbian with LTSP and builds it
  2411. OneTimeFixes #Runs some one off config changes, these are not repeated at any time later
  2412. #PiConfigFixes #Adds configuration changes to LXDE and installs Raspi artwork
  2413. configFixes #Main configuration changes that are run on the the LTSP chroot (/opt/ltsp/armhf). These must be run every time the image is generated
  2414. FixRepo #Adds additional repositories to the Raspbian build
  2415. AddSoftware #Adds all the custom software on top of a normal Armhf Debian Wheezy build
  2416. RaspiTheme #Installs the PiNet theme which can be seen at login
  2417. FixDesktopIcons #Adds desktop icons
  2418. InstallRaspberryPiUIMods
  2419. EnableNBDswap #Enables NBD swap for if the Pi runs out of RAM, it can use server as RAM using NBD
  2420. UpdateConfig NBD false
  2421. UpdateConfig NBDuse false
  2422. $p installSoftwareFromFile
  2423. DisableSPI
  2424. SudoMenu #Asks the user if they wish to enable Sudo for the pupils
  2425. UpdateSD "NoRecompress" #Runs the IP address selector and builds the SD card image
  2426. addSoundcardDefault
  2427. SetupSharedStandalone
  2428. installKernelUpdater ""
  2429. $p checkKernelFileUpdateWeb
  2430. fixGroups "NoRecompress" #Adds all current users to the correct groups.
  2431. DuplicateLTSConf
  2432. usermod -a -G teacher $SUDO_USER
  2433. LegacyFixes "NoRecompress"
  2434. AddSoftware
  2435. EnableNBD #Enables NBD compression
  2436. resetAndCleanup
  2437. $p triggerInstall
  2438. CheckInstallSuccess
  2439.  
  2440. whiptail --title "Main installation complete" --msgbox "PiNet main installation is now complete. There may be a few other minor updates that will be applied now. You will need to flash an SD card with the PiNet boot files, instructions can be found at http://pinet.org.uk/articles/installation/sd-card-copy.html. Then plug the Raspberry Pi into the network and boot it up." 11 78
  2441. else
  2442. whiptail --title "Error" --msgbox "The installation has been cancelled due to a problem accessing key domains used in the installation." 8 78
  2443. echo "The installation has been cancelled due to a problem accessing key domains used in the installation."
  2444. exit 1
  2445. fi
  2446. }
  2447.  
  2448. RebuildOS(){
  2449. checkInternet
  2450. if [ $? -eq 0 ]; then
  2451. rm -rf /opt/ltsp/armhf
  2452. rm -rf /var/lib/tftpboot/ltsp/armhf
  2453. $p initialInstallSoftwareList
  2454. buildClient
  2455. configFixes
  2456. FixRepo
  2457. AddSoftware
  2458. RaspiTheme
  2459. FixDesktopIcons #Adds desktop icons
  2460. InstallRaspberryPiUIMods
  2461. EnableNBDswap
  2462. #whiptail --title $"Extra software" --msgbox $"Select any additional software you want to use or use Install-Custom-software to install a specific package from the Raspbian apt repository if you know its name. To quit the menu, use the cancel option. This menu can be later accessed from Install-Program from the main menu." 12 78
  2463. $p installSoftwareFromFile
  2464. DisableSPI
  2465. SudoMenu #Asks the user if they wish to enable Sudo for the pupils
  2466. UpdateSD "NoRecompress"
  2467. addSoundcardDefault
  2468. SetupSharedStandalone
  2469. installKernelUpdater ""
  2470. $p checkKernelFileUpdateWeb
  2471. fixGroups "NoRecompress"
  2472. DuplicateLTSConf
  2473. LegacyFixes "NoRecompress"
  2474. AddSoftware
  2475. EnableNBD
  2476. resetAndCleanup
  2477. CheckInstallSuccess
  2478. whiptail --title $"Rebuild complete" --msgbox $"PiNet rebuild is now complete. You will need to flash an SD card with the PiNet boot files, instructions can be found at http://pinet.org.uk/articles/installation/sd-card-copy.html. Then plug the Raspberry Pi into the network and boot it up." 10 78
  2479. else
  2480. whiptail --title $"Error" --msgbox $"No internet connection, unable to proceed..." 8 78
  2481. fi
  2482.  
  2483. }
  2484.  
  2485.  
  2486. Menu() {
  2487. GetInternalIPAddress
  2488. MENUOPT=$(whiptail --title $"PiNet $version Main Menu - $IP" --cancel-button $"Quit" --ok-button $"Select" --menu $"What would you like to do?" 22 80 14 \
  2489. "System-Status" $"Display status of key parts of your PiNet server" \
  2490. "Install-Program" $"Install a new program on the Raspberry Pi's" \
  2491. "Manage-Users" $"Add new users, change passwords and delete users" \
  2492. "Update-All" $"Run an automatic update on server and Raspbian" \
  2493. "Backup-Menu" $"User files backup submenu" \
  2494. "Shared-Folders" $"Manage and create shared folders" \
  2495. "Collect-work" $"Collects students work in a single folder" \
  2496. "Update-SD" $"Update the SD card image. This includes IP address changes" \
  2497. "Rebuild-OS" $"Rebuilds the LTSP Raspberry Pi image from scratch again" \
  2498. "Epoptes-Menu" $"Epoptes classroom management submenu" \
  2499. "Troubleshooter" $"Having issues? Try running the troubleshooter" \
  2500. "Other" $"Other options and utilities for management" \
  2501. "Update-PiNet" $"Forces PiNet to update itself" \
  2502. 3>&1 1>&2 2>&3)
  2503.  
  2504. case "$MENUOPT" in
  2505. System-Status)
  2506. listStatus
  2507. Menu
  2508. ;;
  2509. Update-SD)
  2510. UpdateSD
  2511. if [ $? -eq 0 ]; then
  2512. whiptail --title $"SD image updated" --msgbox $"SD card image updated. A folder of boot files in /home/$SUDO_USER/PiBoot has been created. An experimental disk image ready to flash onto the SD card has also been created at /home/$SUDO_USER/pinetSDImage.img. You can use either option. See http://pinet.org.uk/articles/installation/sd-card-copy.html for help." 11 78
  2513. fi
  2514. Menu
  2515. ;;
  2516. Install-Program)
  2517. $p installSoftwareList
  2518. Menu
  2519. ;;
  2520. Shared-Folders)
  2521. SharedFolderMenu
  2522. Menu
  2523. ;;
  2524. Rebuild-OS)
  2525. whiptail --title $"WARNING!!" --yesno $"Warning, you are about to delete the entire Raspbian OS from the server and rebuild it. Students files are not affected but any custom programs added will need to be re-added. This will take 1-2 hours. Are you sure?" 9 78
  2526.  
  2527. exitstatus=$?
  2528. if [ $exitstatus = 0 ]; then
  2529. RebuildOS
  2530. fi
  2531. Menu
  2532. ;;
  2533. Backup-Menu)
  2534. whiptail --title "WARNING" --msgbox 'WARNING - The backup system in PiNet is currently in alpha, you are responsible to check backups are correctly being made and checking the log file frequently. To check the log file, select Display-Logs in the Backup submenu!' 12 78
  2535. BackupMenu
  2536. ;;
  2537. Manage-Users)
  2538. UserGroups
  2539. Menu
  2540. ;;
  2541. Install-Epoptes)
  2542. EpoptesInstaller
  2543. Menu
  2544. ;;
  2545. Update-All)
  2546. UpdateAll
  2547. Menu
  2548. ;;
  2549. Epoptes-Menu)
  2550. EpoptesMenu
  2551. ;;
  2552. Collect-work)
  2553. CollectWork
  2554. Menu
  2555. ;;
  2556. Other)
  2557. OtherMenu
  2558.  
  2559. ;;
  2560. Troubleshooter)
  2561. TroubleShooter
  2562. Menu
  2563. ;;
  2564. Update-PiNet)
  2565. Updater
  2566. ;;
  2567. *)
  2568. exit
  2569. ;;
  2570. esac
  2571.  
  2572.  
  2573. }
  2574.  
  2575.  
  2576.  
  2577. #************************************* Startup stuff **************************************************************
  2578.  
  2579. if [ "$(id -u)" != "0" ]; then #Check if script is being run as root
  2580. echo $"This script must be run as root" 1>&2
  2581. exit 1
  2582. fi
  2583.  
  2584. if [ ! "$BASH_VERSION" ] ; then #Checks that PiNet is being run using bash and not ash (aka sh)
  2585. whiptail --title $"Shell error" --msgbox $"Please do not run PiNet with sudo sh $0. Please run it with bash using sudo bash $0" 8 78
  2586. echo $"Please do not run PiNet with sh $0. Please run it with bash using sudo bash $0" 1>&2
  2587. exit 1
  2588. fi
  2589. CheckOS #Checks if running Ubuntu, if not complains a little
  2590. if [ "$SUDO_USER" = "" ]; then
  2591. SUDO_USER=$(whiptail --inputbox $"No user in the SUDO_USER variable was detected. This occurs when you didn't launch the application with sudo. Please enter your normal Linux username." 9 78 --title $"Unsupported operating system" 3>&1 1>&2 2>&3) #Sometimes can't detect username to run program as.
  2592. fi
  2593.  
  2594. checkInstallLoc #Checks PiNet is installed in /usr/local/bin. If not offer to move it
  2595.  
  2596. echo $"Starting PiNet - Please wait"
  2597. checkPythonFunctionsInstalled #Checks the supporting Python functions are installed correctly
  2598. CheckForRaspiLTSP
  2599. VerifyPythonPackages
  2600.  
  2601. CheckTerminalSize #Changes the terminal to the minimum size if is too small
  2602.  
  2603. case "$1" in #Checks if PiNet needs to run an update all, usually run after an update when the software is launched by itself
  2604. Update-All)
  2605. UpdateSD
  2606. UpdateAll
  2607. ;;
  2608. SD-card-update)
  2609. UpdateSD
  2610. ;;
  2611. Wheezy-upgrade-part-two)
  2612. WheezyJessieUpgradePartTwo
  2613. ;;
  2614. Wheezy-upgrade-part-three)
  2615. WheezyJessieUpgradePartThree
  2616. ;;
  2617. esac
  2618.  
  2619. if [ ! -d /opt/ltsp/armhf ]; then # Check if PiNet is installed. If not, offer to install
  2620. whiptail --title $"Welcome" --yesno $"Welcome to PiNet. No previous PiNet installation is detected, would you like to run the full PiNet installer? " 8 78
  2621. exitstatus=$?
  2622. if [ $exitstatus = 0 ]; then
  2623. UpdateConfig FirstUser $SUDO_USER
  2624. FullInstall
  2625. else
  2626. Menu
  2627. fi
  2628. fi
  2629. ConfigFileRead #Reads the main configuration file (/etc/pinet) and loads all values in as environmental variables
  2630.  
  2631. if [ "$ReleaseChannel" = "" ]; then #Makes sure a release channel is selected, if not asks for one
  2632. ChooseReleaseChannel "Restart"
  2633. fi
  2634.  
  2635. SetupRepositories #Sets up the correct branch variables as selected in ChooseReleaseChannel()
  2636.  
  2637. checkInternet #Checks if PiNet server has a web connection. If so, checks for updates on PiNet, PiNet kernels and PiNet kernel updater
  2638. if [ $? -eq 0 ]; then
  2639. if [ ! "$DisableUpdateChecking" = "true" ]; then
  2640. CheckReleases
  2641. checkKernelFileUpdateWeb
  2642. checkKernelUpdater "NBD"
  2643. fi
  2644. fi
  2645. fixGroups #Verify all groups are set up correctly with correct users
  2646. LegacyFixes #Makes sure all configuration data is correctly configured
  2647. CheckInstallSuccess
  2648. Menu #Runs main menu
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement