Jani Hur's picture

I have been trying to find out how application specific values can be gathered during the first boot and then later used to configure the application.

I guess this is done with inithooks: http://www.turnkeylinux.org/docs/inithooks but I fail to see how the magic happens.

E.g. I have been checking jenkins. In overlay/usr/lib/inithooks/firstboot.d/40jenkins

#!/bin/bash -e
# set jenkins admin password

. /etc/default/inithooks

[ -e $INITHOOKS_CONF ] && . $INITHOOKS_CONF
$INITHOOKS_PATH/bin/setpass.py admin --pass="$APP_PASS"

Here the APP_PASS variable has got the value somehow automatically ? The setpass.py script is part of TKLCore as it's not found from jenkins repository ? How TKLCore knows how to configure jenkins ? Obviously I have to set my application specific settings myself ? How the inithooks knows what settings I want to ask from the user ?

Forum: 
Jeremy Davis's picture

I can't speak for Jenkins, but the point of having them as variables is so that they can be preseeded (e.g. by the values entered in the TKL Hub pre-launch WebUI). If the variables have no value then the firstboot scripts will ask...

TBH I just had a look and you appear to be right (in the fact that setpass.py doesn't seem to be a part of Jenkins itself) so as you suggest perhaps it's a part of Core (although TBH I wouldn't think that Core would need it...). Unfortunately I (still) haven't had time to play with TKLDev yet and so can't help much in that regard, but it must be somewhere and I suspect that you may be able to leverage that same script for your own password creation...

inithooks will just run each script in ../firstboot.d (in order). And as I said above, if a value hasn't already been fed in (via preseeding) then it will ask... Different appliances will have different firstboot scripts...

Jani Hur's picture

I checked Gitlab's inithooks and finally figured this out.

There is two components that contains general boilerplate code and appliance specific code.

First is inithooks/firstboot.d/40oracle:

#!/bin/bash -e

. /etc/default/inithooks

[ -e $INITHOOKS_CONF ] && . $INITHOOKS_CONF
$INITHOOKS_PATH/bin/oracle.py --dbpass="$DB_PASS"

This file is the hook so that appliance specific inithooks/bin/oracle.py file will be executed. The value for DB_PASS variable can be set in preseeding (in file /etc/inithooks.conf), but I don't use preseeding so in my case it is unnecessary. The name of DB_PASS has no magic and it could be e.g. FOO instead.

If the value has not been preseeded then inithooks/bin/oracle.py uses dialog_wrapper Python module to ask it from the user. Below is an example of the minimal script that reads a single piece of information from a user:

#!/usr/bin/python
"""Set Oracle XE SYS-user password for silent installation

Option:
--dbpass= unless provided, will ask interactively
"""

import sys
import getopt

from dialog_wrapper import Dialog

def usage(s=None):
    if s:
        print >> sys.stderr, "Error:", s
    print >> sys.stderr, "Syntax: %s [options]" % sys.argv[0]
    print >> sys.stderr, __doc__
    sys.exit(1)

def main():
    try:
        opts, args = getopt.gnu_getopt(sys.argv[1:], "h",
                                       ['help', 'dbpass='])
    except getopt.GetoptError, e:
        usage(e)

    dbpassword = ""
    
    for opt, val in opts:
        if opt in ('-h', '--help'):
            usage()
        elif opt == '--dbpass':
            dbpassword = val

    if not dbpassword:
        d = Dialog('TurnKey Linux - First boot configuration')
        dbpassword = d.get_password(
            "Oracle XE SYS Password",
            "Enter new password for the Oracle XE SYS-user.")

    #
    # appliance specific code that uses dbpassword variable goes here
    #

if __name__ == "__main__":
    main()

All this is in fact described in http://www.turnkeylinux.org/docs/inithooks but it took me some time understand that.


Add new comment