Compare commits

...

26 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
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
14 changed files with 1759 additions and 99 deletions

1117
aif-config.py Executable file

File diff suppressed because it is too large Load Diff

25
aif.xsd
View File

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


<xs:simpleType name="scripttype"> <xs:simpleType name="scripttype">
<xs:restriction base="xs:token"> <xs:restriction base="xs:token">
<xs:pattern value="(pre|post|pkg)" /> <xs:pattern value="(pre|post|pkg)" />
</xs:restriction> </xs:restriction>
</xs:simpleType> </xs:simpleType>
<xs:simpleType name="bootloaders"> <xs:simpleType name="bootloaders">
<xs:restriction base="xs:token"> <xs:restriction base="xs:token">
@ -143,7 +144,7 @@
<xs:complexType> <xs:complexType>
<xs:attribute name="num" type="xs:positiveInteger" use="required" /> <xs:attribute name="num" type="xs:positiveInteger" use="required" />
<xs:attribute name="start" type="disksize" 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:attribute name="fstype" type="fstype" use="required" />
</xs:complexType> </xs:complexType>
<xs:unique name="unique-partnum"> <xs:unique name="unique-partnum">
@ -263,7 +264,7 @@
</xs:sequence> </xs:sequence>
<xs:attribute name="timezone" type="xs:string" use="required" /> <xs:attribute name="timezone" type="xs:string" use="required" />
<xs:attribute name="locale" 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="kbd" type="xs:token" />
<xs:attribute name="reboot" type="xs:boolean" /> <xs:attribute name="reboot" type="xs:boolean" />
</xs:complexType> </xs:complexType>
@ -332,7 +333,7 @@
<xs:complexType> <xs:complexType>
<xs:attribute name="uri" type="scripturi" use="required" /> <xs:attribute name="uri" type="scripturi" use="required" />
<xs:attribute name="order" type="xs:integer" 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="user" type="xs:string" />
<xs:attribute name="password" type="xs:string" /> <xs:attribute name="password" type="xs:string" />
<xs:attribute name="realm" type="xs:string" /> <xs:attribute name="realm" type="xs:string" />

View File

@ -404,7 +404,7 @@ class archInstall(object):
disksize['max'] = subprocess.check_output(['sgdisk', '-E', d]) disksize['max'] = subprocess.check_output(['sgdisk', '-E', d])
for p in partnums: for p in partnums:
# Need to do some mathz to get the actual sectors if we're using percentages. # 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] val = self.disk[d]['parts'][str(p)][s]
if '%' in val: if '%' in val:
stripped = val.replace('%', '') stripped = val.replace('%', '')
@ -419,7 +419,7 @@ class archInstall(object):
for p in partnums: for p in partnums:
size = {} size = {}
size['start'] = self.disk[d]['parts'][str(p)]['start'] 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() fstype = self.disk[d]['parts'][str(p)]['fstype'].lower()
if fstype not in fstypes.keys(): if fstype not in fstypes.keys():
print('Filesystem type {0} is not valid. Must be a code from:\nCODE:FILESYSTEM'.format(fstype)) print('Filesystem type {0} is not valid. Must be a code from:\nCODE:FILESYSTEM'.format(fstype))
@ -429,7 +429,7 @@ class archInstall(object):
cmds.append(['sgdisk', cmds.append(['sgdisk',
'-n', '{0}:{1}:{2}'.format(str(p), '-n', '{0}:{1}:{2}'.format(str(p),
self.disk[d]['parts'][str(p)]['start'], 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 #'-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), '-t', '{0}:{1}'.format(str(p), fstype),
d]) d])

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 = AIF-NG User Manual
Brent Saner <bts@square-r00t.net> Brent Saner <bts@square-r00t.net>
v1.0, 2017-05-05 v1.1, 2017-05-11
:doctype: book :doctype: book
:data-uri: :data-uri:
:imagesdir: images :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. 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 === 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`. 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`.
@ -138,7 +138,7 @@ Configure your bootloader to add the following options as necessary:
* If `aif_auth` is `digest`, this is the realm we would use (we attempt to "guess" if it isnt specified); otherwise it is ignored. * 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 == Building a compatible LiveCD
The default Arch install CD does not have AIF installed (yet... ;). You have two options of using AIF-NG. The default Arch install CD does not have AIF installed (hopefully, this will change someday). You have two options for using AIF-NG.


=== Recommended === 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): 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):
@ -152,7 +152,7 @@ The recommended option is to use https://bdisk.square-r00t.net/[BDisk^] (the aut
. `echo "aif-git" > *<BDisk directory>*/extra/pre-build.d/root/packages.both` . `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): . 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` .. `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` .. `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.) ... (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!). 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!).
@ -182,7 +182,6 @@ Currently, only one method of logging is enabled, and is always enabled. It can
== Debugging == 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.: 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 export DEBUG=true
cp /proc/cmdline /tmp/. cp /proc/cmdline /tmp/.
chmod 600 /tmp/cmdline chmod 600 /tmp/cmdline
@ -217,12 +216,12 @@ The `/aif/storage/disk/part` element holds information on partitioning that it's
^|Attribute ^|Value ^|Attribute ^|Value
^m|num |The partition number (positive integer) ^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|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>>) ^m|fstype |The partition type. Must be in http://www.rodsbooks.com/gdisk/cgdisk-walkthrough.html[gdisk format^] (see <<fstypes, below>>)
|====================== |======================


[[specialsize]] [[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 percentage, indicated by a percentage sign (`"10%"`)
* A size, indicated by the abbreviation (`"300K"`, `"30G"`, etc.) * A size, indicated by the abbreviation (`"300K"`, `"30G"`, etc.)
@ -541,7 +540,7 @@ There are several script types availabe for `execution`. Currently, these are:
* pkg * pkg
* post * 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 = Further Information
Here you will find further info, other resources, and such relating to AIF-NG. Here you will find further info, other resources, and such relating to AIF-NG.
@ -550,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). 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 === 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 === 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 === 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>>. 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) - support multiple explicit locales via comma-separated list (see how i handle resolvers)
- config layout - config layout
-- need to apply defaults and annotate/document -- need to apply defaults and annotate/document
@ -5,8 +6,8 @@
- how to support mdadm, lvm? - how to support mdadm, lvm?
- support serverside "autoconfig"- a mechanism to let servers automatically generate xml build configs. e.g.: - 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 kernel ... aif_url="https://build.domain.tld/aif-ng.php" auto=yes
would yield the *client* sending info via URL params, e.g. 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.),
https://build.domain.tld/aif-ng.php?disk[]=sda&disk[]=sdb&disk[sda]=300GB&disk[sdb]=500GB 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. or something like that.
- parser: make sure to use https://mikeknoop.com/lxml-xxe-exploit/ fix - 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. - convert use of confobj or whatever to maybe be suitable to use webFetch instead. LOTS of duplicated code there.
@ -23,13 +24,14 @@
run on /mnt/aif/run type tmpfs (rw,nosuid,nodev,relatime,mode=755) run on /mnt/aif/run type tmpfs (rw,nosuid,nodev,relatime,mode=755)
tmp on /mnt/aif/tmp type tmpfs (rw,nosuid,nodev) 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: also create:
-create boot media with bdisk since default arch doesn't even have python 3 -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 -- 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: docs:
http://lxml.de/parsing.html http://lxml.de/parsing.html
https://www.w3.org/2001/XMLSchema.xsd 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"> xsi:schemaLocation="https://aif.square-r00t.net aif.xsd">
<storage> <storage>
<disk device="/dev/sda" diskfmt="gpt"> <disk device="/dev/sda" diskfmt="gpt">
<part num="1" start="0%" size="10%" fstype="ef00" /> <part num="1" start="0%" stop="10%" fstype="ef00" />
<part num="2" start="10%" size="80%" fstype="8300" /> <part num="2" start="10%" stop="80%" fstype="8300" />
<part num="3" start="80%" size="100%" fstype="8200" /> <part num="3" start="80%" stop="100%" fstype="8200" />
</disk> </disk>
<mount source="/dev/sda2" target="/mnt/aif" order="1" /> <mount source="/dev/sda2" target="/mnt/aif" order="1" />
<mount source="/dev/sda1" target="/mnt/aif/boot" order="2" /> <mount source="/dev/sda1" target="/mnt/aif/boot" order="2" />

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

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 strict;
use warnings; 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.";