summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorbrent s <r00t@square-r00t.net>2017-05-15 12:38:10 -0400
committerbrent s <r00t@square-r00t.net>2017-05-15 12:38:10 -0400
commitaea4f1b8e3b44e8f74a0907ee679ef34234b42f6 (patch)
tree01f695ac928676a6ef469443a2fc40435b22e1af
parent372b51b1a66992968540f5144af8e84392b33b0d (diff)
downloadAIF-NG-0.1.10.tar.xz
aif-config is... done?0.1.10
-rwxr-xr-xaif-config.py154
-rw-r--r--docs/examples/aif-sample-intermediate.json27
-rw-r--r--docs/examples/aif-sample-intermediate.json.txt22
-rwxr-xr-xextras/createtest.expect35
4 files changed, 198 insertions, 40 deletions
diff --git a/aif-config.py b/aif-config.py
index 0b18cec..0b91bd1 100755
--- a/aif-config.py
+++ b/aif-config.py
@@ -1,8 +1,9 @@
#!/usr/bin/env python3
-xmldebug = True
+xmldebug = False
+stdlibxmldebug = False
-if not xmldebug:
+if not stdlibxmldebug:
try:
from lxml import etree
lxml_avail = True
@@ -431,6 +432,26 @@ class aifgen(object):
if not re.match('^y(es)?$', morereposin.lower()):
addrepos = False
return(repos)
+ def mirrorPrompt(mirrorhelp):
+ moremirrors = False
+ mirrors = False
+ mirrorchk = chkPrompt('* Would you like to replace the default mirrorlist? (y/{0}n{1}) '.format(color.BOLD, color.END), mirrorhelp)
+ if re.match('^y(es)?$', mirrorchk.lower()):
+ moremirrors = True
+ while moremirrors:
+ if not isinstance(mirrors, list):
+ mirrors = []
+ mirrorin = chkPrompt('** What is the URI for the mirror you would like to add?\n' +
+ '\tCan be one of the following types of URIs:\n' +
+ '\thttp://, https://, or file:// (for directories on the newly-installed system): ', mirrorhelp)
+ if mirrorin == '':
+ exit(' !! ERROR: You cannot specify a blank mirror URI.')
+ else:
+ mirrors.append(mirrorin)
+ moremirrorschk = chkPrompt('* Would you like to add another mirror? (y/{0}n{1}) '.format(color.BOLD, color.END), mirrorhelp)
+ if not re.match('^y(es)?$', moremirrorschk.lower()):
+ moremirrors = False
+ return(mirrors)
def pkgsPrompt(repohelp):
pkgs = {}
morepkgs = True
@@ -466,33 +487,33 @@ class aifgen(object):
'\tMust be a unique integer ' +
'(lower numbers execute before higher numbers): ').format(hook), scrpthlp)
try:
- order = int(ordrin)
+ orderint = int(orderin)
except:
exit(' !! ERROR: Must be an integer')
if order in scrpts[hook].keys():
- exit(' !! ERROR: You already have a {0} script at that order number.'.format(order))
- scrpts[hook][order] = {'uri': scrptin}
- if re.match('^(https?|ftps?)://', scriptin.lower()):
+ exit(' !! ERROR: You already have a {0} script at that order number.'.format(hook))
+ scrpts[hook][orderint] = {'uri': scrptin}
+ if re.match('^(https?|ftps?)://', scrptin.lower()):
authin = chkPrompt('** Does this script URI require auth? (y/{0}n{1}) '.format(color.BOLD, color.END), scrpthlp)
if re.match('^y(es)?$', authin.lower()):
- if re.match('^https?://', scriptin.lower()):
+ if re.match('^https?://', scrptin.lower()):
authtype = chkPrompt(('*** What type of auth does this URI require? ' +
'({0}basic{1}/digest) ').format(color.BOLD, color.END), scrpthlp)
if authtype == '':
- scrpts[hook][order]['auth'] = 'basic'
- elif not re.match('^(basic|digest)$', authtype.lower()):
- scrpts[hook][order]['auth'] = authtype.lower()
+ scrpts[hook][orderint]['auth'] = 'basic'
+ elif re.match('^(basic|digest)$', authtype.lower()):
+ scrpts[hook][orderint]['auth'] = authtype.lower()
else:
exit(' !! ERROR: That is not a valid auth type.')
if authtype.lower() == 'digest':
realmin = chkPrompt('*** Do you know the realm needed for authentication?\n' +
'\tIf not, just leave this blank and AIF-NG will try to guess: ', scrpthlp)
if realmin != '':
- scrpts[hook][order]['realm'] = realmin
- scrpts[hook][order]['user'] = chkPrompt('*** What user should we use for auth? ', scrpthlp)
- scrpts[hook][order]['password'] = chkPrompt('*** What password should we use for auth? ', scrpthlp)
+ scrpts[hook][orderint]['realm'] = realmin
+ scrpts[hook][orderint]['user'] = chkPrompt('*** What user should we use for auth? ', scrpthlp)
+ scrpts[hook][orderint]['password'] = chkPrompt('*** What password should we use for auth? ', scrpthlp)
else:
- scrpts[hook][order][auth] = False
+ scrpts[hook][orderint][auth] = False
morescrptsin = chkPrompt('* Would you like to add another hook script? (y/{0}n{1}) '.format(color.BOLD, color.END), scrpthlp)
if not re.match('^y(es)?$', morescrptsin.lower()):
morescrpts = False
@@ -685,6 +706,10 @@ class aifgen(object):
print('\n{0}=== REPOSITORIES/PACKAGES ==={1}'.format(color.BOLD, color.END))
repohelp = ['https://aif.square-r00t.net/#code_repos_code']
conf['software']['repos'] = repoPrompt(repohelp)
+ mirrorhelp = ['https://wiki.archlinux.org/index.php/installation_guide#Select_the_mirrors',
+ 'https://aif.square-r00t.net/#code_mirrorlist_code',
+ 'https://aif.square-r00t.net/#code_mirror_code']
+ conf['software']['mirrors'] = mirrorPrompt(mirrorhelp)
if pkgrcmd == '':
pkgrcmd = 'pacman --needed --noconfirm -S'
pkgsin = chkPrompt(('* Would you like to install extra packages?\n' +
@@ -704,8 +729,8 @@ class aifgen(object):
btldrin = 'grub'
elif not re.match('^(grub|systemd)$', btldrin.lower()):
exit(' !! ERROR: You must choose a bootloader between grub or systemd.')
- else:
- conf['boot']['bootloader'] = btldrin.lower()
+
+ conf['boot']['bootloader'] = btldrin.lower()
bttgtstr = 'boot partition/disk'
btrgx = re.compile('^/dev/[A-Za-z0]+')
if btldrin.lower() == 'grub':
@@ -790,7 +815,7 @@ class aifgen(object):
for e in ('storage', 'network', 'system', 'pacman', 'bootloader'):
root.append(etree.Element(e))
# /aif/ optional sections
- if conf['scripts']:
+ if 'scripts' in conf.keys() and conf['scripts']:
root.append(etree.Element('scripts'))
# /aif/storage
strg = root.find('storage')
@@ -905,13 +930,86 @@ class aifgen(object):
repo = etree.Element('repo', **o)
repos.append(repo)
pcmn.append(repos)
+ # /aif/pacman/mirrorlist
+ if 'mirrors' in conf['software'].keys() and conf['software']['mirrors']:
+ mrlst = etree.Element('mirrorlist')
+ for m in conf['software']['mirrors']:
+ # /aif/pacman/mirrorlist/mirror
+ mirror = etree.Element('mirror')
+ mirror.text = m
+ mrlst.append(mirror)
+ pcmn.append(mrlst)
+ # /aif/pacman/software
+ if 'packages' in conf['software'].keys() and conf['software']['packages']:
+ sftwr = etree.Element('software')
+ for p in conf['software']['packages'].keys():
+ # /aif/pacman/software/package
+ pkg = etree.Element('package')
+ pkg.set('name', p)
+ if conf['software']['packages'][p]:
+ if conf['software']['packages'][p] not in (None, 'None'): # fix JSON not parsing "None"
+ pkg.set('repo', conf['software']['packages'][p])
+ sftwr.append(pkg)
+ pcmn.append(sftwr)
+ # /aif/bootloader
+ btldr = root.find('bootloader')
+ optmap = {'bttype': 'type', 'efi': 'efi', 'bttgt': 'target'}
+ opts = {}
+ opts['bttype'] = conf['boot']['bootloader']
+ opts['efi'] = str(conf['boot']['efi']).lower()
+ opts['bttgt'] = conf['boot']['target']
+ for k in optmap.keys():
+ btldr.set(optmap[k], opts[k])
+ # /aif/scripts
+ if 'scripts' in conf.keys() and conf['scripts']:
+ scrpts = root.find('scripts')
+ # /aif/scripts/script@execution
+ for t in ('pre', 'pkg', 'post'):
+ # /aif/scripts/script@order
+ if t in conf['scripts'].keys() and conf['scripts'][t]:
+ for n in conf['scripts'][t].keys():
+ # /aif/scripts/script@uri
+ uri = conf['scripts'][t][n]['uri']
+ scrpt = etree.Element('script', execution = t, order = n, uri = uri)
+ # /aif/scripts/script@authtype
+ if 'auth' in conf['scripts'][t][n].keys() and conf['scripts'][t][n]['auth']:
+ scrpt.set('authtype', conf['scripts'][t][n]['auth'])
+ # /aif/scripts/script@realm
+ if conf['scripts'][t][n]['auth'] == 'digest':
+ if 'realm' in conf['scripts'][t][n].keys():
+ scrpt.set('realm', conf['scripts'][t][n]['realm'])
+ # /aif/scripts/script@user
+ scrpt.set('user', conf['scripts'][t][n]['user'])
+ # /aif/scripts/script@password
+ scrpt.set('password', conf['scripts'][t][n]['password'])
+ scrpts.append(scrpt)
# debugging
+ if xmldebug:
+ if lxml_avail:
+ # LXML
+ print(etree.tostring(root, xml_declaration = True, encoding = 'utf-8', pretty_print = True).decode('utf-8'))
+ else:
+ # XML
+ import xml.dom.minidom
+ xmlstr = etree.tostring(root, encoding = 'utf-8')
+ # holy cats, the xml module sucks.
+ nsstr = ''
+ for ns in namespaces.keys():
+ nsstr += ' xmlns:{0}="{1}"'.format(ns, namespaces[ns])
+ for x in xsi.keys():
+ xsiname = x.split('}')[1]
+ nsstr += ' xsi:{0}="{1}"'.format(xsiname, xsi[x])
+ outstr = xml.dom.minidom.parseString(xmlstr).toprettyxml(indent = ' ').splitlines()
+ outstr[0] = '<?xml version=\'1.0\' encoding=\'utf-8\'?>'
+ outstr[1] = '<aif{0}>'.format(nsstr)
+ print('\n'.join(outstr))
+ # end debugging
+ # https://stackoverflow.com/questions/4886189/python-namespaces-in-xml-elementtree-or-lxml
if lxml_avail:
- # LXML
- #print(etree.tostring(root).decode('utf-8'))
- print(etree.tostring(root, xml_declaration = True, encoding = 'utf-8', pretty_print = True).decode('utf-8'))
+ xml = etree.ElementTree(root)
+ with open(self.args['cfgfile'], 'wb') as f:
+ xml.write(f, xml_declaration = True, encoding='utf-8', pretty_print = True)
else:
- # XML
import xml.dom.minidom
xmlstr = etree.tostring(root, encoding = 'utf-8')
# holy cats, the xml module sucks.
@@ -924,17 +1022,9 @@ class aifgen(object):
outstr = xml.dom.minidom.parseString(xmlstr).toprettyxml(indent = ' ').splitlines()
outstr[0] = '<?xml version=\'1.0\' encoding=\'utf-8\'?>'
outstr[1] = '<aif{0}>'.format(nsstr)
- print('\n'.join(outstr))
- # end debugging
- # https://stackoverflow.com/questions/4886189/python-namespaces-in-xml-elementtree-or-lxml
- #if lxml_avail:
- #xml.write(..., xml_declaration = True, encoding='utf-8')
- #else:
- #import xml.dom.minidom
- #xmlstr = etree.tostring(root, encoding = 'utf-8')
- #with open(self.args['cfgfile'], 'w') as f: # TODO: test this. print() wrap it necessary?
- #f.write(xml.dom.minidom.parseString(xmlstr).toprettyxml(indent = ' '))
- return()
+ with open(self.args['cfgfile'], 'w') as f: # TODO: test this. print() wrap it necessary?
+ f.write('\n'.join(outstr))
+ return(root)
def main(self):
if self.args['oper'] == 'create':
diff --git a/docs/examples/aif-sample-intermediate.json b/docs/examples/aif-sample-intermediate.json
index 1f470ba..26a2fa9 100644
--- a/docs/examples/aif-sample-intermediate.json
+++ b/docs/examples/aif-sample-intermediate.json
@@ -1,5 +1,6 @@
{
"boot": {
+ "bootloader": "grub",
"efi": true,
"target": "/boot"
},
@@ -92,8 +93,28 @@
}
}
},
- "scripts": false,
+ "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"
},
@@ -136,7 +157,7 @@
"kbd": "US",
"locale": "en_US.UTF-8",
"reboot": true,
- "rootpass": "$6$OeSE5pp4BLWZUn6H$9Y.NO/2cUliOr.apu8qSmgmL4EbGei0u22cw1IANs0h6ek45t8bpHveY7rlHAlljd8PKIxvIRtY9bRCzV24h50",
+ "rootpass": "$6$aIK0xvxLa/9BTEDu$xFskR0cQcEi273I8dgUtyO7WjjhHUZOfyS6NemelPgfMJORxbjgI6QCW6wEcCh7NVA1qGDpS0Lyg9vDCaRnA9/",
"services": {
"sshd": true
},
@@ -147,7 +168,7 @@
"gid": false,
"group": false,
"home": false,
- "password": "$6$RCL/E8zPTHoYjITS$MsBQ9DXibdRvjE8a0ak8F2OCzShcRg3vKXSyLAipokaIJvTwFWwlLda1MQr6zTzUxlFui.9Ep4k3B8vdRyBX6.",
+ "password": "$6$arRyKn/VsusyJNQo$huX4aa1aJPzRMyyqeEw6IxC1KC1EKKJ8RXdQp6W68Yt7SVdHjwU/fEDvPb3xD3lUHOQ6ysLKWLkEXFNYxLpMf1",
"sudo": true,
"uid": false,
"xgroups": {
diff --git a/docs/examples/aif-sample-intermediate.json.txt b/docs/examples/aif-sample-intermediate.json.txt
index 9bbc381..7b4ff6b 100644
--- a/docs/examples/aif-sample-intermediate.json.txt
+++ b/docs/examples/aif-sample-intermediate.json.txt
@@ -1,4 +1,4 @@
-{'boot': {'efi': True, 'target': '/boot'},
+{'boot': {'bootloader': 'grub', 'efi': True, 'target': '/boot'},
'disks': {'/dev/sda': {'fmt': 'gpt',
'parts': {1: {'fstype': '8300',
'start': '0%',
@@ -45,8 +45,20 @@
'gw': '192.168.1.1',
'proto': 'ipv4',
'resolvers': ['4.2.2.1', '4.2.2.2']}}},
- 'scripts': False,
- 'software': {'packages': {'openssh': None},
+ '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',
@@ -70,14 +82,14 @@
'kbd': 'US',
'locale': 'en_US.UTF-8',
'reboot': True,
- 'rootpass': '$6$OeSE5pp4BLWZUn6H$9Y.NO/2cUliOr.apu8qSmgmL4EbGei0u22cw1IANs0h6ek45t8bpHveY7rlHAlljd8PKIxvIRtY9bRCzV24h50',
+ 'rootpass': '$6$aIK0xvxLa/9BTEDu$xFskR0cQcEi273I8dgUtyO7WjjhHUZOfyS6NemelPgfMJORxbjgI6QCW6wEcCh7NVA1qGDpS0Lyg9vDCaRnA9/',
'services': {'sshd': True},
'timezone': 'UTC',
'users': {'aifusr': {'comment': 'A Test User',
'gid': False,
'group': False,
'home': False,
- 'password': '$6$RCL/E8zPTHoYjITS$MsBQ9DXibdRvjE8a0ak8F2OCzShcRg3vKXSyLAipokaIJvTwFWwlLda1MQr6zTzUxlFui.9Ep4k3B8vdRyBX6.',
+ 'password': '$6$arRyKn/VsusyJNQo$huX4aa1aJPzRMyyqeEw6IxC1KC1EKKJ8RXdQp6W68Yt7SVdHjwU/fEDvPb3xD3lUHOQ6ysLKWLkEXFNYxLpMf1',
'sudo': True,
'uid': False,
'xgroups': {'users': {'create': False,
diff --git a/extras/createtest.expect b/extras/createtest.expect
index bc39ba8..7fb96bf 100755
--- a/extras/createtest.expect
+++ b/extras/createtest.expect
@@ -154,6 +154,22 @@ send -- "\r"
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
@@ -169,5 +185,24 @@ 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