jthan is whining about adding him to acknowledgments
This commit is contained in:
parent
6519ce2f19
commit
837d7a4703
140
aif/config.py
140
aif/config.py
@ -1,19 +1,145 @@
|
|||||||
import os
|
import os
|
||||||
|
import re
|
||||||
##
|
##
|
||||||
|
import requests
|
||||||
from lxml import etree
|
from lxml import etree
|
||||||
|
|
||||||
# https://stackoverflow.com/questions/30232031/how-can-i-strip-namespaces-out-of-an-lxml-tree/30233635#30233635 ?
|
# https://stackoverflow.com/questions/30232031/how-can-i-strip-namespaces-out-of-an-lxml-tree/30233635#30233635 ?
|
||||||
|
|
||||||
|
_patterns = {'raw': re.compile(r'^\s*(?P<xml><(\?xml|aif)\s+.*)\s*$', re.DOTALL|re.MULTILINE),
|
||||||
|
'remote': re.compile(r'^(?P<uri>(?P<proto>(https?|ftps?)://)(?P<path>.*))\s*$'),
|
||||||
|
'local': re.compile(r'^(file://)?(?P<path>(/?[^/]+)+/?)$')}
|
||||||
|
|
||||||
class Config(object):
|
class Config(object):
|
||||||
def __init__(self):
|
def __init__(self, *args, **kwargs):
|
||||||
|
self.tree = None
|
||||||
|
self.namespaced_tree = None
|
||||||
self.xml = None
|
self.xml = None
|
||||||
|
self.namespaced_xml = None
|
||||||
|
self.raw = None
|
||||||
|
self.xsd = None
|
||||||
|
|
||||||
def parseLocalFile(self, fpath):
|
def main(self, validate = True):
|
||||||
fpath = os.path.abspath(os.path.expanduser(fpath))
|
self.fetch()
|
||||||
pass
|
self.parseRaw()
|
||||||
|
if validate:
|
||||||
|
self.validate()
|
||||||
|
|
||||||
def parseRemoteFile(self, url):
|
return()
|
||||||
pass
|
|
||||||
|
|
||||||
def parseRawContent(self, content):
|
def fetch(self): # Just a fail-safe; this is overridden by specific subclasses.
|
||||||
pass
|
pass
|
||||||
|
return()
|
||||||
|
|
||||||
|
def getXSD(self, xsdpath = None):
|
||||||
|
raw_xsd = None
|
||||||
|
if xsdpath:
|
||||||
|
xsdpath = os.path.abspath(os.path.expanduser(xsdpath))
|
||||||
|
if not os.path.isfile(xsdpath):
|
||||||
|
raise ValueError(('An explicit XSD path was specified but '
|
||||||
|
'does not exist on the local filesystem'))
|
||||||
|
with open(xsdpath, 'rb') as fh:
|
||||||
|
raw_xsd = fh.read()
|
||||||
|
else:
|
||||||
|
xsi = self.xml.nsmap.get('xsi', 'http://www.w3.org/2001/XMLSchema-instance')
|
||||||
|
schemaLocation = '{{{0}}}schemaLocation'.format(xsi)
|
||||||
|
schemaURL = self.xml.attrib.get(schemaLocation,
|
||||||
|
'https://aif-ng.io/aif.xsd?ref={0}'.format(self.xml.attrib['version']))
|
||||||
|
req = requests.get(schemaURL)
|
||||||
|
if not req.ok():
|
||||||
|
raise RuntimeError('Could not download XSD')
|
||||||
|
raw_xsd = req.content
|
||||||
|
self.xsd = etree.XMLSchema(etree.XML(raw_xsd))
|
||||||
|
return()
|
||||||
|
|
||||||
|
def parseRaw(self):
|
||||||
|
self.tree = etree.parse(self.raw)
|
||||||
|
self.namespaced_tree = etree.parse(self.raw)
|
||||||
|
self.xml = self.tree.getroot()
|
||||||
|
self.namespaced_xml = self.namespaced_tree.getroot()
|
||||||
|
self.tree.xinclude()
|
||||||
|
self.namespaced_tree.xinclude()
|
||||||
|
return()
|
||||||
|
|
||||||
|
def stripNS(self):
|
||||||
|
# https://stackoverflow.com/questions/30232031/how-can-i-strip-namespaces-out-of-an-lxml-tree/30233635#30233635
|
||||||
|
for x in (self.tree, self.xml):
|
||||||
|
for e in x.xpath("descendant-or-self::*[namespace-uri()!='']"):
|
||||||
|
e.tag = etree.QName(e).localname
|
||||||
|
return()
|
||||||
|
|
||||||
|
def validate(self):
|
||||||
|
if not self.xsd:
|
||||||
|
self.getXSD()
|
||||||
|
|
||||||
|
return()
|
||||||
|
|
||||||
|
|
||||||
|
class LocalFile(Config):
|
||||||
|
def __init__(self, path, *args, **kwargs):
|
||||||
|
super().__init__(*args, **kwargs)
|
||||||
|
self.source = ['local', _patterns['local'].search(path).group('path')]
|
||||||
|
|
||||||
|
def fetch(self):
|
||||||
|
self.source[1] = os.path.abspath(os.path.expanduser(self.source[1]))
|
||||||
|
if not os.path.isfile(self.source[1]):
|
||||||
|
raise ValueError('{0} does not exist'.format(self.source[1]))
|
||||||
|
with open(self.source[1], 'rb') as fh:
|
||||||
|
self.raw = fh.read()
|
||||||
|
return()
|
||||||
|
|
||||||
|
|
||||||
|
class RemoteFile(Config):
|
||||||
|
def __init__(self, uri, *args, **kwargs):
|
||||||
|
super().__init__(*args, **kwargs)
|
||||||
|
self.source = ('remote', uri)
|
||||||
|
|
||||||
|
def fetch(self):
|
||||||
|
r = requests.get(self.source[1])
|
||||||
|
if not r.ok():
|
||||||
|
raise RuntimeError('Could not download XML')
|
||||||
|
self.raw = r.content
|
||||||
|
return()
|
||||||
|
|
||||||
|
|
||||||
|
class ConfigStr(Config):
|
||||||
|
def __init__(self, rawxml, *args, **kwargs):
|
||||||
|
super().__init__(*args, **kwargs)
|
||||||
|
self.source = ('raw', rawxml)
|
||||||
|
|
||||||
|
def fetch(self):
|
||||||
|
self.raw = self.source[1].encode('utf-8')
|
||||||
|
return()
|
||||||
|
|
||||||
|
class ConfigBin(Config):
|
||||||
|
def __init__(self, rawbinaryxml, *args, **kwargs):
|
||||||
|
super().__init__(*args, **kwargs)
|
||||||
|
self.source = ('raw_binary', rawbinaryxml)
|
||||||
|
|
||||||
|
def fetch(self):
|
||||||
|
self.raw = self.source[1]
|
||||||
|
return()
|
||||||
|
|
||||||
|
|
||||||
|
def getConfig(cfg_ref, validate = True):
|
||||||
|
cfgobj = None
|
||||||
|
# This is kind of gross.
|
||||||
|
for configtype, pattern in _patterns.items():
|
||||||
|
try:
|
||||||
|
if pattern.search(cfg_ref):
|
||||||
|
if configtype == 'raw':
|
||||||
|
cfgobj = ConfigStr(cfg_ref)
|
||||||
|
elif configtype == 'remote':
|
||||||
|
cfgobj = RemoteFile(cfg_ref)
|
||||||
|
elif configtype == 'local':
|
||||||
|
cfgobj = LocalFile(cfg_ref)
|
||||||
|
if cfgobj:
|
||||||
|
break
|
||||||
|
except TypeError:
|
||||||
|
ptrn = re.compile(_patterns['raw'].pattern.encode('utf-8'))
|
||||||
|
if not ptrn.search(cfg_ref):
|
||||||
|
raise ValueError('Received junk data for cfg_ref')
|
||||||
|
else:
|
||||||
|
cfgobj = ConfigBin(cfg_ref)
|
||||||
|
break
|
||||||
|
return(cfgobj)
|
||||||
|
3
docs/THANKS
Normal file
3
docs/THANKS
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
AIF-NG owes thanks to:
|
||||||
|
|
||||||
|
* jthan for being a good rubber ducky
|
@ -1,14 +1,14 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8" ?>
|
<?xml version="1.0" encoding="UTF-8" ?>
|
||||||
<aif xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
<aif xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
xmlns="http://aif-ng.io/"
|
xmlns="http://aif-ng.io/"
|
||||||
xsi:schemaLocation="AIF http://aif-ng.io/aif.xsd"
|
xsi:schemaLocation="http://aif-ng.io/ http://aif-ng.io/aif.xsd"
|
||||||
version="0.2.0">
|
version="v2_rewrite"><!-- When we release, this should match the tagged release (e.g. 0.2.0) -->
|
||||||
<storage>
|
<storage>
|
||||||
<blockDevices>
|
<blockDevices>
|
||||||
<disk device="/dev/sda" diskFormat="gpt">
|
<disk device="/dev/sda" diskFormat="gpt">
|
||||||
<!-- Partitions are numbered *in the order they are specified*. -->
|
<!-- Partitions are numbered *in the order they are specified*. -->
|
||||||
<part id="boot" name="BOOT" label="/boot" start="0%" stop="10%"
|
<!-- e.g. "boot" would be /dev/sda1, "secrets1" would be /dev/sda2, etc. -->
|
||||||
fsType="fat32"/><!-- e.g. this would be /dev/sda1 -->
|
<part id="boot" name="BOOT" label="/boot" start="0%" stop="10%" fsType="fat32"/>
|
||||||
<part id="secrets1" name="crypted" label="shh" start="10%" stop="20%" fsType="ext4"/>
|
<part id="secrets1" name="crypted" label="shh" start="10%" stop="20%" fsType="ext4"/>
|
||||||
<part id="lvm_member1" name="jbod" label="dynamic" start="20%" stop="30%" fsType="ext4"/>
|
<part id="lvm_member1" name="jbod" label="dynamic" start="20%" stop="30%" fsType="ext4"/>
|
||||||
<part id="raid1_d1" start="30%" stop="55%" fsType="ext4"/>
|
<part id="raid1_d1" start="30%" stop="55%" fsType="ext4"/>
|
||||||
@ -46,8 +46,8 @@
|
|||||||
</lvmGroup>
|
</lvmGroup>
|
||||||
</lvm>
|
</lvm>
|
||||||
<mdadm>
|
<mdadm>
|
||||||
<!-- level can be 0, 1, 4, 5, or 6. RAID 10 would be done by creating an array with members of a
|
<!-- level can be 0, 1, 4, 5, 6, or 10. RAID 1+0 (which is different from mdadm RAID10) would be done by
|
||||||
previously assembled array. -->
|
creating an array with members of a previously assembled array. -->
|
||||||
<array id="mdadm1" name="md0" meta="1.2" level="1">
|
<array id="mdadm1" name="md0" meta="1.2" level="1">
|
||||||
<member source="raid1_d1"/>
|
<member source="raid1_d1"/>
|
||||||
<member source="raid1_d2"/>
|
<member source="raid1_d2"/>
|
||||||
|
Loading…
Reference in New Issue
Block a user