Subject: [alpine-devel] Unattended Installation Ideas for 2.1

From: "Matt Smith" <[email-masked]>
Date: Fri, 13 Aug 2010 22:12:01 -0500 (CDT)

Hello,

On the topic of implementing an unattended installation, here's what I've come
up with, in part by Natanael Copa.

The concept work-flow at the moment, goes something like this:

1. The user will obtain "alpine-iso" via git.

2. A new ISO configuration will be created, e.g.:

   ~/alpine-iso$ cp alpine.conf.mk alpine-unattended.conf.mk
   ~/alpine-iso$ cp alpine.packages alpine-unattended.packages
   ~/alpine-iso$ sed -ri "s/^(ALPINE_NAME[ \t]+:= alpine)/\1-unattended/" alpine-unattended.conf.mk
   ~/alpine-iso$ echo "UNATTENDED_DIR := unattended" >> alpine-unattended.conf.mk
   ~/alpine-iso$ echo "UNATTENDED_SCRIPT := main.sh" >> alpine-unattended.conf.mk

   The above unattended files could also be included by default in alpine-iso.

3. At a minimum, UNATTENDED_DIR and UNATTENDED_SCRIPT would be created.
   This could be as simple as the following:
   ~/alpine-iso$ mkdir unattended && cd unattended
   ~/alpine-iso/unattended$ touch main.sh && chmod +x main.sh
   ~/alpine-iso/unattended$ echo -en "#!/bin/sh\n\
                                      /sbin/setup-disk --accept-defaults\n" > main.sh

   Complex and simple examples (such as the above) could also be included in
   alpine-iso.

4. Build the ISO:
   ~/alpine-iso/unattended$ cd ..
   ~/alpine-iso$ make PROFILE=alpine-unattended iso

5. Burn and use.

Here are some extra notes and recommendations:

=> I recommend that we make the system "free-form," allowing for much
   flexibility.  I like this idea for two reasons:
     1) The implementation will be simple.
     2) It will be relatively straight-forward for the user; they will do
        everything they would normally do from the installation's "LiveCD"
        environment, as well as, e.g., configuring the installed system for
        networking with an IP address and OpenSSH.  All in an automated,
        non-prompting fashion.
=> The UNATTENDED_SCRIPT should be executed at the end of the ISO's boot
   process, allowing the user to do everything from custom partitioning to
   networking.
=> The UNATTENDED_SCRIPT can source other shell scripts (like any other shell
   script), for use of common functions.  (One handy function would be the one
   I've created already that makes it easy to execute lengthy commands via
   chroot.)
=> The UNATTENDED_SCRIPT can call other scripts (like any other shell script),
   perhaps based on certain conditions (e.g., if it's DHCP IP is x.x.x.x,
   set the hostname accordingly, and add specific packages for this system).
=> When these scripts are absorbed into the initrd created by the 'make'
   process, file permissions should be retained.  Granted, we will need to
   "chown -R root:root alpine-iso/unattended" before it's inclusion, this gives
   the user the possibility of "disabling" scripts simply by removing the
   execute permission from a script.
=> We should add some sort of universal "accept the defaults" option to the
   /sbin/setup-* scripts (e.g. setup-disk), such as "--accept-defaults."
   (I've already got a basic version of setup-disk that does this.)
=> The process responsible for eventually executing the user's main script
   should first warn the user about what's going to happen and sleep for at least
   30 seconds or more, giving the user a chance to cancel the unattended setup,
   thus lessening the chance for accidental loss of data, should such a CD/ISO
   be booted on a production system.
=> When the unattended install is complete, we could either "halt" or "reboot."
   Assuming the CD/ISO will still be present after doing an automatic reboot, 
   we would need to do some sort of check to see if a prior unattended install
   has completed.  If it has, proceed to booting the MBR of the first HDD, or,
   if the user knows in advance what to boot, perhaps that could be added as an
   option to the .conf.mk file.
   => For example:
      ON_FINISH=(halt|reboot)  # Maybe even make this a user-configurable script
                               # instead.
      ON_REBOOT_BOOT=sda
=> Also, I don't recommend updating the busybox passwd applet to accept passwords
   via an option or stdin for installing passwords to the installed system, as
   this could be a security risk if the CD/ISO was leaked.  Instead, shadow
   password hashes should be used and the {ROOT}/etc/shadow file updated directly.
   Perhaps the most secure way to generate a hash is to create a local dummy user,
   run passwd and extract the hash.  We could also modify passwd to allow us to
   locally generate a hash and echo it to stdout for inclusion in our scripts.

Later on, I think we should look into PXE booting with PXELINUX, with and/or
without unattended support.  Perhaps that part should be branched into a new
project, "alpine-pxe," or make it a Makefile target ("make PROFILE=alpine pxe"),
and rename "alpine-iso" to "alpine-image" or something similar.

Let me know what your thoughts are.

-- Matt Smith

---
Unsubscribe:  [email-masked]
Help:         [email-masked]
---

---

From: Natanael Copa <[email-masked]>
Date: Wed, 18 Aug 2010 16:54:05 +0200

> Hello,

Hi,

> up with, in part by Natanael Copa.

The goal is to make a bootable cdrom or USB that will run the install
for you and give you a running system.

The goal is that it should be easy for enduser to create such system and
it should be simple to understand whats going on.

> 1. The user will obtain "alpine-iso" via git.

I think it would be nice if the enduser would not need to create new iso
if the target was a bootable USB. In other words, it would be nice if it
would be enough to just copy a file to a bootable usb or something.

>    The above unattended files could also be included by default in alpine-iso.

We talked about this some really long time ago. The boot scripts used to
look for a localinit script on the boot media (iso image/usb) and if
found it was executed as last step in boot process.

We still have something similar with the /etc/init.d/local "service"
which executes /etc/rc.local

>         networking with an IP address and OpenSSH.  All in an automated,

freeform as in a simple shell script? like /etc/rc.local?

>    process, allowing the user to do everything from custom partitioning to

If you have a boot script called /etc/init.d/myscript

you can add 'rc_after=*' to /etc/conf.d/myscript and myscript will be
executed last.

>    I've created already that makes it easy to execute lengthy commands via

Ok, so you want stuff in more than a single file. You'd need a tar
archive then, like apkovl?

>    (I've already got a basic version of setup-disk that does this.)

I think it would be nice with some preseeds, that answers some of the
questions or all or tells the script "use default". User could be asked
the missing answers. That way you could make an half automated install,
where end user maybe only need to answer 1 question.

>       ON_FINISH=(halt|reboot)  # Maybe even make this a user-configurable script

Fedora/Redhat uses a boot option, "ks" to fire up the unattended
install. If you need enter an option at bootprompt it fire the thing up,
you would not need check if it was previously run. (even if thats
trivial to implemnt too).

And you normally want look at the screen to see that it properly boots
before you leave it unattended.

>    locally generate a hash and echo it to stdout for inclusion in our scripts.

once you have the hash its fairly simple to include it /etc/shadow. But
still, good point, not clear textwords in any config files or "preseeds"

> Let me know what your thoughts are.

First, let me explain what initramfs is supposed to do.
The only job for initramfs image is to mount root and execute init in
there, which starts up the sysmtem. So for an installed disk, this might
include load drivers for finding the disk (SATA, IDE or SCSI host
drivers) and loading the file system drivers (ext3 foexample). For a RAM
install, it also includes finding the apkovl, unpack it and install
packages in the package list in the apkovl to a tmpfs mount. If there
are no apkovl, it will set up a very minimal system, installing
alpine-base and set up a very minimal set of services to start at boot
(mdev, syslog etc).

Now, whatever we do, i would really prefer to not add lots of logic in
the initramfs, doing smart things based on magic files found. If we want
do something, it should happen after initramfs has handled over system
to normal boot.

For the unattended install problem, I think we can split it up in
atleast 3 parts:

1. something that kicks in a script at end of boot.
2. having preseeded answers to the setup-scripts.
3. optionally fix alpine-iso to include #1 and #2 on the iso (trivial)

Problem #1 can be solved in various ways:
a. ship an apkovl with the contents:
  /etc/rc.local
  /etc/runlevels/default/local -> /etc/init.d/local

(if rc.local's last thing it does is 'rc-update del local', then it will
not be execute next run)

b. we could have a boot script parse boot params to kernel and excute
stuff based on that

c. we could have a magic file on boot media, similar to apkovl, but
instead of beeing a tar archive it is a simple script that gets
autostarted. (like we did long time ago with localinit)

Since we already have a magic file (the apkovl) to trigger installation
of packages and executing init.d scripts i think I would prefer using
that. I'm open to options though.

For problem #2, i think we need some serious redesign of the setup
script framework for this to work. I'd like some file which holds the
answers for the questions or prompt user if answer is missing in file.
(or plain "accept-all-defaults")

We could also have an option to the master setup script that make it
spit out an unattended.conf or maybe an apkovl. I already had some
thought of running the setup scripts on an alternate root dir. That was
never really followed up though so I don't think it currently works.

I think we need figure out how to deal with #1 and #2 before we even
start talking about problem #3: modifying alpine-iso makefile.

Have a look at ho fedora does it:
http://fedoraproject.org/wiki/Anaconda/Kickstart

Debian have also some preseeds but they do lots of smarts in their
packages which we don't so I dont think we want go in debian direction
there.

Thanks for looking into this!

PS. I had some ideas and a proof-of-concept for an partially unattended
web based (ACF) setup wizard, that you could ship with a preseed with
answered questions. There are still leftovers in alpine-conf from the
script that fired up an initial dhcp server (after checking for other
dhcp servers on all interfaces first) and redirected all dns lookups to
the alpine box. The idea was that you started up the alpine on a
headless box, plugged a laptop to any interface via cross over cable,
fired up the web browser and configured the rest from there. Have a look
at the setup-alpine-web script.

---