self.li - note to self and share with others, blog by Peter Legierski

Peter Legierski

/pronounced as leg-year-ski/

Occasional workaholic, regular teaholic. Maker of things. Fat, powdered nose, indoor climber!

Currently working on my personal project MRR.io. Check it out!

Creating a post-installation script for Ubuntu

I want to share with you today how to create your own bash script that can be used to bootstrap a fresh installation of Ubuntu (and very likely any other Linux distro after small modifications), bringing it very close to a state where you can just open your favourite apps and start working.

Back in the days of Windows XP I’d create a perfect setup of my machine and use software like Norton Ghost to create an image of the main partition. It had several advantages over my current approach:

  • no access to the internet required
  • fully automated process
  • every tiny detail saved

Here’s the thing, though: with Windows I’d have to reinstall it every 2-4 weeks due to my heavy usage, installing and uninstalling of apps and general sluggishness of the system after a while. With Linux, on the other hand, I can go for months on the same install and I rarely run into problems that force me to reinstall the system. I can, however, put it on a different disk, partition, completely different machine or even use it for a different user, tweaking the username and adding/deleting sections of the script to match it to a new environment. Another great thing is that the script and all resources that it uses are very small compared to disk image. There is also no need to update any apps (or the system itself) after running the script as it already uses the newest versions available and runs system update.

The script is separated roughly into 3 parts:

  • install apps
  • configure apps
  • change system settings
    • with gsettings
    • with dconf

I’ve developed this script using Ubuntu 13.10 in Virtualbox 4.3 - you can create a snapshot of the system right after the basic installation (+ initial update & upgrade commands) and revert to it every time you want to run your code.

Part 1: Install apps

Some apps will require additional repositories, which should be added to the very top of your script. After that you can run update & upgrade, which will bring your fresh install up to speed with latest versions of everything installed by default.

The way I went about the apps was to go through my ~/.bash_history file and make a list of all apps that I’d like to have from the get go. I’ve added them all to one massive apt-get install.

There are two more apps that I want to install, that can’t be installed via apt-get, as they are essentially PHAR files: Composer and Laravel. These are kept in /usr/local/bin/ . Don’t forget to change their permissions and owner.

At the very end I have ubuntu-restricted-extras that requires interaction.

Part 2: Configure apps

There is generally several things to do, depending on app and your personal preference:

  • replace existing conf files / dotfiles with the ones inside data folder
  • append settings to existing conf files
  • add user to groups
  • copy scripts / program files into appropriate folders

Note: Pay attention to files that require root access to edit them. You won’t be able to do the following:

sudo echo "alpha" > /etc/some/important/file
sudo echo "bravo" >> /etc/some/other/important/file

The “sudo” applies only to “echo” in the examples above. Here’s how you replace and append contents of these files:

echo "alpha" | sudo tee /etc/some/important/file
echo "bravo" | sudo tee -a /etc/some/important/file

Note: Here’s how to copy dotfiles with a wildcard (*):

shopt -s dotglob
cp -ar ./data/dotfiles/* ~

Without the first line, the * wouldn’t match files starting with “.” .

Part 3: Change system settings

In this part we’ll focus on two different tools: gsettings and dconf. I was planning to use only gsettings, but it turns out that some things just can’t be changed with it.

Part 3.1: gsettings

My favourite way to make use of gsettings is to save all current settings from fresh install and diff them against my working machine.

On a fresh install within Virtualbox:

gsettings list-recursively > ~/original.txt

On my working machine:

gsettings list-recursively > ~/new.txt

It’s a good idea to sort settings and get rid of duplicates before diffing the two files. Sublime Text can do that for you as well as diff the files. This way you will be able to see which settings actually changed since the fresh installation.

copy all settings that you want to preserve and prepend each line with gsettings set. Don’t forget to add double quotes around arrays like ['spotify.desktop']

Part 3.2: dconf

I’ve used this tool to capture a few more settings that I couldn’t change with gsettings. This time, the easiest way to do it is to run dconf on a fresh install in monitor mode with:

dconf watch /

And make desired changes manually. You should see paths popping on the screen with their new values. Prepend dconf write to the lines and values you want to set on a fresh machine and add them to your script.

One final note

sudo requires you to retype user password after 10 minutes, so I try to put all sudo commands before the rest of the commands, as much as possible.

Here’s my current script:

#!/bin/bash


# add repos
sudo apt-add-repository -y "deb http://repository.spotify.com stable non-free"
sudo add-apt-repository -y "deb http://linux.dropbox.com/ubuntu $(lsb_release -sc) main"
sudo add-apt-repository -y "deb http://archive.canonical.com/ $(lsb_release -sc) partner"
sudo add-apt-repository -y "deb http://dl.google.com/linux/chrome/deb/ stable main"
sudo add-apt-repository -y "deb http://dl.google.com/linux/talkplugin/deb/ stable main"
sudo add-apt-repository -y ppa:webupd8team/sublime-text-3
sudo add-apt-repository -y ppa:tuxpoldo/btsync
sudo add-apt-repository -y ppa:freyja-dev/unity-tweak-tool-daily
sudo add-apt-repository -y ppa:stefansundin/truecrypt
sudo apt-key adv --keyserver pgp.mit.edu --recv-keys 5044912E
sudo apt-key adv --keyserver keyserver.ubuntu.com --recv-keys 94558F59
sudo wget -q -O - https://dl-ssl.google.com/linux/linux_signing_key.pub | apt-key add -


# basic update
sudo apt-get -y --force-yes update
sudo apt-get -y --force-yes upgrade


# install apps
sudo apt-get -y install \
    libxss1 spotify-client sublime-text-installer git gitk gitg \
    virtualbox virtualbox-guest-additions-iso filezilla dropbox \
    skype btsync-user gimp p7zip p7zip-full p7zip-rar unity-tweak-tool \
    indicator-multiload curl gparted dkms google-chrome-stable \
    ubuntu-wallpapers* php5-cli php5-common php5-mcrypt php5-sqlite \
    php5-curl php5-json phpunit mcrypt ssmtp mailutils mpack truecrypt\
    nautilus-open-terminal google-talkplugin linux-headers-generic \
    build-essential tp-smapi-dkms thinkfan moc


# install Composer
sudo curl -sS https://getcomposer.org/installer | php
sudo mv composer.phar /usr/local/bin/composer
sudo chmod 755 /usr/local/bin/composer


# install Laravel
sudo wget http://laravel.com/laravel.phar
sudo mv laravel.phar /usr/local/bin/laravel
sudo chmod 755 /usr/local/bin/laravel


# Virtualbox
sudo adduser x vboxusers


# email
sudo cp ./data/etc/ssmtp.conf /etc/ssmtp/ssmtp.conf
sudo chmod 744 /etc/ssmtp/ssmtp.conf


# x200 fan settings
# http://hackmemory.wordpress.com/2012/07/19/lenovo-x200-tuning/
echo "tp_smapi" | sudo tee -a /etc/modules
echo "thinkpad_acpi" | sudo tee -a /etc/modules
echo "options thinkpad_acpi fan_control=1" | sudo tee /etc/modprobe.d/thinkpad_acpi.conf
sudo cp ./data/etc/default/thinkfan /etc/default/thinkfan
sudo cp ./data/etc/thinkfan.conf /etc/thinkfan.conf
sudo chmod 744 /etc/default/thinkfan
sudo chmod 744 /etc/thinkfan.conf


# usb wifi + disable built in wifi // https://github.com/pvaret/rtl8192cu-fixes
mkdir -p /tmp/bootstrap/usb-wifi-fix/
unzip -d /tmp/bootstrap/usb-wifi-fix/ ./data/usb-wifi-fix.zip
sudo dkms add /tmp/bootstrap/usb-wifi-fix/
sudo dkms install 8192cu/1.8
sudo depmod -a
sudo cp /tmp/bootstrap/usb-wifi-fix/blacklist-native-rtl8192.conf /etc/modprobe.d/


# swappiness
cat ./data/etc/sysctl-append >> /etc/sysctl.conf


# Sublime Text 3
mkdir ~/.config/sublime-text-3/
unzip -d ~/.config/sublime-text-3/ ./data/sublime-text-3.zip
cp -ar ./data/sublime-text-3/* ~/.config/sublime-text-3/


# fonts
mkdir ~/.fonts
cp -ar ./data/fonts/* ~/.fonts/


# scripts
mkdir ~/.scripts
cp -ar ./data/scripts/* ~/.scripts/
chmod +x ~/.scripts/*


# dotfiles
shopt -s dotglob
cp -a ./data/dotfiles/* ~


# autostart
cp -a ./data/autostart/* ~/.config/autostart/


# Filezilla servers
mkdir ~/.filezilla/
cp -a ./data/filezilla/sitemanager.xml ~/.filezilla/


# Terminal
cp -a ./data/gconf/%gconf.xml ~/.gconf/apps/gnome-terminal/profiles/Default/


# folders
rm -rf ~/Documents
rm -rf ~/Public
rm -rf ~/Templates
rm -rf ~/Videos
rm -rf ~/Music
rm ~/examples.desktop
mkdir ~/Development
mkdir ~/BTSync


# update system settings
gsettings set com.canonical.indicator.power show-percentage true
gsettings set com.canonical.indicator.sound interested-media-players "['spotify.desktop']"
gsettings set com.canonical.indicator.sound preferred-media-players "['spotify.desktop']"
gsettings set com.canonical.Unity form-factor 'Netbook'
gsettings set com.canonical.Unity.Launcher favorites "['application://google-chrome.desktop', 'application://sublime-text.desktop', 'application://spotify.desktop', 'application://nautilus.desktop', 'application://gnome-control-center.desktop', 'application://gitg.desktop', 'application://gnome-terminal.desktop', 'unity://running-apps', 'unity://expo-icon', 'unity://devices']"
gsettings set com.canonical.Unity.Lenses remote-content-search 'none'
gsettings set com.canonical.Unity.Runner history "['/home/x/.scripts/screen_colour_correction.sh']"
gsettings set com.ubuntu.update-notifier regular-auto-launch-interval 0
gsettings set de.mh21.indicator.multiload.general autostart true
gsettings set de.mh21.indicator.multiload.general speed 500
gsettings set de.mh21.indicator.multiload.general width 75
gsettings set de.mh21.indicator.multiload.graphs.cpu enabled true
gsettings set de.mh21.indicator.multiload.graphs.disk enabled true
gsettings set de.mh21.indicator.multiload.graphs.load enabled true
gsettings set de.mh21.indicator.multiload.graphs.mem enabled true
gsettings set de.mh21.indicator.multiload.graphs.net enabled true
gsettings set de.mh21.indicator.multiload.graphs.swap enabled false
gsettings set org.freedesktop.ibus.general engines-order "['xkb:us::eng']"
gsettings set org.freedesktop.ibus.general preload-engines "['xkb:us::eng']"
gsettings set org.gnome.DejaDup backend 'file'
gsettings set org.gnome.DejaDup delete-after 365
gsettings set org.gnome.DejaDup include-list "['/home/x/Development', '/home/x/Pictures']"
gsettings set org.gnome.DejaDup periodic-period 1
gsettings set org.gnome.DejaDup welcomed true
gsettings set org.gnome.desktop.a11y.magnifier mag-factor 13.0
gsettings set org.gnome.desktop.background picture-uri 'file:///usr/share/backgrounds/163_by_e4v.jpg'
gsettings set org.gnome.desktop.default-applications.terminal exec 'gnome-terminal'
gsettings set org.gnome.desktop.input-sources sources "[('xkb', 'us')]"
gsettings set org.gnome.desktop.input-sources xkb-options "['lv3:ralt_switch', 'compose:rctrl']"
gsettings set org.gnome.desktop.media-handling autorun-never true
gsettings set org.gnome.desktop.privacy remember-recent-files false
gsettings set org.gnome.desktop.screensaver lock-enabled false
gsettings set org.gnome.desktop.screensaver ubuntu-lock-on-suspend false
gsettings set org.gnome.gitg.preferences.commit.message right-margin-at 72
gsettings set org.gnome.gitg.preferences.commit.message show-right-margin true
gsettings set org.gnome.gitg.preferences.diff external false
gsettings set org.gnome.gitg.preferences.hidden sign-tag true
gsettings set org.gnome.gitg.preferences.view.files blame-mode true
gsettings set org.gnome.gitg.preferences.view.history collapse-inactive-lanes 2
gsettings set org.gnome.gitg.preferences.view.history collapse-inactive-lanes-active true
gsettings set org.gnome.gitg.preferences.view.history search-filter false
gsettings set org.gnome.gitg.preferences.view.history show-virtual-staged true
gsettings set org.gnome.gitg.preferences.view.history show-virtual-stash true
gsettings set org.gnome.gitg.preferences.view.history show-virtual-unstaged true
gsettings set org.gnome.gitg.preferences.view.history topo-order false
gsettings set org.gnome.gitg.preferences.view.main layout-vertical 'vertical'
gsettings set org.gnome.nautilus.list-view default-zoom-level 'smaller'
gsettings set org.gnome.nautilus.preferences executable-text-activation 'ask'
gsettings set org.gnome.settings-daemon.plugins.media-keys terminal 'XF86Launch1'
gsettings set org.gnome.settings-daemon.plugins.power critical-battery-action 'shutdown'
gsettings set org.gnome.settings-daemon.plugins.power idle-dim false
gsettings set org.gnome.settings-daemon.plugins.power lid-close-ac-action 'nothing'
gsettings set org.gnome.settings-daemon.plugins.power lid-close-battery-action 'nothing'


# update some more system settings
dconf write /org/compiz/profiles/unity/plugins/unityshell/icon-size 32
dconf write /org/compiz/profiles/unity/plugins/core/vsize 1
dconf write /org/compiz/profiles/unity/plugins/core/hsize 5
dconf write /org/compiz/profiles/unity/plugins/opengl/texture-filter 2
dconf write /org/compiz/profiles/unity/plugins/unityshell/alt-tab-bias-viewport false


# requires clicks
sudo apt-get install -y ubuntu-restricted-extras


# prompt for a reboot
clear
echo ""
echo "===================="
echo " TIME FOR A REBOOT! "
echo "===================="
echo ""
Recommend:
Posted 12 years ago - Comments
  1. blog-self-li posted this
#linux #ubuntu #installation #configure #bootstrap #setup #script