Update: You might want to look at this post instead:
http://verahill.blogspot.com.au/2013/02/331-full-linux-install-on-usb-stick.html -- it covers setting up Arch with LXDE (very, very basic set-up -- more openbox than lxde) and wicd
I'll update this post once I've got a good solution to setting up network on headless boxes (i.e. a way of bringing up multiple interfaces without knowing their mac addresses)
Original post:
Note: what follows is what I've 'discovered' while learning. If you have suggestions, feel free to post comments. If you have questions, be aware that I'm only a beginning at Arch myself and will probably not have much advice to offer.
The problem: I have a headless server running 32 bit debian. I don't actually use it much, and so I figured I might as well use it to explore Gentoo or Arch. Given that it's a single core atom I didn't want to risk spending hours compiling things just to get things up and running (Feb/March are busy days at Australian Unis) and I figured that Arch, with it's version of ports, ABS, is a better choice for now.
I'm also curious about
systemd, which arch uses by default. (that curiosity has currently turned to frustration)
Why Arch?
I do like my debian, but you need to challenge yourself every now and again. I can also see how a more 'sparse' distro might be a good candidate for my cluster nodes -- less overhead is a good thing. But before doing that I need a test case.
Also, even though I've been using debian I occasionally pay a visit to the Arch wiki and forum when I run into trouble with software that I've compiled myself -- Arch is a lot more bleeding edge than debian (which emphasizes stability), and the information there is often quite good.
Well then...
The easiest way (needing little preparation) by far to install arch would be to use ArchBang which is fast, pretty and functional. I don't need the graphical environment, and I want the learning experience. Otherwise I'd definitely give that a look as well:
http://archbang.org/
We'll follow this guide:
https://wiki.archlinux.org/index.php/Install_from_Existing_Linux
We'll use method "2: Chroot into LiveCD image".
I've ripped out the harddrive from the headless box and have attached it via USB to my main desktop, which runs Debian Testing.
I've rewritten this guide a couple of time -- not everything worked smoothly from the beginning -- so if it's unreadable and confusing, let me know. Also, due to the lack of versioning in blogspot I have had to try to recover/rewrite from memory, which annoys me.
A word of warning: at one point when working in a chroot I accidentally did grub-install /dev/sda instead of /dev/sdc. I then did update-grub in the main system and rebooted. I should've done grub-install /dev/sda again but from the host system. Anyway, you might screw things up, so a first precaution will be to burn a live CD of some linux distro that you can use to rescue your system with if you mess things up too badly. I'm a debian guy, but I found that the Ubuntu Rescue Remix (
http://ubuntu-rescue-remix.org/) was a pretty good thing to have lying around.
Overview:
1. Nuke the existing file system (not necessary, but easier)
2. Get the iso and unsquash it
3. Mount the unsquashed image using chroot, and mount your hdd under it. Get packages
4. Chroot inside the chroot and install the bootloader
5. Set up network
Get started
Format/Prepare your harddrive:
In this case I'm using a 40 Gb hard drive. Since it's so small I'll just partition it to hold one / partition and one /swap partition. We'll make the swap partition 1 Gb which should be plenty, given that the box has 512 Mb RAM.
Make sure that you leave enough space before you partition -- 1 Mb is overkill, but is something you can afford. In my original attempt I used palimpsest to format my drive and ended up having to shrink the partition using gparted. Better to use fdisk which may be slightly more challenging, but will give you full control.
Remove the harddrive from your target box, and attach it to your running linux desktop e.g. via USB (or by opening the case and hooking it up via sata/pata). If it automounted, do
df -h so see what device it is (here /dev/sdc), otherwise just do
ls /dev/sd* before and after it's attached.
df -h
Filesystem Size Used Avail Use% Mounted on
/dev/sdc1 36G 15G 20G 43% /media/steelhead
Unmount it:
sudo umount /media/steelhead
We now know that our disk is /dev/sdc, so let's get cracking with fdisk
fdisk -u -l /dev/sdc
Disk /dev/sdc: 40 GB, 40007761920 bytes
255 heads, 63 sectors/track, 4864 cylinders, total 78140160 sectors
Units = sectors of 1 * 512 = 512 bytes
Device Boot Start End Blocks Id System
/dev/sdc1 * 63 78140159 39070048 83 Linux
We want our swap to be 1 Gb. (40007761920 bytes /4864 cylinders)/(1024*1024*1024)=.00766038894653320312 Gb per cylinder or ca 130.5 cylinders per Gb. Our first partition will start at cylinder 2 and run until cylinder (4864-131=)4733.
sudo fdisk /dev/sdc
Command (m for help): d
Partition number (1-1): 1
Command (m for help): n
Partition type
e extended
p primary partition (1-4)
p
First cylinder (default 0cyl): 2
Last cylinder or +size or +sizeMB or +sizeKB (default 4863cyl): 4733
Command (m for help): n
Partition type
e extended
p primary partition (1-4)
p
First cylinder (default 0cyl): 4735
Last cylinder or +size or +sizeMB or +sizeKB (default 4863cyl):
Command (m for help): w
sudo fdisk /dev/sdc
Command (m for help): p
Disk /dev/sdc: 40 GB, 40007761920 bytes
255 heads, 63 sectors/track, 4864 cylinders
Units = cylinders of 16065 * 512 = 8225280 bytes
Device Boot Start End Blocks Id System
/dev/sdc1 2 4734 38025792 83 Linux
Warning: Partition 1 does not end on cylinder boundary.
/dev/sdc2 4735 4864 1036192 83 Linux
Command (m for help): a
Partition number (1-2): 1
Command (m for help): t
Partition number (1-2): 2
Hex code (type L to list codes): 82
Changed type of partition 2 to 82 (Linux swap)
Command (m for help): w
The cylinder boundary warning is why we started the next partition on cylinder 4735, so as to avoid overlap. 'a' makes the first partition bootable. 't' creates the swap fs.
Create the file system for partition 1:
sudo mkfs.ext4 /dev/sdc1
sudo mkswap /dev/sdc2
Get the iso:
sudo apt-get install bittorrent
cd ~/Downloads
btdownloadcurses https://www.archlinux.org/iso/2013.01.04/archlinux-2013.01.04-dual.iso.torrent
If you're company/isp/whatever has a blanket ban on P2P (e.g. bittorrent) download the file using
regular http, e.g.
cd ~/Downloads
wget http://mirror.aarnet.edu.au/pub/archlinux/iso/2013.01.04/archlinux-2013.01.04-dual.iso
However you downloaded it, do:
sudo apt-get install squashfs-tools
sudo mount -o loop archlinux-2013.01.04-dual.iso /mnt
unsquashfs -d /tmp/squashfs-root /mnt/arch/i686/root-image.fs.sfs
This is for a 32 bit install. Most likely you'll want the 64 bit, so change i686 to
x86_64 for that. Also note that the unsquashed image is
1.4 Gb so make sure you put it somewhere with sufficient space.
Continue:
sudo umount /mnt
sudo mount -o loop /tmp/squashfs-root/root-image.fs /mnt
sudo mount -t proc none /mnt/proc
sudo mount -t sysfs none /mnt/sys
sudo mount -o bind /dev /mnt/dev
sudo mount -o bind /dev/pts /mnt/dev/pts
sudo cp /etc/resolv.conf /mnt/etc/resolv.conf
sudo chroot /mnt
[root@beryllium /]#
You're now in the chroot.
In the chroot:
mount /dev/sdc1 /mnt
mkdir /run/shm
Since
I am installing 32 bit Arch from a 64 bit host, I had to edit
/etc/pacman.conf using nano and change
23 Architecture = auto
to
23 Architecture = i686
If you are installing 64 bit Arch from a 64 bit host
you don't need to edit anything. Also, the only editor installed by default is
nano, not vi, for some reason
.
Finally, edit
/etc/pacman.d/mirrors and copy/paste (ctrl+k, ctrl+u) the nearest/most logical mirror to the beginning of the file.
pacman-key --init
pacman-key --populate archlinux
pacstrap /mnt base base-devel vim grub-bios openssh
==> Creating install root at /mnt
==> Installing packages to /mnt
warning: database file for 'core' does not exist
warning: database file for 'extra' does not exist
warning: database file for 'community' does not exist
:: Synchronizing package databases...
core 105.1 KiB 15.8K/s 00:07 [##################] 100%
[..]
Total Download Size: 163.59 MiB
Total Installed Size: 603.01 MiB
[..]
I got a couple of errors above re file systems (during grub init) that arch had no business looking at. I don't think it matters since the next chroot is what's important.
pacman -Syy
genfstab -p /mnt >> /mnt/etc/fstab
cat /mnt/etc/fstab
#
# /etc/fstab: static file system information
#
#
# UUID=ae73518f-5675-486e-8cdd-6579c528ab72 LABEL=steelhead
/dev/sdc1 / ext4 rw,relatime,data=ordered 0 1
# UUID=f25a484c-e8e2-4ead-808b-96dd5e915020
/dev/sda5 none swap defaults 0 0
Two problems here:
* Since this will be the only hdd on the new system the root partition is probably
/dev/sda1. Change the sdc1 to sda1 above OR use UUID
* Likewise, the swap will be the current sdc2 but the future sda2. Alternatively, get the UUID via blkid.
Here's my new two-line version of fstab with uuid:
UUID=ae73518f-5675-486e-8cdd-6579c528ab72 / ext4 rw,relatime,data=ordered 0 1
UUID=a12b484c-f2d2-4edd-8d8b-76ee6f725020 none swap defaults 0 0
Continue:
arch-chroot /mnt
which gives
sh-4.2#
You're now in a chroot inside a chroot.
A chroot within a chroot:
pacman -Syy
pacman-key --init
pacman-key --populate archlinux
ln -s /usr/share/zoneinfo/Australia/Melbourne /etc/localtime
echo "kookaburra" > /etc/hostname
Kookaburra is the hostname of the new Arch box.
Edit
/etc/pacman.conf and change Architecture from
auto to
i686 if you need to.
Edit
/etc/locale.gen and uncomment the locales you want. For me
en_AU.UTF-8 UTF-8
en_GB.UTF-8 UTF-8
en_US.UTF-8 UTF-8
Continue working on boot:
locale-gen
echo 'LANG="en_AU.UTF-8"'>/etc/locale
echo 'KEYMAP=us'> /etc/vconsole.conf
mkinitcpio -p linux
==> Building image from preset: 'default'
-> -k /boot/vmlinuz-linux -c /etc/mkinitcpio.conf -g /boot/initramfs-linux.img
==> Starting build: 3.7.4-1-ARCH
-> Running build hook: [base]
[..]
==> Creating gzip initcpio image: /boot/initramfs-linux-fallback.img
==> Image generation successful
grub-mkconfig -o /boot/grub/grub.cfg
Generating grub.cfg ...
Found linux image: /boot/vmlinuz-linux
Found initrd image: /boot/initramfs-linux.img
done
Check
/boot/grub/grub.cfg to see that it exists and that it doesn't look like it's about to blow up.
Double-check the uuid vs fstab. Check the 'root'. Mine was wrong. I changed it in
/boot/grub/grub.cfg by hand, which isn't recommended but we'll deal with that later.
In
/boot/grub/grub.cfg change
hdX to whatever the correct setting is (
counting starts at 0) e.g.
set root='hd0,msdos1'
since
/dev/sdc in the future will be the only hdd. Changing this file by hand is untenable in the long run, but our goal is to boot and then regenerate the
grub.cfg at a later stage.
grub-install /dev/sdc
Installation finished. No error reported.
Then continue -- in this case we're working with a headless box so we want openssh-server and all that:
passwd
Enter new UNIX password:
Retype new UNIX password:
passwd: password updated successfully
pacman -S net-tools ifplugd dialog sudo wireless_tools wpa_supplicant wpa_actiond
systemctl enable sshd.service
systemctl enable net-auto-wired.service
systemctl enable net-auto-wireless.service
cp /etc/network.d/examples/ethernet-dhcp /etc/network.d/ethli
Edit the
/etc/network.d/ethli file as shown in the next section.(the ethli name holds no significance)
adduser verahill -m
Edit
/etc/sudoers and add:
verahill ALL=(ALL) ALL
pacman -S pkgtools mlocate htop screen elinks
Time to exit:
sh-4.2# exit
exit
[root@beryllium /]# umount /mnt
[root@beryllium /]# exit
You're now back in your normal host filesystem, and unmount the rest:
sudo umount /mnt/proc
sudo umount /mnt/sys
sudo umount /mnt/dev/pts
sudo umount /mnt/dev
sudo umount /mnt
At this point you have a bootable system. I attached the hdd to my laptop using USB, and chose to boot from it. Went fine. However, it turns out that networking in arch and/or using systemd is very different from debian and initd.
Networking:
Networking should be one of the easiest things in the world to set up, since if you have network access everything else will eventually sort itself out. No network means no remote access via ssh if the screen/keyboard/mouse get screwed up. No network means that you can't install anything. No network means that you can't go online and look up solutions.
initd was easy -- you checked your udev rules, then edited /etc/network/interfaces and added an auto eth0 line followed by e.g. iface eth0 inet dhcp or a more extensive static definition. It was easy.
So I'm a bit frustrated that systemd seems to make the whole process of managing network interfaces so much more difficult. At least for a newcomer.
With
systemd your interfaces may not have simple names like eth0 right off the bat, but may have names like enpS08 instead -- it does make things a bit more difficult and unpredictable -- remember that my goal is to get a headless box up and running and that I have no way of getting any error messages -- openssh will simply have to work from the start. I mean, there's a certain logic to systemd, but there are plenty of frustrating issues with it too if you're used to chucking start-up commands in rc.local and setting up your own network devices.
Some of this stuff you could do by hand on a running system, but that's not very helpful when you are working with a headless box where your only option is to connect via ssh (technically I could do rs-232 but I can't find a cable).
Anyway.
Create
/etc/udev/10-persisten-net.rules
SUBSYSTEM=="net", ATTR{address}=="00:2e:9e:2e:bb:20", KERNEL=="eth*", NAME="ethli"
SUBSYSTEM=="net", ATTR{address}=="00:e2:bb:be:d4:c8", KERNEL=="wlan*", NAME="wlan0"
and put the mac addresses of you interfaces in it.
Edit
/etc/conf.d/netcfg to use the correct WIRED_INTERFACE,
NETWORKS=(ethli ethkb5 ethkb3 wpa-wireless)
WIRED_INTERFACE="ethli"
WIRELESS_INTERFACE="wlan0"
ethkb5, ethb3 and wpa-wireless are other files that I've set up in
/etc/network.d/, although at this point they are pretty darned useless -- I can define plenty of profiles, but I can only define a single WIRED_INTERFACE from what I can tell. So only one interface will be started by netcfg.
Copy
/etc/network.d/example/ethernet-dhcp to
/etc/network.d/ethli, and edit the interface name.
CONNECTION='ethernet'
DESCRIPTION='A basic dhcp ethernet connection using iproute'
INTERFACE='ethli'
IP='dhcp'
Do the same for any other profiles.
For wireless, all you need to do is copy
/etc/network.d/examples/wpa-wireless to
/etc/network.d/ and add the password in clear text (i.e. no need to use wpa_password). Change the permissions so that it's 'safe'.
Here's my wpa-wireless
CONNECTION='wireless'
DESCRIPTION='A simple WPA encrypted wireless connection'
INTERFACE='wlan0'
SECURITY='wpa'
ESSID='verahillunwired'
KEY='sadfUsfdjdsfH87j'
IP='dhcp'
The wired network should now start on boot. To launch it manually, just do
sudo netcfg ethli
This is where I'm currently at:
* arch works fine when I boot it by attaching the hdd via usb to a laptop or desktop and booting off of it. I have working internet and the sky's the limit to what can be done
* I can't get it to boot my headless box (or at least not to get a working network connection), and because it's completely headless (it's a server with only eth ports and an RS 232 port) I have no idea why. The logging in systemd leaves a lot to be desired it seems. I'm waiting for an rs-232 cable to arrive via ebay, so we'll see.
The two possibilities that I'm entertaining right now is that either there's an issue with the network devices or...well, I don't know. I'm also getting tired of netcfg and will probably switch to wicd -- it's not quite what I want, but at least I know that it works.
But more about that some other time...
Error 1:
# pacstrap /mnt
==> Creating install root at /mnt
mount: mount point /mnt/dev/shm is a symbolic link to nowhere
==> ERROR: failed to setup API filesystems in new root
Solution:
mkdir /run/shm
On debian /dev/shm points to /run/shm via a symlink, so your chroot has a dead link.
Error 2:
error: key "E62F853100F0D0F0" could not be looked up remotely
error: psmisc: key "FCF2CB179205AC90" is unknown
error: key "FCF2CB179205AC90" could not be looked up remotely
error: reiserfsprogs: key "7F2D434B9741E8AC" is unknown
error: key "7F2D434B9741E8AC" could not be looked up remotely
Solution:
pacman-key --init
pacman-key --populate archlinux
You need to get all the gpg keys so you can check the package signatures.
Error 3:
warning: database file for 'core' does not exist
warning: database file for 'extra' does not exist
warning: database file for 'community' does not exist
Solution:
pacman -Syy
Not sure, but probably due to me interrupting pacman rather rudely with ^C at some point.
Error 4:
# arch-chroot /mnt pacman -S grub-bios
error: failed to prepare transaction (package architecture is not valid)
:: package grub-bios-2.00-1-i686 does not have a valid architecture
Solution:
pacstrap /mnt grub-bios
And then skip the arch-root command
Error:
grub-install /dev/sdc
/usr/sbin/grub-bios-setup: warning: your embedding area is unusually small. core.img won't fit in it..
/usr/sbin/grub-bios-setup: warning: Embedding is not possible. GRUB can only be installed in this setup by using blocklists. However, blocklists are UNRELIABLE and their use is discouraged..
/usr/sbin/grub-bios-setup: error: will not proceed with blocklists.
Solution:
You partitioned your system without leaving enough space before the first partition. In my case I had 32 sectors*512 bytes.
sudo apt-get install gparted
gparted
Start gparted and shrink the partition. I put 2 Mb (probably overkill) of free space in front, and aligned to cylinder.