Compare commits

...

39 Commits

Author SHA1 Message Date
brent s 7a2e66f1a2 manual update 2017-09-02 23:01:39 -04:00
brent s addd1cb65a updated todo 2017-08-20 04:33:15 -04:00
brent s ad0b36201b documentation bug 2017-07-27 14:40:24 -04:00
brent s 56cddb593a updating docs, unnecessary rm 2017-06-20 18:00:56 -04:00
brent s aea4f1b8e3 aif-config is... done? 2017-05-15 12:38:10 -04:00
brent s 372b51b1a6 holy cats. xml generation's almost done 2017-05-15 02:47:04 -04:00
brent s 3f8c626fca changing size attrib to stop 2017-05-15 02:46:24 -04:00
brent s d6f4548b88 client's coming along well, and have a working expect script to automate testing. next up, actual XML generation and writing it out 2017-05-14 12:07:39 -04:00
brent s 4172111fcd hoo man. heads up, those password hashes are all just "test" 2017-05-14 01:21:15 -04:00
brent s abaf931f37 having a view function is stupid, and cleaning up some things with the validation... next up, actually creating the XML (and handle converting from JSON, but that'll be easy to parse since it should be in the same format as the dict) 2017-05-13 08:11:59 -04:00
brent s c2e6fe1a04 debugging some verifying errors... 2017-05-13 07:27:58 -04:00
brent s e2f7b29287 okay. opts done. need to work on the other functionality now. still untested. 2017-05-13 06:06:53 -04:00
brent s ba9f1df347 ALMOST done... the conf-gathering part. the rest should be a breeze compared to this tedious nonsense. 2017-05-13 03:59:31 -04:00
brent s 07d1efb607 check-in 2017-05-12 23:00:17 -04:00
brent s 0b971e7b4f updating TODO 2017-05-11 23:30:41 -04:00
brent s 094623f710 commiting sample JSON input file fir aif-config.py 2017-05-11 23:27:22 -04:00
brent s cdc77545ea version bump for docs 2017-05-11 21:26:25 -04:00
brent s 74a3b35a16 update docs to use unified categorized project 2017-05-11 21:13:08 -04:00
brent s 9aa8061018 typo 2017-05-11 20:33:52 -04:00
brent s 29f6761017 config tool's sort of done. still need to actually generate xml from the conf dict and write to a file, then handle the other operations 2017-05-11 18:46:36 -04:00
brent s. fd8b26eb48 don't need these 2017-05-09 10:17:29 -04:00
brent s 75f5f4a46d beginnings of aif-config tool 2017-05-09 08:17:07 -04:00
brent s c16e365b04 updating kernel patch reference link 2017-05-08 12:05:14 -04:00
brent s bbb37c3c29 beginnings of a conf generator 2017-05-07 23:50:11 -04:00
brent s 479c6e65bc 15:37:38 < jthan> you should use say, not print.
15:37:43 < r00t^2> and why is that?
15:37:50 < jthan> get rid of your ugly \n
15:37:52 < jthan> saves space
15:37:54 < jthan> say is shorter
15:37:56 < jthan> no \n
15:37:57 < jthan> win win win
15:38:04 < r00t^2> lol, fucking fine
15:38:18 < jthan> 1337 perl
15:38:23 < jthan> jthan's specialty
2017-05-07 15:39:02 -04:00
brent s af5944bfea quick update to docs 2017-05-07 14:40:44 -04:00
brent s 0a88b4347c let's kick the example bdisk.ini to match the released 2017-05-07 13:23:20 -04:00
brent s 9278cd016a whoops, this is important 2017-05-07 13:08:46 -04:00
brent s 0a99af21ee i think i'm all ready for a 1.0 release... 2017-05-07 12:55:30 -04:00
brent s a28121cbab fixing that formatting a bit 2017-05-07 11:27:14 -04:00
brent s 32980870b7 notes on logging 2017-05-07 11:24:51 -04:00
brent s c64b800618 better log file 2017-05-07 11:21:44 -04:00
brent s ffedfaf684 updating todo 2017-05-07 01:03:06 -04:00
brent s f744d7e5d4 fixing package install bug 2017-05-07 00:17:26 -04:00
brent s 935df2083f disable reboot 2017-05-06 08:07:03 -04:00
brent s 09d6632e3a more quick fixes in prep for next tag 2017-05-06 07:57:10 -04:00
brent s df26d0394b oops 2017-05-06 07:51:06 -04:00
brent s 517d8135cc making some tweaks... 2017-05-06 07:49:23 -04:00
brent s b7ef1d5ea3 fixing systemd unit 2017-05-06 07:17:47 -04:00
18 changed files with 1934 additions and 117 deletions

1117
aif-config.py Executable file

File diff suppressed because it is too large Load Diff

26
aif.xsd
View File

@ -1,7 +1,7 @@
<?xml version="1.0" encoding="UTF-8" ?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
targetNamespace="https://aif.square-r00t.net"
xmlns="https://aif.square-r00t.net"
targetNamespace="http://aif.square-r00t.net"
xmlns="http://aif.square-r00t.net"
elementFormDefault="qualified">
<xs:annotation>
<xs:documentation>
@ -9,7 +9,7 @@
</xs:documentation>
</xs:annotation>
<!-- GLOBAL CUSTOM DATA TYPES -->
<xs:simpleType name="diskdev">
<xs:simpleType name="diskdev">
<xs:annotation>
<xs:documentation>
This element specifies a type to be used for validating storage devices, such as hard disks or mdadm-managed devices.
@ -104,16 +104,17 @@
</xs:simpleType>
<xs:simpleType name="pacuri">
<xs:restriction base="xs:anyURI">
<!-- <xs:restriction base="xs:anyURI"> -->
<xs:restriction base="xs:token">
<xs:pattern value="(file|https?)://.*" />
</xs:restriction>
</xs:simpleType>

<xs:simpleType name="scripttype">
<xs:restriction base="xs:token">
<xs:pattern value="(pre|post|pkg)" />
</xs:restriction>
</xs:simpleType>
<xs:simpleType name="scripttype">
<xs:restriction base="xs:token">
<xs:pattern value="(pre|post|pkg)" />
</xs:restriction>
</xs:simpleType>
<xs:simpleType name="bootloaders">
<xs:restriction base="xs:token">
@ -143,7 +144,7 @@
<xs:complexType>
<xs:attribute name="num" type="xs:positiveInteger" use="required" />
<xs:attribute name="start" type="disksize" use="required" />
<xs:attribute name="size" type="disksize" use="required" />
<xs:attribute name="stop" type="disksize" use="required" />
<xs:attribute name="fstype" type="fstype" use="required" />
</xs:complexType>
<xs:unique name="unique-partnum">
@ -263,8 +264,9 @@
</xs:sequence>
<xs:attribute name="timezone" type="xs:string" use="required" />
<xs:attribute name="locale" type="xs:string" use="required" />
<xs:attribute name="chrootpath" type="xs:string" user="required" />
<xs:attribute name="chrootpath" type="xs:string" use="required" />
<xs:attribute name="kbd" type="xs:token" />
<xs:attribute name="reboot" type="xs:boolean" />
</xs:complexType>
</xs:element>
<!-- END SYSTEM -->
@ -331,7 +333,7 @@
<xs:complexType>
<xs:attribute name="uri" type="scripturi" use="required" />
<xs:attribute name="order" type="xs:integer" use="required" />
<xs:attribute name="execution" type="xs:scripttype" use="required" />
<xs:attribute name="execution" type="scripttype" use="required" />
<xs:attribute name="user" type="xs:string" />
<xs:attribute name="password" type="xs:string" />
<xs:attribute name="realm" type="xs:string" />

View File

@ -16,6 +16,7 @@ try:
except ImportError:
import xml.etree.ElementTree as etree # https://docs.python.org/3/library/xml.etree.elementtree.html
lxml_avail = False
import datetime
import shlex
import fileinput
import os
@ -31,7 +32,7 @@ import urllib.response as urlresponse
from ftplib import FTP_TLS
from io import StringIO

logfile = '/root/log'
logfile = '/root/aif.log.{0}'.format(int(datetime.datetime.utcnow().timestamp()))

class aif(object):
@ -285,9 +286,11 @@ class aif(object):
aifdict['system']['locale'] = False
aifdict['system']['kbd'] = False
aifdict['system']['chrootpath'] = False
for i in ('locale', 'timezone', 'kbd', 'chrootpath'):
aifdict['system']['reboot'] = False
for i in ('locale', 'timezone', 'kbd', 'chrootpath', 'reboot'):
if i in xmlobj.find('system').attrib:
aifdict['system'][i] = xmlobj.find('system').attrib[i]
aifdict['system']['reboot'] = aifdict['system']['reboot'].lower() in ('true', '1')
# And now services...
if xmlobj.find('system/service') is None:
aifdict['system']['services'] = False
@ -335,7 +338,8 @@ class aif(object):
if xmlobj.find('scripts') is not None:
aifdict['scripts']['pre'] = []
aifdict['scripts']['post'] = []
tempscriptdict = {'pre': {}, 'post': {}}
aifdict['scripts']['pkg'] = []
tempscriptdict = {'pre': {}, 'post': {}, 'pkg': {}}
for x in xmlobj.find('scripts'):
if all(keyname in list(x.attrib.keys()) for keyname in ('user', 'password')):
auth = {}
@ -400,7 +404,7 @@ class archInstall(object):
disksize['max'] = subprocess.check_output(['sgdisk', '-E', d])
for p in partnums:
# Need to do some mathz to get the actual sectors if we're using percentages.
for s in ('start', 'size'):
for s in ('start', 'stop'):
val = self.disk[d]['parts'][str(p)][s]
if '%' in val:
stripped = val.replace('%', '')
@ -415,7 +419,7 @@ class archInstall(object):
for p in partnums:
size = {}
size['start'] = self.disk[d]['parts'][str(p)]['start']
size['end'] = self.disk[d]['parts'][str(p)]['size']
size['end'] = self.disk[d]['parts'][str(p)]['stop']
fstype = self.disk[d]['parts'][str(p)]['fstype'].lower()
if fstype not in fstypes.keys():
print('Filesystem type {0} is not valid. Must be a code from:\nCODE:FILESYSTEM'.format(fstype))
@ -425,7 +429,7 @@ class archInstall(object):
cmds.append(['sgdisk',
'-n', '{0}:{1}:{2}'.format(str(p),
self.disk[d]['parts'][str(p)]['start'],
self.disk[d]['parts'][str(p)]['size']),
self.disk[d]['parts'][str(p)]['stop']),
#'-c', '{0}:"{1}"'.format(str(p), self.disk[d]['parts'][str(p)]['label']), # TODO: add support for partition labels
'-t', '{0}:{1}'.format(str(p), fstype),
d])
@ -815,8 +819,8 @@ class archInstall(object):
else:
mirror = 'Server = {0}'.format(self.software['repos'][r]['mirror'])
newentry = ['[{0}]\n'.format(r), '{0}\n'.format(mirror)]
if self.software['repos'][r][siglevel] != 'default':
newentry.append('Siglevel = {0}\n'.format(self.software['repos'][r][siglevel]))
if self.software['repos'][r]['siglevel'] != 'default':
newentry.append('Siglevel = {0}\n'.format(self.software['repos'][r]['siglevel']))
if self.software['repos'][r]['enabled']:
pass # I know, shame on me. We want this because we explicitly want it to be set as True
else:
@ -849,8 +853,7 @@ class archInstall(object):
if self.software['packages']:
for p in self.software['packages'].keys():
if self.software['packages'][p]['repo']:
pkgname = '{0}/{1}'.format(self.software['packages'][p]['repo'],
self.software['packages'][p])
pkgname = '{0}/{1}'.format(self.software['packages'][p]['repo'], p)
else:
pkgname = p
pkgr.append(pkgname)
@ -881,6 +884,9 @@ class archInstall(object):
scripts = self.scripts
if not pkgcmds:
pkgcmds = self.packagecmds()
# Switch in the log, and link.
os.rename(logfile, '{0}/{1}'.format(self.system['chrootpath'], logfile))
os.symlink('{0}/{1}'.format(self.system['chrootpath'], logfile), logfile)
self.pacmanSetup() # This needs to be done before the chroot
# We don't need this currently, but we might down the road.
#chrootscript = '#!/bin/bash\n# https://aif.square-r00t.net/\n\n'
@ -922,6 +928,9 @@ class archInstall(object):
def unmount(self):
with open(logfile, 'a') as log:
subprocess.call(['umount', '-lR', self.system['chrootpath']], stdout = log, stderr = subprocess.STDOUT)
# We should also remove the (now dead) log symlink.
#Note that this does NOT delete the logfile on the installed system.
os.remove(logfile)
return()
def runInstall(confdict):
@ -942,7 +951,8 @@ def main():
with open(logfile, 'a') as log:
pprint.pprint(instconf, stream = log)
runInstall(instconf)
subprocess.call(['reboot'])
if instconf['system']['reboot']:
subprocess.run(['reboot'])

if __name__ == "__main__":
main()

View File

@ -1,62 +0,0 @@
#!/usr/bin/env python3


import re
import os
import io
from lxml import etree
from urllib.request import urlopen

cwd = os.path.dirname(os.path.realpath(__file__))

# Validate in the form of file:XSD/namespace.
xmlfiles = {}
#xmlfiles['aif.xml'] = 'https://aif.square-r00t.net/aif.xsd'
xmlfiles['aif.xml'] = 'aif.xsd'

def validXSD(xsdfile):
print("Checking XSD: ", xsdfile)
webres = False
if re.match('^(https?|ftp)', xsdfile, re.IGNORECASE):
webres = True
if not webres:
with open('{0}/{1}'.format(cwd, xsdfile), 'rb') as f:
xsd_in = f.read()
else:
with urlopen(xsdfile) as f:
xsd_in = f.read()
xsd = False
try:
xsd_in = io.BytesIO(xsd_in)
xmlschema_doc = etree.parse(xsd_in)
xsd = etree.XMLSchema(xmlschema_doc)
except:
print('XSD: {0} failed.'.format(xsdfile))
return(xsd)

def validXML(xml, xsd):
print("Checking XML: ", xml)
xmlfile = xml
with open('{0}/{1}'.format(cwd, xml), 'rb') as f:
xml_in = f.read()
valid = False
try:
xml_in = io.BytesIO(xml_in)
xml = etree.parse(xml_in)
valid = xsd.validate(xml)
except:
print('XML: {0} failed.'.format(xmlfile))
return(valid)

def allValidXML(xmlfiles):
for key,value in xmlfiles.items():
xmlfile = key
xsdfile = xmlfiles[xmlfile]
xml = False
xsdobj = validXSD(xsdfile)
xml = validXML(xmlfile, xsdobj)
return(xml)


if __name__ == '__main__':
allValidXML(xmlfiles)

View File

@ -1,6 +1,6 @@
= AIF-NG User Manual
Brent Saner <bts@square-r00t.net>
v1.0, 2017-05-05
v1.1, 2017-05-11
:doctype: book
:data-uri:
:imagesdir: images
@ -33,7 +33,7 @@ AIF-NG is not intended to be a complete turnup solution. Instead, it's useful to

Though if you're really gung-ho about it, I suppose you could use the post-script feature to fully turn up a box.

It is also not a magic bullet. It will not make an Arch Linux installation *easier*, nor is it designed to do that. Don't file bug reports for this. It's designed to make it *faster*. I recommend you follow the https://wiki.archlinux.org/index.php/installation_guide[manual installation process^] several times first so you're comfortable with the process and understand what's happening behind the scenes. (If you find it too hard to understand, you may instead be interested in https://antergos.com/[Antergos^] instead.)
It is also not a magic bullet. It will not make an Arch Linux installation *easier*, nor is it designed to do that. Don't file bug reports for this. It's designed to make it *faster*. I recommend you follow the https://wiki.archlinux.org/index.php/installation_guide[manual installation process^] several times first so you're comfortable with the process and understand what's happening behind the scenes. (If you find it too hard to understand, you may be interested in https://antergos.com/[Antergos^] instead.)

=== Copyright/Licensing
The AIF-NG code is https://www.gnu.org/licenses/gpl-3.0.en.html[GPLv3-licensed^]. This means that you can use it for business reasons, personal reasons, modify it, etc. Please be sure to familiarize yourself with the full set of terms. You can find the full license in `docs/LICENSE`.
@ -137,16 +137,57 @@ Configure your bootloader to add the following options as necessary:
** The same behavior applies for `aif_password`.
* If `aif_auth` is `digest`, this is the realm we would use (we attempt to "guess" if it isnt specified); otherwise it is ignored.

== Building a compatible LiveCD
The default Arch install CD does not have AIF installed (hopefully, this will change someday). You have two options for using AIF-NG.

=== Recommended
The recommended option is to use https://bdisk.square-r00t.net/[BDisk^] (the author should look familiar ;) and per https://bdisk.square-r00t.net/#advanced_customization[the documentation^], you would simply create the following modifications (remember to replace *<BDisk directory>* with your actual BDisk directory):

. `mkdir -p *<BDisk directory>*/overlay/etc/systemd/system/multi-target.wants`
. `ln -s /etc/systemd/system/aif.service *<BDisk directory>*/overlay/etc/systemd/system/multi-target.wants/aif.service`
.. (NOTE: This is not a typo; the symlink will resolve to the correct place during the build)
. `printf '[Unit]\nDescription=AIF-NG Client Service\nAfter=livecdfix.service\n\n[Service]\nType=oneshot\nExecStart=/usr/bin/aif\n\n[Install]\nWantedBy=multi-user.target\n' > *<BDisk directory>*/overlay/etc/systemd/system/aif.service`
.. (NOTE: This is all one line.)
.. (NOTE: We use a custom aif.service instead of the AUR package provided one because of how BDisk handles bringing up the network.)
. `echo "aif-git" > *<BDisk directory>*/extra/pre-build.d/root/packages.both`
. If you want automatic root login on TTY1 like the Arch install ISO (optional):
.. `mkdir -p *<BDisk directory>*/overlay/etc/systemd/system/getty\@tty1.service.d`
.. `printf '[Service]\nType=idle\nExecStart=\nExecStart=-/usr/bin/agetty --autologin root --noclear %%I 38400 linux\n' > *<BDisk directory>*/overlay/etc/systemd/system/getty\@tty1.service.d/autologin.conf`
... (NOTE: This is all one line.)

Remember to also create a https://bdisk.square-r00t.net/#the_code_build_ini_code_file[build.ini file^]. You can find a compatible one https://git.square-r00t.net/AIF-NG/plain/extras/bdisk.build.ini[here^] (but remember to tailor it to your particular paths and needs first!).

Make any further customizations as you wish, then https://bdisk.square-r00t.net/#building_a_bdisk_iso[start the build^].

=== Quickest
For convenience, I've already built a LiveCD that will auto-start AIF. Note, however, that it is configured to my personal preferences (it installs https://aif.square-r00t.net/cfgs/scripts/pkg/python.sh[python3^], installs https://aif.square-r00t.net/cfgs/scripts/pkg/apacman.py[apacman^] (and configures it and pacman to my tastes), sets up a more strict https://aif.square-r00t.net/cfgs/scripts/post/sshsecure.py[SSH configuration^], and https://aif.square-r00t.net/cfgs/scripts/post/sshkeys.py[installs my SSH pubkeys^].), so you may want to use the recommended method above instead.

==== The full environment
A full ISO build is https://aif.square-r00t.net/download/aif.iso[here] (GPG signatures are available in https://aif.square-r00t.net/download/aif.iso.sig[SIG] and https://aif.square-r00t.net/download/aif.iso.asc[ASC^] format; make sure you https://devblog.square-r00t.net/about/my-gpg-public-key-verification-of-identity[verify it^]).

It has a full GNU/Linux environment that you can use, and works on both UEFI and BIOS systems. It boots to a non-passworded root login, but AIF will be running in the background. SSH is installed and configured for key-based authentication only, but is not enabled by default.

==== The iPXE environment
If you would like to boot over the network, I have an iPXE ISO https://aif.square-r00t.net/download/aif-mini.iso[here] (GPG signatures are available in https://aif.square-r00t.net/download/aif-mini.iso.sig[SIG] and https://aif.square-r00t.net/download/aif-mini.iso.asc[ASC^] format; make sure you https://devblog.square-r00t.net/about/my-gpg-public-key-verification-of-identity[verify it^]).

You will need at least 2GB of RAM, as it loads entirely into memory.

It also boots to a full GNU/Linux environment that you can use, and works on both UEFI and BIOS systems. It boots to a non-passworded root login, but AIF will be running in the background. SSH is installed and configured for key-based authentication only, but is not enabled by default.



== Logging
Currently, only one method of logging is enabled, and is always enabled. It can be found on the host and guest at */root/aif.log._<UNIX epoch timestamp>_*. Note that after the build finishes successfully, it will remove the host's log (as it's just a broken symlink at that point). You will be able to find the full log in the guest after the install, however.

== Debugging
Sometimes it's useful to get a little more information, or to start an installation from within an already-booted environment and you didn't remember (or weren't able to) change the kernel parameters. If this is the case, simply export the `DEBUG` environment variable (it can be set to anything, it doesn't matter) -- if this is done, the arguments will be read from /tmp/cmdline instead. e.g.:

rm -f *
export DEBUG=true
cp /proc/cmdline /tmp/.
chmod 600 /tmp/cmdline
sed -i -e '1s/$/ aif aif_url=https:\/\/aif.square-r00t.net\/aif.xml/' /tmp/cmdline

It will also write the full configuration (*after* parsing) to `/root/log`.
It will also write the full configuration (*after* parsing) to the <<logging, logfile>>.

= Writing an XML Configuration File
I've included a sample `aif.xml` file with the project which is fully functional. However, it's not ideal -- namely because it will add my personal SSH pubkeys to your new install, and you probably don't want that. However, it's fairly complete so it should serve as a good example. If you want to see the full set of supported configuration elements, take a look at the most up-to-date https://aif.square-r00t.net/aif.xsd[aif.xsd^]. For explanation's sake, however, we'll go through it here. The directives are referred to in https://www.w3schools.com/xml/xml_xpath.asp[XPath^] syntax within the documentation text for easier context (but not the titles).
@ -175,12 +216,12 @@ The `/aif/storage/disk/part` element holds information on partitioning that it's
^|Attribute ^|Value
^m|num |The partition number (positive integer)
^m|start |The amount of the *total disk size* to _start_ the partition at (see <<specialsize, below>>)
^m|size |The amount of the *total disk size* to _end_ the partition at (see <<specialsize, below>>)
^m|stop |The amount of the *total disk size* to _end_ the partition at (see <<specialsize, below>>)
^m|fstype |The partition type. Must be in http://www.rodsbooks.com/gdisk/cgdisk-walkthrough.html[gdisk format^] (see <<fstypes, below>>)
|======================

[[specialsize]]
The `start` and `size` attributes can be in the form of:
The `start` and `stop` attributes can be in the form of:

* A percentage, indicated by a percentage sign (`"10%"`)
* A size, indicated by the abbreviation (`"300K"`, `"30G"`, etc.)
@ -349,6 +390,7 @@ The `/aif/system` element is for handling general system configuration. It conta
^m|locale |The https://wiki.archlinux.org/index.php/Locale#Setting_the_system_locale[locale^] of the installed system (e.g. `en_US.UTF-8`); if a short version is used (e.g. `en`), then all locales starting with that prefix will be enabled (multiple explicit locale support is in the TODO)
^m|chrootpath |The path on the host that will serve as the https://wiki.archlinux.org/index.php/Change_root[chroot^] path. This should be where your new install's / (root filesystem partition) is mounted at in <<code_mount_code, mounts>>
^m|kbd |The https://wiki.archlinux.org/index.php/installation_guide#Set_the_keyboard_layout[keyboard layout^] (if not US)
^m|reboot |If we should reboot the system after the install (in order to boot to the newly-installed system, assuming your boot order is set correctly). Boolean, accepts `1`/`true` or `0`/`false`.
|======================

==== `<users>`
@ -498,7 +540,7 @@ There are several script types availabe for `execution`. Currently, these are:
* pkg
* post

*pre* scripts are run (in numerical `order`) before the disks are even formatted. *pkg* scripts are run (in numerical `order`) right before the <<code_package_code, packages>> are installed (this allows you to configure an <<command, alternate packager>> such as https://aur.archlinux.org/packages/apacman/[apacman^]) -- these are run *inside* the chroot of the new install. *pre* scripts are run inside the chroot like *pkg*, but are executed very last thing, just before the reboot.
*pre* scripts are run (in numerical `order`) before the disks are even formatted. *pkg* scripts are run (in numerical `order`) right before the <<code_package_code, packages>> are installed (this allows you to configure an <<command, alternate packager>> such as https://aur.archlinux.org/packages/apacman/[apacman^]) -- these are run *inside* the chroot of the new install. *post* scripts are run inside the chroot like *pkg*, but are executed very last thing, just before the reboot.

= Further Information
Here you will find further info, other resources, and such relating to AIF-NG.
@ -507,17 +549,21 @@ Here you will find further info, other resources, and such relating to AIF-NG.
NOTE: It is possible to submit a bug or feature request without registering in my bugtracker. One of my pet peeves is needing to create an account/register on a bugtracker simply to report a bug! The following links only require an email address to file a bug (which is necessary in case I need any further clarification from you or to keep you updated on the status of the bug/feature request -- so please be sure to use a valid email address).

=== Bugs
If you encounter any bugs in *AIF-NG*, you can file a bug report https://bugs.square-r00t.net/index.php?do=newtask&project=9&task_type=1[here^].
If you encounter any bugs in *AIF-NG* (for the actual agent), you can file a bug report https://bugs.square-r00t.net/index.php?do=newtask&project=9&task_type=1&https://bugs.square-r00t.net/index.php?do=newtask&project=9&product_category=19[here^].

If you encounter any bugs (inaccurate information, typos, misformatting, etc.) in *this documentation*, you can file a bug report https://bugs.square-r00t.net/index.php?do=newtask&project=10&task_type=1[here^].
If you encounter any bugs in the *configuration file tool*, you can file a bug report https://bugs.square-r00t.net/index.php?do=newtask&project=9&task_type=1&https://bugs.square-r00t.net/index.php?do=newtask&project=9&product_category=24[here^].

If you encounter any bugs (inaccurate information, typos, misformatting, etc.) in *this documentation*, you can file a bug report https://bugs.square-r00t.net/index.php?do=newtask&project=9&task_type=1&product_category=25[here^].

=== Feature Requests
If you have any features you'd like to see or you think would help *AIF-NG* become even more useful, please file a feature request https://bugs.square-r00t.net/index.php?do=newtask&project=9&task_type=2[here^].
If you have any features you'd like to see or you think would help *AIF-NG* become even more useful, please file a feature request https://bugs.square-r00t.net/index.php?do=newtask&project=9&task_type=2&product_category=19[here^].

If you have any suggestions on how to improve *this documentation* or feel it's missing information that could be useful, please file a feature request https://bugs.square-r00t.net/index.php?do=newtask&project=10&task_type=2[here^].
If you have any features you'd like to see in the *configuration file tool*, you can file a feature requests https://bugs.square-r00t.net/index.php?do=newtask&project=9&task_type=1&https://bugs.square-r00t.net/index.php?do=newtask&project=9&task_type=2product_category=25[here^].

If you have any suggestions on how to improve *this documentation* or feel it's missing information that could be useful, please file a feature request https://bugs.square-r00t.net/index.php?do=newtask&project=9&task_type=2&product_category=25[here^].

=== Patches
I gladly welcome https://www.gnu.org/software/diffutils/manual/html_node/Unified-Format.html[patches^], but I deplore using GitHub (even though I https://github.com/johnnybubonic/aif-ng[have a mirror there^]). For this reason, please follow the same https://www.kernel.org/doc/Documentation/SubmittingPatches[patch/pull request process] for the Linux kernel and email it to bts@square-r00t.net.
I gladly welcome https://www.gnu.org/software/diffutils/manual/html_node/Unified-Format.html[patches^], but I deplore using GitHub (even though I https://github.com/johnnybubonic/aif-ng[have a mirror there^]). For this reason, please follow the same https://www.kernel.org/doc/Documentation/process/submitting-patches.rst[patch/pull request process] for the Linux kernel and email it to bts@square-r00t.net.

Alternatively, you may attach a patch to a <<bugs,bug report>>/<<feature_requests,feature request>>.


View File

@ -1,3 +1,4 @@
- support Arch Linux ARM?
- support multiple explicit locales via comma-separated list (see how i handle resolvers)
- config layout
-- need to apply defaults and annotate/document
@ -5,8 +6,8 @@
- how to support mdadm, lvm?
- support serverside "autoconfig"- a mechanism to let servers automatically generate xml build configs. e.g.:
kernel ... aif_url="https://build.domain.tld/aif-ng.php" auto=yes
would yield the *client* sending info via URL params, e.g.
https://build.domain.tld/aif-ng.php?disk[]=sda&disk[]=sdb&disk[sda]=300GB&disk[sdb]=500GB
would yield the *client* sending info via URL params (actually, this might be better as a JSON POST, since we already have a way to generate JSON. sort of.),
e.g. https://build.domain.tld/aif-ng.php?disk[]=sda&disk[]=sdb&disk[sda]=300GB&disk[sdb]=500GB (can have it so that the autoconfig is only supported clientside if pyyaml is installed)
or something like that.
- parser: make sure to use https://mikeknoop.com/lxml-xxe-exploit/ fix
- convert use of confobj or whatever to maybe be suitable to use webFetch instead. LOTS of duplicated code there.
@ -23,14 +24,14 @@
run on /mnt/aif/run type tmpfs (rw,nosuid,nodev,relatime,mode=755)
tmp on /mnt/aif/tmp type tmpfs (rw,nosuid,nodev)

DOCUMENTATION: BUG REPORTS/FEATURE REQUESTS!!!!
DOCUMENTATION: aif-config.py (and note sample json as well)

for network configuration, add in support for using a device's MAC address instead of interface name

also create:
-systemd unit to start on boot
-mkinitcpio hooks to start from initrd environment (minimal boot env)
-create boot media with bdisk since default arch doesn't even have python 3


-- this is.. sort of? done. but iPXE/mini build is failing, need to investigate why
-- i tihnk i fixed iPXE but i need to generate another one once 1.5 is released
docs:
http://lxml.de/parsing.html
https://www.w3.org/2001/XMLSchema.xsd

View File

@ -0,0 +1,183 @@
{
"boot": {
"bootloader": "grub",
"efi": true,
"target": "/boot"
},
"disks": {
"/dev/sda": {
"fmt": "gpt",
"parts": {
"1": {
"fstype": "8300",
"start": "0%",
"stop": "95%"
},
"2": {
"fstype": "ef00",
"start": "95%",
"stop": "100%"
}
}
},
"/dev/sdb": {
"fmt": "gpt",
"parts": {
"1": {
"fstype": "8300",
"start": "0%",
"stop": "47%"
},
"2": {
"fstype": "8300",
"start": "47%",
"stop": "95%"
},
"3": {
"fstype": "8200",
"start": "95%",
"stop": "100%"
}
}
}
},
"mounts": {
"1": {
"device": "/dev/sda1",
"fstype": "ext4",
"opts": "defaults",
"target": "/mnt/aif"
},
"2": {
"device": "/dev/sda2",
"fstype": "vfat",
"opts": "rw,relatime,fmask=0022,dmask=0022,codepage=437,iocharset=iso8859-1,shortname=mixed,errors=remount-ro",
"target": "/mnt/aif/boot"
},
"3": {
"device": "/dev/sdb1",
"fstype": "ext4",
"opts": "defaults",
"target": "/mnt/aif/home"
},
"4": {
"device": "/dev/sdb2",
"fstype": "ext4",
"opts": "defaults",
"target": "/mnt/aif/mnt/data"
},
"5": {
"device": "/dev/sdb3",
"fstype": false,
"opts": false,
"target": "swap"
}
},
"network": {
"hostname": "aif.loc.lan",
"ifaces": {
"ens3": {
"address": "auto",
"gw": false,
"proto": "ipv4",
"resolvers": false
},
"ens4": {
"address": "192.168.1.2/24",
"gw": "192.168.1.1",
"proto": "ipv4",
"resolvers": [
"4.2.2.1",
"4.2.2.2"
]
}
}
},
"scripts": {
"pkg": false,
"post": {
"1": {
"auth": "digest",
"password": "password",
"realm": "realmname",
"uri": "https://aif.square-r00t.net/sample-scripts/post/first.sh",
"user": "test"
}
},
"pre": false
},
"software": {
"mirrors": [
"http://mirrors.advancedhosters.com/archlinux/$repo/os/$arch",
"http://mirror.us.leaseweb.net/archlinux/$repo/os/$arch",
"http://arch.mirror.constant.com/$repo/os/$arch",
"http://mirror.vtti.vt.edu/archlinux/$repo/os/$arch",
"http://arch.mirrors.pair.com/$repo/os/$arch",
"http://mirror.yellowfiber.net/archlinux/$repo/os/$arch"
],
"packages": {
"openssh": "None"
},
"pkgr": false,
"repos": {
"community": {
"enabled": true,
"mirror": "file:///etc/pacman.d/mirrorlist",
"siglevel": "default"
},
"community-testing": {
"enabled": false,
"mirror": "file:///etc/pacman.d/mirrorlist",
"siglevel": "default"
},
"core": {
"enabled": true,
"mirror": "file:///etc/pacman.d/mirrorlist",
"siglevel": "default"
},
"extra": {
"enabled": true,
"mirror": "file:///etc/pacman.d/mirrorlist",
"siglevel": "default"
},
"multilib": {
"enabled": true,
"mirror": "file:///etc/pacman.d/mirrorlist",
"siglevel": "default"
},
"multilib-testing": {
"enabled": false,
"mirror": "file:///etc/pacman.d/mirrorlist",
"siglevel": "default"
}
}
},
"system": {
"chrootpath": "/mnt/aif",
"kbd": "US",
"locale": "en_US.UTF-8",
"reboot": true,
"rootpass": "$6$aIK0xvxLa/9BTEDu$xFskR0cQcEi273I8dgUtyO7WjjhHUZOfyS6NemelPgfMJORxbjgI6QCW6wEcCh7NVA1qGDpS0Lyg9vDCaRnA9/",
"services": {
"sshd": true
},
"timezone": "UTC",
"users": {
"aifusr": {
"comment": "A Test User",
"gid": false,
"group": false,
"home": false,
"password": "$6$arRyKn/VsusyJNQo$huX4aa1aJPzRMyyqeEw6IxC1KC1EKKJ8RXdQp6W68Yt7SVdHjwU/fEDvPb3xD3lUHOQ6ysLKWLkEXFNYxLpMf1",
"sudo": true,
"uid": false,
"xgroups": {
"users": {
"create": false,
"gid": false
}
}
}
}
}
}

View File

@ -0,0 +1,96 @@
{'boot': {'bootloader': 'grub', 'efi': True, 'target': '/boot'},
'disks': {'/dev/sda': {'fmt': 'gpt',
'parts': {1: {'fstype': '8300',
'start': '0%',
'stop': '95%'},
2: {'fstype': 'ef00',
'start': '95%',
'stop': '100%'}}},
'/dev/sdb': {'fmt': 'gpt',
'parts': {1: {'fstype': '8300',
'start': '0%',
'stop': '47%'},
2: {'fstype': '8300',
'start': '47%',
'stop': '95%'},
3: {'fstype': '8200',
'start': '95%',
'stop': '100%'}}}},
'mounts': {1: {'device': '/dev/sda1',
'fstype': 'ext4',
'opts': 'defaults',
'target': '/mnt/aif'},
2: {'device': '/dev/sda2',
'fstype': 'vfat',
'opts': 'rw,relatime,fmask=0022,dmask=0022,codepage=437,iocharset=iso8859-1,shortname=mixed,errors=remount-ro',
'target': '/mnt/aif/boot'},
3: {'device': '/dev/sdb1',
'fstype': 'ext4',
'opts': 'defaults',
'target': '/mnt/aif/home'},
4: {'device': '/dev/sdb2',
'fstype': 'ext4',
'opts': 'defaults',
'target': '/mnt/aif/mnt/data'},
5: {'device': '/dev/sdb3',
'fstype': False,
'opts': False,
'target': 'swap'}},
'network': {'hostname': 'aif.loc.lan',
'ifaces': {'ens3': {'address': 'auto',
'gw': False,
'proto': 'ipv4',
'resolvers': False},
'ens4': {'address': '192.168.1.2/24',
'gw': '192.168.1.1',
'proto': 'ipv4',
'resolvers': ['4.2.2.1', '4.2.2.2']}}},
'scripts': {'pkg': False,
'post': {1: {'auth': 'digest',
'password': 'password',
'realm': 'realmname',
'uri': 'https://aif.square-r00t.net/sample-scripts/post/first.sh',
'user': 'test'}},
'pre': False},
'software': {'mirrors': ['http://mirrors.advancedhosters.com/archlinux/$repo/os/$arch',
'http://mirror.us.leaseweb.net/archlinux/$repo/os/$arch',
'http://arch.mirror.constant.com/$repo/os/$arch',
'http://mirror.vtti.vt.edu/archlinux/$repo/os/$arch',
'http://arch.mirrors.pair.com/$repo/os/$arch',
'http://mirror.yellowfiber.net/archlinux/$repo/os/$arch'],
'packages': {'openssh': None},
'pkgr': False,
'repos': {'community': {'enabled': True,
'mirror': 'file:///etc/pacman.d/mirrorlist',
'siglevel': 'default'},
'community-testing': {'enabled': False,
'mirror': 'file:///etc/pacman.d/mirrorlist',
'siglevel': 'default'},
'core': {'enabled': True,
'mirror': 'file:///etc/pacman.d/mirrorlist',
'siglevel': 'default'},
'extra': {'enabled': True,
'mirror': 'file:///etc/pacman.d/mirrorlist',
'siglevel': 'default'},
'multilib': {'enabled': True,
'mirror': 'file:///etc/pacman.d/mirrorlist',
'siglevel': 'default'},
'multilib-testing': {'enabled': False,
'mirror': 'file:///etc/pacman.d/mirrorlist',
'siglevel': 'default'}}},
'system': {'chrootpath': '/mnt/aif',
'kbd': 'US',
'locale': 'en_US.UTF-8',
'reboot': True,
'rootpass': '$6$aIK0xvxLa/9BTEDu$xFskR0cQcEi273I8dgUtyO7WjjhHUZOfyS6NemelPgfMJORxbjgI6QCW6wEcCh7NVA1qGDpS0Lyg9vDCaRnA9/',
'services': {'sshd': True},
'timezone': 'UTC',
'users': {'aifusr': {'comment': 'A Test User',
'gid': False,
'group': False,
'home': False,
'password': '$6$arRyKn/VsusyJNQo$huX4aa1aJPzRMyyqeEw6IxC1KC1EKKJ8RXdQp6W68Yt7SVdHjwU/fEDvPb3xD3lUHOQ6ysLKWLkEXFNYxLpMf1',
'sudo': True,
'uid': False,
'xgroups': {'users': {'create': False,
'gid': False}}}}}}

View File

@ -0,0 +1,62 @@
<?xml version="1.0" encoding="UTF-8" ?>
<aif xmlns:aif="http://aif.square-r00t.net/"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://aif.square-r00t.net aif.xsd">
<storage>
<disk device="/dev/sda" diskfmt="gpt">
<part num="1" start="0%" stop="10%" fstype="ef00" />
<part num="2" start="10%" stop="100%" fstype="8300" />
</disk>
<mount source="/dev/sda2" target="/mnt/aif" order="1" />
<mount source="/dev/sda1" target="/mnt/aif/boot" order="2" />
</storage>
<network hostname="aiftest.square-r00t.net">
<iface device="auto" address="auto" netproto="ipv4" />
</network>
<system timezone="EST5EDT" locale="en_US.UTF-8" chrootpath="/mnt/aif" reboot="1">
<users rootpass="!" />
<service name="sshd" status="1" />
<service name="cronie" status="1" />
<service name="haveged" status="1" />
</system>
<pacman command="apacman -S">
<repos>
<repo name="core" enabled="true" siglevel="default" mirror="file:///etc/pacman.d/mirrorlist" />
<repo name="extra" enabled="true" siglevel="default" mirror="file:///etc/pacman.d/mirrorlist" />
<repo name="community" enabled="true" siglevel="default" mirror="file:///etc/pacman.d/mirrorlist" />
<repo name="multilib" enabled="true" siglevel="default" mirror="file:///etc/pacman.d/mirrorlist" />
<repo name="testing" enabled="false" siglevel="default" mirror="file:///etc/pacman.d/mirrorlist" />
<repo name="multilib-testing" enabled="false" siglevel="default" mirror="file:///etc/pacman.d/mirrorlist" />
<repo name="archlinuxfr" enabled="false" siglevel="Optional TrustedOnly" mirror="http://repo.archlinux.fr/$arch" />
</repos>
<mirrorlist>
<mirror>http://mirror.us.leaseweb.net/archlinux/$repo/os/$arch</mirror>
<mirror>http://mirrors.advancedhosters.com/archlinux/$repo/os/$arch</mirror>
<mirror>http://ftp.osuosl.org/pub/archlinux/$repo/os/$arch</mirror>
<mirror>http://arch.mirrors.ionfish.org/$repo/os/$arch</mirror>
<mirror>http://mirrors.gigenet.com/archlinux/$repo/os/$arch</mirror>
<mirror>http://mirror.jmu.edu/pub/archlinux/$repo/os/$arch</mirror>
</mirrorlist>
<software>
<package name="sed" repo="core" />
<package name="python" />
<package name="openssh" />
<package name="vim" />
<package name="vim-plugins" />
<package name="haveged" />
<package name="byobu" />
<package name="etc-update" />
<package name="cronie" />
<package name="mlocate" />
<package name="mtree-git" />
</software>
</pacman>
<bootloader type="grub" target="/boot" efi="true" />
<scripts>
<script uri="https://aif.square-r00t.net/cfgs/scripts/pkg/python.sh" order="1" execution="pkg" />
<script uri="https://aif.square-r00t.net/cfgs/scripts/pkg/apacman.py" order="2" execution="pkg" />
<script uri="https://aif.square-r00t.net/cfgs/scripts/post/sshsecure.py" order="1" execution="post" />
<script uri="https://aif.square-r00t.net/cfgs/scripts/post/sshkeys.py" order="2" execution="post" />
<script uri="https://aif.square-r00t.net/cfgs/scripts/post/configs.py" order="3" execution="post" />
</scripts>
</aif>

View File

@ -4,9 +4,9 @@
xsi:schemaLocation="https://aif.square-r00t.net aif.xsd">
<storage>
<disk device="/dev/sda" diskfmt="gpt">
<part num="1" start="0%" size="10%" fstype="ef00" />
<part num="2" start="10%" size="80%" fstype="8300" />
<part num="3" start="80%" size="100%" fstype="8200" />
<part num="1" start="0%" stop="10%" fstype="ef00" />
<part num="2" start="10%" stop="80%" fstype="8300" />
<part num="3" start="80%" stop="100%" fstype="8200" />
</disk>
<mount source="/dev/sda2" target="/mnt/aif" order="1" />
<mount source="/dev/sda1" target="/mnt/aif/boot" order="2" />
@ -15,7 +15,7 @@
<network hostname="aiftest.square-r00t.net">
<iface device="auto" address="auto" netproto="ipv4" />
</network>
<system timezone="EST5EDT" locale="en_US.UTF-8" chrootpath="/mnt/aif">
<system timezone="EST5EDT" locale="en_US.UTF-8" chrootpath="/mnt/aif" reboot="0">
<!-- note: all password hashes below are "test"; don't waste your time trying to crack. :) -->
<users rootpass="$6$3YPpiS.l3SQC6ELe$NQ4qMvcDpv5j1cCM6AGNc5Hyg.rsvtzCt2VWlSbuZXCGg2GB21CMUN8TMGS35tdUezZ/n9y3UFGlmLRVWXvZR.">
<user name="aifusr"
@ -58,9 +58,9 @@
</pacman>
<bootloader type="grub" target="/boot" efi="true" />
<scripts>
<script uri="https://aif.square-r00t.net/sample-scripts/post/first.sh" order="1" bootstrap="0" />
<script uri="https://aif.square-r00t.net/sample-scripts/pre/second.pl" order="2" bootstrap="1" />
<script uri="https://aif.square-r00t.net/sample-scripts/pre/first.sh" order="1" bootstrap="1" />
<script uri="https://aif.square-r00t.net/sample-scripts/post/second.py" order="2" bootstrap="0" />
<script uri="https://aif.square-r00t.net/sample-scripts/post/first.sh" order="1" execution="post" />
<script uri="https://aif.square-r00t.net/sample-scripts/pre/second.pl" order="2" execution="pre" />
<script uri="https://aif.square-r00t.net/sample-scripts/pre/first.sh" order="1" execution="pre" />
<script uri="https://aif.square-r00t.net/sample-scripts/post/second.py" order="2" execution="post" />
</scripts>
</aif>

104
extras/bdisk.build.ini Normal file
View File

@ -0,0 +1,104 @@
###########################################################
## BUILD.CONF SAMPLE FILE ##
###########################################################
#
# This file is used to define various variables/settings
# used by the build script.
#
# For full (perhaps overly-verbose ;) documentation, please
# see:
# https://bdisk.square-r00t.net/#_the_code_build_ini_code_file
# Or simply refer to the section titled "The build.ini File"
# in the user manual.

[bdisk]
name = AIF
uxname = aif
pname = AIF-NG
ver = 1.00
dev = r00t^2
email = bts@square-r00t.net
desc = See https://aif.square-r00t.net/
uri = https://aif.square-r00t.net/
root_password = BLANK
user = no

[user]
username = ${bdisk:uxname}
name = Default user
password = BLANK

[source_x86_64]
mirror = mirror.us.leaseweb.net
#mirrorproto = https
mirrorproto = http
mirrorpath = /archlinux/iso/latest/
mirrorfile =
mirrorchksum = ${mirrorpath}sha1sums.txt
chksumtype = sha1
mirrorgpgsig = .sig
gpgkey = 4AA4767BBC9C4B1D18AE28B77F2D434B9741E8AC
gpgkeyserver =

[source_i686]
mirror = mirror.us.leaseweb.net
#mirrorproto = https
mirrorproto = http
mirrorpath = /archlinux/iso/latest/
mirrorfile =
mirrorchksum = ${mirrorpath}sha1sums.txt
chksumtype = sha1
mirrorgpgsig = .sig
gpgkey = 7F2D434B9741E8AC
gpgkeyserver =

[build]
gpg = yes
dlpath = /var/tmp/${bdisk:uxname}
chrootdir = /var/tmp/chroots
basedir = /opt/dev/bdisk
isodir = ${dlpath}/iso
srcdir = ${dlpath}/src
prepdir = ${dlpath}/temp
archboot = ${prepdir}/${bdisk:name}
mountpt = /mnt/${bdisk:uxname}
multiarch = 64
sign = yes
ipxe = yes
i_am_a_racecar = yes

[gpg]
mygpgkey = 748231EBCBD808A14F5E85D28C004C2F93481F6B
mygpghome = /root/.gnupg

[sync]
http = yes
tftp = yes
git = no
rsync = no

[http]
path = ${build:dlpath}/http
user = root
group = root

[tftp]
path = ${build:dlpath}/tftpboot
user = root
group = root

[ipxe]
iso = yes
uri = https://aif.square-r00t.net/boot.ipxe
ssldir = ${build:dlpath}/ssl
ssl_ca = ${ssldir}/ca.crt
ssl_cakey = ${ssldir}/ca.key
ssl_crt = ${ssldir}/main.crt
ssl_key = ${ssldir}/main.key

[rsync]
#host = 10.1.1.1
host = bdisk.square-r00t.net
user = root
path = /srv/http/bdisk_ipxe
iso = yes

208
extras/createtest.expect Executable file
View File

@ -0,0 +1,208 @@
#!/usr/bin/expect -f

log_file -noappend /tmp/expect.log
set force_conservative 0 ;# set to 1 to force conservative mode even if
;# script wasn't run conservatively originally
if {$force_conservative} {
set send_slow {1 .1}
proc send {ignore arg} {
sleep .1
exp_send -s -- $arg
}
}

#set send_slow {10 .001}

set timeout -1
#spawn ./aif-config.py create -v:r -f /tmp/aif.xml
spawn ./aif-config.py create -v -f /tmp/aif.xml
## disks
send -- "/dev/sda,/dev/sdb\r"
# sda
send -- "gpt\r"
send -- "2\r"
# sda1
send -- "0%\r"
send -- "95%\r"
send -- "8300\r"
# sda2
send -- "95%\r"
send -- "100%\r"
send -- "ef00\r"
# sdb
send -- "gpt\r"
send -- "3\r"
# sdb1
send -- "0%\r"
send -- "47%\r"
send -- "8300\r"
# sdb2
send -- "47%\r"
send -- "95%\r"
send -- "8300\r"
# sdb3
send -- "95%\r"
send -- "100%\r"
send -- "8200\r"
## mounts
send -- "/mnt/aif,/mnt/aif/boot,/mnt/aif/home,/mnt/aif/mnt/data,swap\r"
# /mnt/aif
send -- "/dev/sda1\r"
send -- "1\r"
send -- "ext4\r"
send -- "defaults\r"
# /mnt/aif/boot
send -- "/dev/sda2\r"
send -- "2\r"
send -- "vfat\r"
send -- "rw,relatime,fmask=0022,dmask=0022,codepage=437,iocharset=iso8859-1,shortname=mixed,errors=remount-ro\r"
# /mnt/aif/home
send -- "/dev/sdb1\r"
send -- "3\r"
send -- "ext4\r"
send -- "defaults\r"
# /mnt/aif/mnt/data
send -- "/dev/sdb2\r"
send -- "4\r"
send -- "ext4\r"
send -- "defaults\r"
# swap
send -- "/dev/sdb3\r"
send -- "5\r"
## network
# hostname
send -- "aif.loc.lan\r"
# interface
send -- "ens3\r"
send -- "auto\r"
send -- "ipv4\r"
# add another interface?
send -- "y\r"
# second interface
send -- "ens4\r"
send -- "192.168.1.2/24\r"
send -- "192.168.1.1\r"
send -- "4.2.2.1,4.2.2.2\r"
# add another interface? default is no
send -- "\r"
## system
# timezone (default is UTC)
send -- "\r"
# locale (default is en_US.UTF-8
send -- "\r"
# chroot path
send -- "/mnt/aif\r"
# kbd (default is US)
send -- "\r"
# reboot host after install? default is yes
send -- "\r"
# root password
sleep 2
send -- "test\r"
sleep 2
expect *
# add user?
send -- "y\r"
# user
send -- "aifusr\r"
# sudo access
send -- "y\r"
# password
sleep 2
send -- "test\r"
sleep 2
send -- "A Test User\r"
# uid (default is autogen)
send -- "\r"
# primary group (default is autogen'd based on username)
send -- "\r"
# home dir (default is e.g. /home/username)
send -- "\r"
# add exta groups?
send -- "y\r"
# extra group
send -- "users\r"
# need to be created? default is no
send -- "\r"
# add another extra group? default is no
send -- "\r"
# add more users? default is no
send -- "\r"
# enable/disable services
send -- "y\r"
# service
send -- "sshd\r"
# enable? default is yes
send -- "\r"
# manage another service? default is no
send -- "\r"
# packager (default is pacman)
send -- "\r"
# review default repos? default is yes
send -- "\r"
# edit any of them?
send -- "y\r"
# edit the 6th repo (multilib)
send -- "6\r"
# enabled?
send -- "y\r"
# siglevel (default is unchanged)
send -- "\r"
# mirror URI (default is unchanged)
send -- "\r"
# edit another repo? default is no
send -- "\r"
# add additional repositories? default is no
send -- "\r"
# modify default mirrorlist?
send -- "y\r"
# URI for mirror
send -- "http://mirrors.advancedhosters.com/archlinux/\$repo/os/\$arch\r"
# add another?
send -- "y\r"
send -- "http://mirror.us.leaseweb.net/archlinux/\$repo/os/\$arch\r"
send -- "y\r"
send -- "http://arch.mirror.constant.com/\$repo/os/\$arch\r"
send -- "y\r"
send -- "http://mirror.vtti.vt.edu/archlinux/\$repo/os/\$arch\r"
send -- "y\r"
send -- "http://arch.mirrors.pair.com/\$repo/os/\$arch\r"
send -- "y\r"
send -- "http://mirror.yellowfiber.net/archlinux/\$repo/os/\$arch\r"
send -- "\r"
# install extra software?
send -- "y\r"
# software
send -- "openssh\r"
# repository (optional)
send -- "\r"
# add another package?
send -- "\r"
# bootloader (default is grub)
send -- "\r"
# system supports UEFI? default is yes
send -- "\r"
# ESP/EFI system partition
send -- "/boot\r"
# any hook scripts? default is no
send -- "y\r"
# pre, pkg, or post
send -- "post\r"
# script URI
send -- "https://aif.square-r00t.net/sample-scripts/post/first.sh\r"
# order for the execution run
send -- "1\r"
# auth required?
send -- "y\r"
# basic/digest? default is basic
send -- "digest\r"
# if digest, realm
send -- "realmname\r"
# user
send -- "test\r"
# password
send -- "password\r"
# would you like to add another script? default is no
send -- "\r"
interact
expect eof

View File

@ -1,7 +1,7 @@
run_hook () {
msg ":: Starting AIF-NG..."
/usr/bin/aifclient &
#nohup /usr/bin/aifclient &
/usr/bin/aif &
#nohup /usr/bin/aif &
#disown -h %1
}


View File

@ -1,6 +1,6 @@
buid() {
add_binary "/usr/bin/python"
add_binary "/usr/bin/aifclient"
add_binary "/usr/bin/aif"

add_runscript
}

View File

@ -4,7 +4,7 @@ After=network.target

[Service]
Type=oneshot
ExecStart=/usr/bin/aifclient
ExecStart=/usr/bin/aif

[Install]
WantedBy=multi-user.target

49
extras/txttojson.py Executable file
View File

@ -0,0 +1,49 @@
#!/usr/bin/env python3

import argparse
import json
import os
import pprint
#import re
try:
import yaml
except:
exit('You need pyYAML.')

def parseArgs():
args = argparse.ArgumentParser()
args.add_argument('-i',
'--in',
dest = 'infile',
required = True,
help = 'The plaintext representation of a python dict')
args.add_argument('-o',
'--out',
dest = 'outfile',
required = True,
help = 'The JSON file to create')
return(args)

def main():
args = vars(parseArgs().parse_args())
infile = os.path.abspath(os.path.normpath(args['infile']))
outfile = os.path.abspath(os.path.normpath(args['outfile']))
if not os.path.lexists(infile):
exit('Input file doesn\'t exist.')
#try:
with open(outfile, 'w') as outgoing:
with open(infile, 'r') as incoming:
#data = re.sub("'", '"', incoming.read())
#outgoing.write(data)
#d = json.dumps(data, ensure_ascii = False)
#d = json.dumps(incoming.read().replace("'", '"'))
d = yaml.load(incoming.read())
pprint.pprint(d)
j = json.dumps(d, indent = 4)
outgoing.write(j)
#except:
#exit('Error when trying to read/write file(s).')
return()

if __name__ == '__main__':
main()

View File

@ -3,4 +3,5 @@
use strict;
use warnings;

print "And this is the second pre (bootstrap) script.\n";
# because jthan is a baby
say "And this is the second pre (bootstrap) script.";