Raspberry PI arrived – setup howto

TL;DR

This is mainly a reference for myself how and what to install/configure on a fresh Raspberry PI

Hope it helps you too

Instructions

Have a Raspberry PI

  • on a 8GB card download and install an image: Raspbian
  • Power on Raspberry PI
  • First time installation
    • via GUI: maximize hard drive
    • set GPU RAM to 16
    • enable SSH
    • setup static DHCP address on home router
    • setup another system user (thanks to this post) and make sure it can do `sudo` without password prompt
      • adduser foo
        echo "foo ALL=(ALL) NOPASSWD: ALL" >>/etc/sudoers
        userdel pi
    • add yourself to disk group
      • sudo vigr # find disk, add your username
    • setup SSH
      • sshkey-gen
        remote$ ssh-add foo@..
        remote$ ssh-copy-id foo@..
        vim /etc/ssh/sshd_config
        PermitRootLogin no
        #http://blog.self.li/post/63281257339/raspberry-pi-part-1-basic-setup-without-cables
    • setup /etc/hosts
      • sudo vi /etc/hosts #add your fav hostnames here
    • Setup timezone
      • sudo tzselect
    • Update OS (2nd step might take a while)
      • sudo apt-get update
        sudo apt-get upgrade
  • Install useful software
    • sudo apt-get install vim samba screen mc git-core htop tig pydf nmap gqview iotop iperf nmap pydf tig cryptsetup ftp pv gitk evince curl w3m lynx xdu baobab mutt git fbset libpcre3-dev libboost-dev omxplayer libgstreamer1.0-0-dbg gstreamer1.0-tools libgstreamer-plugins-base1.0-0 gstreamer1.0-plugins-good gstreamer1.0-plugins-bad-dbg gstreamer1.0-omx gstreamer1.0-alsa dcfldd tcpdump zip subversion libudev-dev make build-essential cec-utils
    • sudo apt-get install
    • vim /etc/apt/sources.list
      deb-src http://archive.raspbian.org/raspbian wheezy main contrib non-free rpi
      sudo apt-get update
      mkdir ~/unrar-nonfree && cd ~/unrar-nonfree
      sudo apt-get build-dep unrar-nonfree
      sudo apt-get source -b unrar-nonfree
      sudo dpkg -i unrar_4.1.4-1_armhf.deb
      cd && sudo rm -rf ~/unrar-nonfree
      sudo apt-get install unrar-free
  • Setup of my dotfiles (vimrc, bashrc for better console cmd history)
    • cd; mkdir -p github; git clone https://github.com/nthx/dotfiles.git; cd dotfiles; ./install
  • setup WiFi
    • Router: Disable “Enable AP Isolation” – this prevented my laptop accessing RPi network
    • Bus 001 Device 005: ID 148f:5370 Ralink Technology, Corp. RT5370 Wireless Adapter
    • cp /etc/network/interfaces /etc/network/interfaces.backup
      cp /etc/wpa_supplicant/wpa_supplicant.conf /etc/wpa_supplicant/wpa_supplicant.conf.backup
    • #vim /etc/network/interfaces
      auto lo
      iface lo inet loopback
      iface eth0 inet dhcp
      auto wlan0
      allow-hotplug wlan0
      iface wlan0 inet dhcp
         post-up iwconfig wlan0 power off
      wpa-conf /etc/wpa_supplicant/wpa_supplicant.conf
    • #vim /etc/wpa_supplicant/wpa_supplicant.conf
      ctrl_interface=/var/run/wpa_supplicant
      ctrl_interface_group=0
      update_config=1
      network={
       ssid="***-24"
       psk="***"
       id_str="rpi-0"
      }
    • sudo ifdown wlan0
      sudo ifup wlan0
      sudo wpa_cli status
    • In order to make Raspberry Pi automatically reconnect to Wifi after router down, use this solution:
      https://raspberrypi.stackexchange.com/a/5341/28218
      Works perfectly for me
    • For TP-LINK TL-WN725N card use this tutorial: https://www.raspberrypi.org/forums/viewtopic.php?p=462982#p462982
      • wget https://dl.dropboxusercontent.com/u/80256631/8188eu-v7-20150212.tar.gz
        wget https://dl.dropboxusercontent.com/u/80256631/8188eu-v7-20150818.tar.gz
        
        
  • Samba
    • cp /etc/samba/smb.conf /etc/samba/smb.conf.backup
      socket options = TCP_NODELAY
      workgroup = FOOBAR
      [pictures]
         comment = opt
         writable = no
         locking = no
         path = /mnt/foo/bar
         public = yes
    • service samba restart
  • Ruby
    • rvm (this is long, like hours of compilation)
      • https://rvm.io/rvm/install
  • SqueezeBox server
    • http://allthingspi.webspace.virginmedia.com/lms.php
  • DLNA Server
    • http://bbrks.me/rpi-minidlna-media-server/
    • apt-get install minidlna
      vi /etc/minidlna.conf
      #inotify=yes
      #db_dir=.... #setup to your hdd, not sd
      #log_dir=... #setup to your hdd, not sd
      #listening_ip=0.0.0.0 #though, my version failed on this - I had to disable and start /usr/bin/minidlnad -f /etc/minidlna.conf manually once
      #friendly_name=foo...
      #serial=bar...
      #notify_interval=895
      echo 120000 > /proc/sys/fs/inotify/max_user_watches
      sudo sysctl fs.inotify.max_user_watches=66538
      sudo service minidlna restart
  • PS3 Eye camera video straming
    • sudo apt-get install motion ffmpeg
      sudo vi /etc/default/motion # start_motion_daemon=yes
  • Console based bandwith speed test
    • wget https://raw.github.com/sivel/speedtest-cli/master/speedtest_cli.py
      chmod a+rx speedtest_cli.py ; ./speedtest_cli.py
  • Udev rules for auto-mounting HDD
    • ls -l /dev/disk/by-uuid/ #find your uuid and:
      sudo vi /etc/fstab
      UUID=41b81019-8838-4d22-9bf2-3673ca855ce7 /mnt/foobar ext4 noauto,user,sync,noatime,errors=remount-ro 0 2
    • udevadm info --name=/dev/sda1 --attribute-walk
      
      sudo vi /etc/udev/rules.d/81-my-drives.rules
      ACTION=="add", KERNELS=="sd*1", ATTRS{size}=="312581745", ATTRS{partition}=="1", SYMLINK+="foobar", RUN+="/bin/mount /mnt/foobar/"
      ACTION=="remove", KERNELS=="sd*1", ATTRS{size}=="312581745", ATTRS{partition}=="1", SYMLINK+="foobar", RUN+="/bin/umount -lf /mnt/foobar/"
      sudo udevadm control --reload-rules
      sudo udevadm test -a -p $(udevadm info -q path -n /dev/sda1)
  • Local DNS server for access of local servers by name
    • http://www.ducky-pond.com/posts/2013/Oct/how-to-setup-a-dns-server-with-powerdns-on-raspberry-pi/
    • sudo apt-get install pdns-serve
      sudo sed -i 's/# recursor=/recursor=8.8.8.8/g' /etc/powerdns/pdns.conf
      sudo sed -i 's/allow-recursion=127.0.0.1/allow-recursion=127.0.0.1,192.168.1.0\/24/g' /etc/powerdns/pdns.conf
      sudo service pdns restart
      sudo apt-get install dnsutils
    • vim /etc/powerdns/bind/example.com.zone
      $ORIGIN example.com     ; base for unqualified names
      $TTL 1h                 ; default time-to-live
      @                       IN      SOA ns.example.com hostmaster.example.com (
                                      1; serial
                                      1d; refresh
                                      2h; retry
                                      4w; expire
                                      1h; minimum time-to-live
                              )
                              IN      NS      ns
                              IN      A       192.168.1.15
      ns                      IN      A       192.168.1.15
    • nslookup example.com localhost
    • Then in your device in network configuration add Rpi IP address to list of DNS servers. Also in search domain enter: “example.com”
  • Firewall
    • sudo apt-get install ufw
      sudo ufw allow 22 #ssh
      sudo ufw allow 21 #ftp
      sudo ufw allow 53 #dns
      sudo ufw allow 137,138,139,445/tcp #samba
      sudo ufw allow 80 #www
      sudo ufw allow 8080 #www
      sudo ufw allow 111,2049/tcp #port mapper (nfs, glusterfs)
      sudo ufw allow 8554 #vlc
      sudo ufw allow 631 #cups
      #glusterfs
      sudo ufw allow 24007,24008/tcp
      sudo ufw allow 24009,24010,24011/tcp
      sudo ufw allow 49152,49153,49154/tcp
      sudo ufw allow 38465,38466,38467/tcp
      sudo ufw allow 24008/tcp
      sudo ufw enable
    • fail2ban – this I don’t yet cover here, as not yet sure how it works. Was banning myself too much ;-)
  • Software watchdog of network connectivity to your home router
    • */5 * * * * /home/foo/bin/soft-watchdog-wifi.sh
    • In order for Wifi to reconnect see this solution: http://raspberrypi.stackexchange.com/questions/4120/how-to-automatically-reconnect-wifi?newreg=e44a9ccb623b402094502f27c554e1c5
    • cd /etc/ifplugd/action.d/
      mv ifupdown ifupdown.original
      cp /etc/wpa_supplicant/ifupdown.sh ./ifupdown
      sudo reboot
  • Usenet with Sabnzbd
    • http://www.howtogeek.com/142249/how-to-turn-a-raspberry-pi-into-an-always-on-usenet-machine/
      sudo apt-get install sabnzbdplus par2
  • FTP server for backup of my iPhone pics
    sudo apt-get install vsftpd
    sudo adduser ftpsecure
    sudo vi /etc/vsftpd.conf
    #listen=YES
    #allow_writeable_chroot=YES
    #local_umask=022
    #write_enable=YES
    #chroot_local_user=YES
    #nopriv_user=ftpsecure
    #chroot_list_enable=YES
    #chroot_list_file=/etc/vsftpd.chroot_list
    
    sudo vi /etc/vsftpd.chroot_list
    foo
    sudo service vsftpd restart
  • For iPhone iOS app PhotoSync in order to backup pics/videos via ftp this has to be also done (if one wants other than ~/Pictures dir only)
    mount --bind /foo/bar/archived-synced/ /home/foo/Pictures/
  • Photos management

    https://www.linux.com/learn/how-sort-and-remove-duplicate-photos-linux

    sudo apt-get install  fdupes exiftool
  • NFS
    sudo apt-get install nfs-kernel-server nfs-common portmap
    sudo update-rc.d rpcbind enable && sudo update-rc.d nfs-common enable
    sudo vi /etc/exports
    /mnt/foo/bar/ *(rw,sync,no_root_squash,no_subtree_check)
    sudo exportfs -av
    sudo service nfs-kernel-server restart
    sudo service rpcbind restart
  • HDD maintenance
    sudo apt-get install smartmontools gsmartcontrol
    sudo smartctl --all /dev/sdd
    
    touch /forcefsck
    sudo shutdown -rF now
    
    sudo apt-get install gnome-disk-utility
    sudo gnome-disks #somehow on raspbian it's missing :-?
    sudo gsmartcontrol
  • crontab logs
    • sudo vi /etc/rsyslog.conf
      #ucomment #cron
      sudo /etc/init.d/rsyslog restart
  • security
    • list all services running on the system
      sudo service --status-all
  • screenfetch – show system details on a console
    wget https://raw.github.com/KittyKatt/screenFetch/master/screenfetch-dev
    chmod a+rx screenfetch-dev
    ./screenfetch-dev
  • dd with progress
    dd if=/dev/zero | pv --size 16g | dd of=/dev/sdb
    dcfldd if=/tmp/in of=/tmp/out
  • camera
    sudo modprobe bcm2835-v4l2
    echo bcm2835-v4l2 >> /etc/modules
    sudo apt-get install vlc v4l-utils motion
    raspivid -o - -t 0 -n -w 1280 -h 720 | cvlc -vvv stream:///dev/stdin --sout '#rtp{sdp=rtsp://:8888/}' :demux=h264
  • sound
    echo snd-bcm2835 >> /etc/modules
    vi /etc/asound.conf
    
    pcm.!default {
      type hw    
      card 0 }
    ctl.!default {
    type hw
    card 0   }
  • print server
    sudo apt-get install cups
    sudo cupsctl --remote-any
    sudo usermod -a -G lpadmin nthx
    sudo apt-get install avahi-discover #for air print
    #canon ip4700 works
    sudo /etc/init.d/cups restart 
    browser http://localhost:631/
    #add your driver
  • purge some extra space
    sudo apt-get install localepurge deborphan wajig 
    sudo localepurge
    sudo apt-get autoremove
    sudo apt-get autoclean
    sudo apt-get clean
    sudo apt-get purge wolfram-engine minecraft-pi sonic-pi gnome-accessibility-themes gnome-themes* gnome-icon-theme-extras gnome-icon-theme-symbolic gnome-games*
    
    wajig large #and analyze..
    baobab #and analyze
  • Process Canon RAW files
    sudo apt-get install ufraw ufraw-batch
    ufraw-batch --out-type png *.crw

 

  • VNC
    sudo apt-get install xtightvncviewer
    sudo apt-get install tightvncserver
  • Power off Raspberry PI
    sudo poweroff

 

Upgrading to Raspberry PI 2

  • on existing Rpi1 apt-get update && apt-get upgrade && apt-get dist-upgrade
  • copy entire SD card to another dd if=/dev/mmcblk0 of=backup-of-mmcblk0
  • mount /dev/mmcblk0p2 /mnt/memcard
  • vi /etc/hostname #modify hostname
  • vi /etc/hosts #modify hostname
  • ssh-keygen
  • raspi-config

Hacking: Custom Rails Assets Compressor

We came on issue:

In production environment we still want to make JavaScript not readable, and compressed into one file, but just for now I need it better suited for AirBrake debugging, so new lines are preserved, and white space too..

As we now as of Rails 3 it uses assets pipeline for doing magic with javascript. So what I had to do is to hack config/environments/production.rb a bit with this:

Above code still produces one big JavaScript file, but this time human can easily read it and see a line where possible JavaScript error occurs.
Instead of creating new compressor instance, one can do it via config option. But somehow I failed to use it properly

config.assets.js_compressor_options = {:except => [‘$super’]}

Basicly I found this idea from here: https://github.com/rails/rails/issues/2693

Doc on Uglifier gem options

My Law #1: DRY .. or not

I think that’s the rule that drives my programming style the most is:

#1: Keep it DRY: Don’t Repeat Yourself

more here http://media.pragprog.com/articles/may_04_oo1.pdf from smarter than me

But there are 2 very different parts of the code where DRY might and might not be applied: programmer’s code and “high level” domain logic

A) Programmer’s code

I say, it’s a place quite deep in your code, rather related to implementation and less to design. Those are rather controllers and views, and deep parts of model implementation, every helper and utility class. Details far away from actual functional requirements, use cases, business logic.

So there – in programmer’s world – I spend lots of time thinking how not to write the same/similar code twice. Really, I can even spend 10 hours or few days of thinking and writing ZERO code..
.. because I’d rather shoot myself in a foot with a railgun than used dumb-COPY-&-PASTE. We nowadays know it’s PLAIN WRONG, do we..

  • copy & paste exact parts of code is lazy (“lazy” the wrong way as opposite to being positively lazy as in yagni)
  • copy & paste similar parts of code might look and is quick solution at first, but it’s not. Someone WILL try to understand and refactor it later and WTF you
  • it’s about respect to other developers
  • it’s about write-once, read-100-times. It’s been always this way. So why bothering people after you with your unsolved problems
  • copy & paste is a smell for immediate action: extract similar code into a method, pass parameters, whatever.. make duplication gone
  • and obviously if a change must be later done to all duplicates, it must be made in X places instead of ONE

So this is BAD code. Effect of dumb COPY&PASTE&CHANGE-ONE-VAR

B) Domain Code

.. we must make distinction on the “A)” code made for programmers and “B)” code meant to describe our natural world, our domain specific requirements.
This is a “high-level” domain code, possibly close to what customer say and do; to what their use cases describe. So it should really tell what it does.

Such code should not distract reader by forcing the reader to jump & dive around in & out of methods to see how things are implemented. I’d have all code served in front of me instead

In my opinion in domain code it is more important to see the intent of the code than to be pure DRY. I must admit I don’t make some strict rule on that yet. It’s rather my intuition today.

Applying all the fancy programming patters and refactorings just to make code few lines shorter does opposite and makes intent, the flow, the algorithm not clearly visible.

I say there are 2 cases where I’m not always fully DRY

  • acceptance tests – simulating user interacting directly with application (via browser mouse clicks, keyboard, triggering events, etc)
  • use cases – the most important domain code, domain algorigthms, business logic

So I would live with such code..

.. and I think I would also live with this one, but maybe bit less comfortable in the long term..
..although at first those 3 cases now look shorter and more readable, but they also PRETEND that they do something by a nice method naming. In fact those methods might do sth completely different. They hide details, but those details ARE IMPORTANT, so should not be hidden

PS. .. methods longer than 10-20 lines might be OK for domain code, but they’re rather on the longer side