okay, some minor changes to the XML stuff. getting there

This commit is contained in:
brent s. 2019-12-10 06:59:47 -05:00
parent c7ce23ff0f
commit 06c99221d2
8 changed files with 103 additions and 1244 deletions

1170
aif.xsd

File diff suppressed because it is too large Load Diff

View File

@ -1,8 +1,9 @@
import os
##
from . import _common
from . import netctl
from . import networkd
from . import networkmanager
from . import main

# No longer necessary:
# try:
@ -18,3 +19,43 @@ from . import main
# from . import networkd
# except ImportError:
# from . import networkd_fallback as networkd


class Net(object):
def __init__(self, chroot_base, network_xml):
self.xml = network_xml
self.chroot_base = chroot_base
self.hostname = self.xml.attrib['hostname'].strip()
self.provider = self.xml.attrib.get('provider', 'networkd').strip()
if self.provider == 'netctl':
self.provider = netctl
elif self.provider == 'nm':
self.provider = networkmanager
elif self.provider == 'networkd':
self.provider = networkd
else:
raise RuntimeError('Could not determine provider')
self.connections = []
self._initConns()

def _initConns(self):
for e in self.xml.xpath('ethernet|wireless'):
conn = None
if e.tag == 'ethernet':
conn = self.provider.Ethernet(e)
elif e.tag == 'wireless':
conn = self.provider.Wireless(e)
self.connections.append(conn)

def apply(self, chroot_base):
cfg = os.path.join(chroot_base, 'etc', 'hostname')
with open(cfg, 'w') as fh:
fh.write('{0}\n'.format(self.hostname))
os.chown(cfg, 0, 0)
os.chmod(cfg, 0o0644)
for iface in self.connections:
for src, dest in iface.services.items():
realdest = os.path.join(chroot_base, dest)
os.symlink(src, realdest)
iface.writeConf(chroot_base)
return ()

View File

@ -1,42 +0,0 @@
import os


class Network(object):
def __init__(self, network_xml):
self.xml = network_xml
self.hostname = self.xml.attrib['hostname'].strip()
self.provider = self.xml.attrib.get('provider', 'networkd').strip()
handler = None
if self.provider == 'netctl':
import aif.network.netctl as handler
elif self.provider == 'nm':
import aif.network.networkmanager as handler
elif self.provider == 'networkd':
import aif.network.networkd as handler
self.provider = handler
if not self.provider:
raise RuntimeError('Could not determine handler')
self.connections = []
self._initConns()

def _initConns(self):
for e in self.xml.xpath('ethernet|wireless'):
conn = None
if e.tag == 'ethernet':
conn = self.provider.Ethernet(e)
elif e.tag == 'wireless':
conn = self.provider.Wireless(e)
self.connections.append(conn)

def apply(self, chroot_base):
cfg = os.path.join(chroot_base, 'etc', 'hostname')
with open(cfg, 'w') as fh:
fh.write('{0}\n'.format(self.hostname))
os.chown(cfg, 0, 0)
os.chmod(cfg, 0o0644)
for iface in self.connections:
for src, dest in iface.services.items():
realdest = os.path.join(chroot_base, dest)
os.symlink(src, realdest)
iface.writeConf(chroot_base)
return()

View File

@ -4,5 +4,18 @@ from . import users
from . import services


def main(system_xml):
pass
class Sys(object):
def __init__(self, chroot_base, system_xml):
self.xml = system_xml
self.chroot_base = chroot_base
self.locale = locales.Locale(self.chroot_base, self.xml.find('locales'))
self.tz = locales.Timezone(self.chroot_base, self.xml.attrib.get('timezone', 'UTC'))
self.user = users.UserDB(self.chroot_base, self.xml.find('rootPassword'), self.xml.find('users'))
self.services = services.ServiceDB(self.chroot_base, self.xml.find('services'))

def apply(self):
self.locale.writeConf()
self.tz.apply()
self.user.writeConf()
self.services.apply()
return()

View File

@ -34,8 +34,9 @@ class Font(object):


class Keyboard(object):
def __init__(self, keyboard_xml):
def __init__(self, chroot_base, keyboard_xml):
self.xml = keyboard_xml
self.chroot_base = chroot_base
self.settings = {}
if self.xml:
chk = {'KEYMAP': self.xml.find('map'),
@ -44,14 +45,14 @@ class Keyboard(object):
if xml:
self.settings[setting] = xml.text.strip()

def verify(self, chroot_base):
def verify(self):
kbdnames = []
for i in ('KEYMAP', 'KEYMAP_TOGGLE'):
if i in self.settings.keys():
kbdnames.append(self.settings[i])
if not kbdnames:
return(None)
keymapdir = os.path.join(chroot_base, 'usr', 'share', 'kbd', 'keymaps')
keymapdir = os.path.join(self.chroot_base, 'usr', 'share', 'kbd', 'keymaps')
kbdmaps = []
for root, dirs, files in os.walk(keymapdir, topdown = True):
if root.endswith('/include'):
@ -69,8 +70,9 @@ class Keyboard(object):


class Console(object):
def __init__(self, console_xml):
def __init__(self, chroot_base, console_xml):
self.xml = console_xml
self.chroot_base = chroot_base
self._cfg = configparser.ConfigParser()
self._cfg.optionxform(str)
self.keyboard = Keyboard(self.xml.find('keyboard'))
@ -79,10 +81,10 @@ class Console(object):
for i in (self.keyboard, self.font):
self._cfg['BASE'].update(i.settings)

def writeConf(self, chroot_base):
def writeConf(self):
for x in (self.font, self.keyboard):
x.verify(chroot_base)
cfg = os.path.join(chroot_base, 'etc', 'vconsole.conf')
x.verify()
cfg = os.path.join(self.chroot_base, 'etc', 'vconsole.conf')
# We have to strip out the section from the ini.
cfgbuf = io.StringIO()
self._cfg.write(cfgbuf, space_around_delimiters = False)

View File

@ -11,8 +11,9 @@ _locale_def_re = re.compile(r'([^.]*)[^@]*(.*)')


class Locale(object):
def __init__(self, locales_xml):
def __init__(self, chroot_base, locales_xml):
self.xml = locales_xml
self.chroot_base = chroot_base
self.syslocales = {}
self.userlocales = []
self.rawlocales = None
@ -31,8 +32,8 @@ class Locale(object):
self.userlocales = ['en_US', 'en_US.UTF-8']
return()

def _verify(self, chroot_base):
localegen = os.path.join(chroot_base, 'etc', 'locale.gen') # This *should* be brand new.
def _verify(self):
localegen = os.path.join(self.chroot_base, 'etc', 'locale.gen') # This *should* be brand new.
with open(localegen, 'r') as fh:
self.rawlocales = fh.read().splitlines()
for idx, line in enumerate(self.rawlocales[:]):
@ -50,12 +51,12 @@ class Locale(object):
raise ValueError('non-existent locale specified')
return()

def writeConf(self, chroot_base):
def writeConf(self):
# We basically recreate locale-gen in python here, more or less.
self._verify(chroot_base)
localegen = os.path.join(chroot_base, 'etc', 'locale.gen')
localedbdir = os.path.join(chroot_base, 'usr', 'lib', 'locale')
localesrcdir = os.path.join(chroot_base, 'usr', 'share', 'i18n')
self._verify()
localegen = os.path.join(self.chroot_base, 'etc', 'locale.gen')
localedbdir = os.path.join(self.chroot_base, 'usr', 'lib', 'locale')
localesrcdir = os.path.join(self.chroot_base, 'usr', 'share', 'i18n')
with open(localegen, 'w') as fh:
fh.write('# Generated by AIF-NG.\n\n')
fh.write('\n'.join(self.rawlocales))
@ -86,12 +87,12 @@ class Locale(object):
# '--charmap={0}'.format(os.path.join(localesrcdir, 'charmaps', charset)),
'--inputfile={0}'.format(ldef_name),
'--charmap={0}'.format(charset),
'--alias-file={0}'.format(os.path.join(chroot_base,
'--alias-file={0}'.format(os.path.join(self.chroot_base,
'usr', 'share', 'locale', 'locale.alias')),
'--prefix={0}'.format(chroot_base),
'--prefix={0}'.format(self.chroot_base),
locale],
env = env)
cfg = os.path.join(chroot_base, 'etc', 'locale.conf')
cfg = os.path.join(self.chroot_base, 'etc', 'locale.conf')
# And now we write the variables.
# We have to strip out the section from the ini.
cfgbuf = io.StringIO()
@ -108,19 +109,20 @@ class Locale(object):


class Timezone(object):
def __init__(self, timezone):
def __init__(self, chroot_base, timezone):
self.tz = timezone.strip().replace('.', '/')
self.chroot_base = chroot_base

def _verify(self, chroot_base):
def _verify(self):
tzfilebase = os.path.join('usr', 'share', 'zoneinfo', self.tz)
tzfile = os.path.join(chroot_base, tzfilebase)
tzfile = os.path.join(self.chroot_base, tzfilebase)
if not os.path.isfile(tzfile):
raise ValueError('Invalid timezone')
return(tzfilebase)

def apply(self, chroot_base):
tzsrcfile = os.path.join('/', self._verify(chroot_base))
tzdestfile = os.path.join(chroot_base, 'etc', 'localtime')
def apply(self):
tzsrcfile = os.path.join('/', self._verify())
tzdestfile = os.path.join(self.chroot_base, 'etc', 'localtime')
if os.path.isfile(tzdestfile):
os.remove(tzdestfile)
os.symlink(tzsrcfile, tzdestfile)

View File

@ -37,7 +37,7 @@ class Service(object):


class ServiceDB(object):
def __init__(self, services_xml, chroot_base):
def __init__(self, chroot_base, services_xml):
self.xml = services_xml
self.chroot_base = chroot_base
self.systemd_sys = os.path.join(self.chroot_base, 'usr', 'lib', 'systemd', 'system')

View File

@ -1,10 +1,23 @@
<?xml version="1.0" encoding="UTF-8" ?>
<aif xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://aif-ng.io/"
xsi:schemaLocation="http://aif-ng.io/ http://aif-ng.io/aif.xsd"
version="v2_rewrite"
xmlns="https://aif-ng.io/"
xsi:schemaLocation="https://aif-ng.io/ https://schema.xml.r00t2.io/projects/aif.xsd"
chrootPath="/mnt/aif"
reboot="false"><!-- When we release, this should match the tagged release (e.g. 0.2.0) -->
reboot="false">
<bootstrap>
<tarball>https://arch.mirror.square-r00t.net/iso/latest/archlinux-bootstrap-2019.12.01-x86_64.tar.gz</tarball>
<verify>
<gpg>
<signatureFile>
https://arch.mirror.square-r00t.net/iso/latest/archlinux-bootstrap-2019.12.01-x86_64.tar.gz.sig
</signatureFile>
</gpg>
<hash>
<checksumFile hashType="md5">http://arch.mirror.square-r00t.net/iso/latest/md5sums.txt</checksumFile>
<checksumFile hashType="sha1">http://arch.mirror.square-r00t.net/iso/latest/sha1sums.txt</checksumFile>
</hash>
</verify>
</bootstrap>
<storage>
<blockDevices>
<disk id="sda" device="/dev/sda" diskFormat="gpt">