Compare commits
39 Commits
0.0.1-BETA
...
master
Author | SHA1 | Date |
---|---|---|
brent s | 7a2e66f1a2 | |
brent s | addd1cb65a | |
brent s | ad0b36201b | |
brent s | 56cddb593a | |
brent s | aea4f1b8e3 | |
brent s | 372b51b1a6 | |
brent s | 3f8c626fca | |
brent s | d6f4548b88 | |
brent s | 4172111fcd | |
brent s | abaf931f37 | |
brent s | c2e6fe1a04 | |
brent s | e2f7b29287 | |
brent s | ba9f1df347 | |
brent s | 07d1efb607 | |
brent s | 0b971e7b4f | |
brent s | 094623f710 | |
brent s | cdc77545ea | |
brent s | 74a3b35a16 | |
brent s | 9aa8061018 | |
brent s | 29f6761017 | |
brent s. | fd8b26eb48 | |
brent s | 75f5f4a46d | |
brent s | c16e365b04 | |
brent s | bbb37c3c29 | |
brent s | 479c6e65bc | |
brent s | af5944bfea | |
brent s | 0a88b4347c | |
brent s | 9278cd016a | |
brent s | 0a99af21ee | |
brent s | a28121cbab | |
brent s | 32980870b7 | |
brent s | c64b800618 | |
brent s | ffedfaf684 | |
brent s | f744d7e5d4 | |
brent s | 935df2083f | |
brent s | 09d6632e3a | |
brent s | df26d0394b | |
brent s | 517d8135cc | |
brent s | b7ef1d5ea3 |
File diff suppressed because it is too large
Load Diff
26
aif.xsd
26
aif.xsd
|
@ -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" />
|
||||
|
|
32
aifclient.py
32
aifclient.py
|
@ -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()
|
||||
|
|
62
aifverify.py
62
aifverify.py
|
@ -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)
|
|
@ -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 isn’t 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>>.
|
||||
|
||||
|
|
15
docs/TODO
15
docs/TODO
|
@ -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
|
||||
|
|
|
@ -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
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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}}}}}}
|
|
@ -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>
|
|
@ -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>
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
||||
}
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
buid() {
|
||||
add_binary "/usr/bin/python"
|
||||
add_binary "/usr/bin/aifclient"
|
||||
add_binary "/usr/bin/aif"
|
||||
|
||||
add_runscript
|
||||
}
|
||||
|
|
|
@ -4,7 +4,7 @@ After=network.target
|
|||
|
||||
[Service]
|
||||
Type=oneshot
|
||||
ExecStart=/usr/bin/aifclient
|
||||
ExecStart=/usr/bin/aif
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
|
|
|
@ -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()
|
|
@ -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.";
|
||||
|
|
Loading…
Reference in New Issue