writing XSDs fucking sucks

This commit is contained in:
brent s. 2018-05-23 01:45:31 -04:00
parent e818b04f16
commit b134ee67bd
4 changed files with 185 additions and 22 deletions

View File

@ -1,6 +1,147 @@
<?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="http://bdisk.square-r00t.net" targetNamespace="http://bdisk.square-r00t.net/"
xmlns="http://bdisk.square-r00t.net" xmlns="http://bdisk.square-r00t.net/"
elementFormDefault="qualified"> elementFormDefault="qualified">
</xs:schema> <!-- ROOT ELEMENT ("BDISK") -->
<xs:element name="bdisk">
<xs:complexType>
<xs:choice>
<!-- BDISK/PROFILE -->
<xs:element name="profile" maxOccurs="unbounded" minOccurs="1">
<xs:complexType>
<xs:all>
<!-- BDISK/PROFILE/META -->
<xs:element name="meta" maxOccurs="1" minOccurs="1">
<xs:complexType>
<xs:all>
<!-- BDISK/PROFILE/META/NAMES -->
<xs:element name="names" maxOccurs="1" minOccurs="1">
<xs:complexType>
<xs:all>
<!-- BDISK/PROFILE/META/NAMES/NAME -->
<xs:element name="name" maxOccurs="1" minOccurs="1">
<xs:simpleType>
<xs:restriction base="xs:string">
<xs:pattern
value="(\{(xpath|variable)%[A-Za-z0-9_]\}|[A-Z0-9]{1,8})"/>
</xs:restriction>
</xs:simpleType>
</xs:element>
<!-- END BDISK/PROFILE/META/NAMES/NAME -->
<!-- BDISK/PROFILE/META/NAMES/UXNAME -->
<xs:element name="uxname" maxOccurs="1" minOccurs="1">
<xs:simpleType>
<xs:restriction base="xs:string">
<xs:pattern
value="(\{(xpath|variable)%[A-Za-z0-9_]+\}|[A-Za-z0-9]{1,255})"/>
</xs:restriction>
</xs:simpleType>
</xs:element>
<!-- END BDISK/PROFILE/META/NAMES/UXNAME -->
<!-- BDISK/PROFILE/META/NAMES/PNAME -->
<xs:element name="pname" maxOccurs="1" minOccurs="1">
<xs:simpleType>
<xs:restriction base="xs:string">
<!-- https://stackoverflow.com/a/9805789/733214 -->
<xs:pattern value="\p{IsBasicLatin}*"/>
</xs:restriction>
</xs:simpleType>
</xs:element>
<!-- END BDISK/PROFILE/META/NAMES/PNAME -->
</xs:all>
</xs:complexType>
</xs:element>
<!-- END BDISK/PROFILE/META/NAMES -->
<!-- BDISK/PROFILE/META/DESC -->
<xs:element name="desc" maxOccurs="1" minOccurs="1" type="xs:string"/>
<!-- END BDISK/PROFILE/META/DESC -->
<!-- BDISK/PROFILE/META/DEV -->
<xs:element name="dev" maxOccurs="1" minOccurs="1" type="xs:string"/>
<!-- END BDISK/PROFILE/META/DEV -->
<!-- BDISK/PROFILE/META/URI -->
<xs:element name="uri" maxOccurs="1" minOccurs="1" type="xs:anyURI"/>
<!-- END BDISK/PROFILE/META/URI -->
<!-- BDISK/PROFILE/META/VER -->
<xs:element name="ver" maxOccurs="1" minOccurs="1" type="xs:string"/>
<!-- END BDISK/PROFILE/META/VER -->
<!-- BDISK/PROFILE/META/MAX_RECURSE -->
<xs:element name="max_recurse" maxOccurs="1" minOccurs="1"
type="xs:positiveInteger"/>
<!-- END BDISK/PROFILE/META/MAX_RECURSE -->
<!-- BDISK/PROFILE/META/REGEXES -->
<xs:element name="regexes" maxOccurs="1" minOccurs="0">
<xs:complexType>
<xs:sequence>
<!-- BDISK/PROFILE/META/REGEXES/PATTERN -->
<xs:element name="pattern" maxOccurs="unbounded" minOccurs="1">
<xs:complexType>
<xs:simpleContent>
<xs:extension base="xs:string">
<xs:attribute name="id" type="xs:string"
use="required"/>
</xs:extension>
</xs:simpleContent>
</xs:complexType>
</xs:element>
<!-- END BDISK/PROFILE/META/REGEXES/PATTERN -->
</xs:sequence>
</xs:complexType>
</xs:element>
<!-- END BDISK/PROFILE/META/REGEXES -->
<!-- BDISK/PROFILE/META/VARIABLES -->
<xs:element name="variables" maxOccurs="1" minOccurs="0">
<xs:complexType>
<xs:sequence>
<!-- BDISK/PROFILE/META/VARIABLES/VARIABLE -->
<xs:element name="variable" maxOccurs="unbounded" minOccurs="1">
<xs:complexType>
<xs:simpleContent>
<xs:extension base="xs:string">
<xs:attribute name="id" type="xs:string"
use="required"/>
</xs:extension>
</xs:simpleContent>
</xs:complexType>
</xs:element>
<!-- END BDISK/PROFILE/META/VARIABLES/VARIABLE -->
</xs:sequence>
</xs:complexType>
</xs:element>
<!-- END BDISK/PROFILE/META/VARIABLES -->
</xs:all>
</xs:complexType>
</xs:element>
<!-- END BDISK/PROFILE/META -->
<!-- BDISK/PROFILE/ACCOUNTS -->
<xs:element name="accounts" maxOccurs="1" minOccurs="1"/>
<!-- END BDISK/PROFILE/ACCOUNTS -->
<!-- BDISK/PROFILE/BUILD-->
<xs:element name="build" maxOccurs="1" minOccurs="1"/>
<!-- END BDISK/PROFILE/BUILD -->
<!-- BDISK/PROFILE/ISO -->
<xs:element name="iso" maxOccurs="1" minOccurs="1"/>
<!-- END BDISK/PROFILE/ISO -->
<!-- BDISK/PROFILE/IPXE -->
<xs:element name="ipxe" maxOccurs="1" minOccurs="1"/>
<!-- END BDISK/PROFILE/IPXE -->
<!-- BDISK/PROFILE/GPG -->
<xs:element name="gpg" maxOccurs="1" minOccurs="1"/>
<!-- END BDISK/PROFILE/GPG -->
<!-- BDISK/PROFILE/PKI -->
<xs:element name="pki" maxOccurs="1" minOccurs="1"/>
<!-- END BDISK/PROFILE/PKI -->
<!-- BDISK/PROFILE/SYNC -->
<xs:element name="sync" maxOccurs="1" minOccurs="1"/>
<!-- END BDISK/PROFILE/SYNC -->
</xs:all>
<xs:attribute name="id" type="xs:positiveInteger"/>
<xs:attribute name="name" type="xs:string"/>
</xs:complexType>
</xs:element>
<!-- END BDISK/PROFILE -->
</xs:choice>
</xs:complexType>
</xs:element>
<!-- END BDISK -->
</xs:schema>

3
bin/xmllint.sh Executable file
View File

@ -0,0 +1,3 @@
#!/bin/bash

xmllint -schema ../bdisk/bdisk.xsd ../docs/examples/multi_profile.xml --noout

View File

@ -1,5 +1,5 @@
<?xml version='1.0' encoding='UTF-8'?> <?xml version='1.0' encoding='UTF-8'?>
<bdisk> <bdisk xmlns:bdisk="http://bdisk.square-r00t.net/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://bdisk.square-r00t.net bdisk.xsd">
<profile name="default" id="1" uuid="8cdd6bcb-c147-4a63-9779-b5433c510dbc"> <profile name="default" id="1" uuid="8cdd6bcb-c147-4a63-9779-b5433c510dbc">
<meta> <meta>
<names> <names>

View File

@ -1,5 +1,7 @@
<?xml version="1.0" encoding="UTF-8" ?> <?xml version="1.0" encoding="UTF-8" ?>
<bdisk> <bdisk xmlns:bdisk="http://bdisk.square-r00t.net/"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://bdisk.square-r00t.net bdisk.xsd">
<profile name="default" id="1" uuid="8cdd6bcb-c147-4a63-9779-b5433c510dbc"> <profile name="default" id="1" uuid="8cdd6bcb-c147-4a63-9779-b5433c510dbc">
<meta> <meta>
<names> <names>
@ -27,7 +29,8 @@
items. See the manual for more information. NO btags within the patterns is allowed. --> items. See the manual for more information. NO btags within the patterns is allowed. -->
<regexes> <regexes>
<pattern id="tarball_x86_64">archlinux-bootstrap-[0-9]{4}\.[0-9]{2}\.[0-9]{2}-x86_64\.tar\.gz$</pattern> <pattern id="tarball_x86_64">archlinux-bootstrap-[0-9]{4}\.[0-9]{2}\.[0-9]{2}-x86_64\.tar\.gz$</pattern>
<pattern id="sig_x86_64">archlinux-bootstrap-[0-9]{4}\.[0-9]{2}\.[0-9]{2}-x86_64\.tar\.gz\.sig$</pattern> <pattern id="sig_x86_64">archlinux-bootstrap-[0-9]{4}\.[0-9]{2}\.[0-9]{2}-x86_64\.tar\.gz\.sig$
</pattern>
<pattern id="tarball_i686">archlinux-bootstrap-[0-9]{4}\.[0-9]{2}\.[0-9]{2}-i686\.tar\.gz$</pattern> <pattern id="tarball_i686">archlinux-bootstrap-[0-9]{4}\.[0-9]{2}\.[0-9]{2}-i686\.tar\.gz$</pattern>
<pattern id="sig_i686">archlinux-bootstrap-[0-9]{4}\.[0-9]{2}\.[0-9]{2}-i686\.tar\.gz\.sig$</pattern> <pattern id="sig_i686">archlinux-bootstrap-[0-9]{4}\.[0-9]{2}\.[0-9]{2}-i686\.tar\.gz\.sig$</pattern>
</regexes> </regexes>
@ -38,7 +41,9 @@
</meta> </meta>
<accounts> <accounts>
<!-- Salted/hashed password is "test" --> <!-- Salted/hashed password is "test" -->
<rootpass hashed="yes">$6$7KfIdtHTcXwVrZAC$LZGNeMNz7v5o/cYuA48FAxtZynpIwO5B1CPGXnOW5kCTVpXVt4SypRqfM.AoKkFt/O7MZZ8ySXJmxpELKmdlF1</rootpass> <rootpass hashed="yes">
$6$7KfIdtHTcXwVrZAC$LZGNeMNz7v5o/cYuA48FAxtZynpIwO5B1CPGXnOW5kCTVpXVt4SypRqfM.AoKkFt/O7MZZ8ySXJmxpELKmdlF1
</rootpass>
<user sudo="yes"> <user sudo="yes">
<username>{xpath%//meta/names/uxname/text()}</username> <username>{xpath%//meta/names/uxname/text()}</username>
<!-- You can also use substitution from different profiles in this same configuration: --> <!-- You can also use substitution from different profiles in this same configuration: -->
@ -46,14 +51,16 @@
<comment>{xpath%//meta/dev/author/text()}</comment> <comment>{xpath%//meta/dev/author/text()}</comment>
<password hashed="no" <password hashed="no"
hash_algo="sha512" hash_algo="sha512"
salt="auto">testpassword</password> salt="auto">testpassword
</password>
</user> </user>
<user sudo="no"> <user sudo="no">
<username>testuser</username> <username>testuser</username>
<name>Test User</name> <name>Test User</name>
<password hashed="no" <password hashed="no"
hash_algo="sha512" hash_algo="sha512"
salt="auto">anothertestpassword</password> salt="auto">anothertestpassword
</password>
</user> </user>
</accounts> </accounts>
<sources> <sources>
@ -62,20 +69,25 @@
<rootpath>/iso/latest</rootpath> <rootpath>/iso/latest</rootpath>
<tarball flags="regex,latest">{regex%tarball_x86_64}</tarball> <tarball flags="regex,latest">{regex%tarball_x86_64}</tarball>
<checksum hash_algo="sha1" <checksum hash_algo="sha1"
explicit="no">sha1sums.txt</checksum> explicit="no">sha1sums.txt
<sig keys="7F2D434B9741E8AC" </checksum>
<sig keys="7F2D434B9741E8AC"
keyserver="hkp://pool.sks-keyservers.net" keyserver="hkp://pool.sks-keyservers.net"
flags="regex,latest">{regex%sig_x86_64}</sig> flags="regex,latest">{regex%sig_x86_64}
</sig>
</source> </source>
<source arch="i686"> <source arch="i686">
<mirror>http://archlinux32.mirror.domain.tld</mirror> <mirror>http://archlinux32.mirror.domain.tld</mirror>
<rootpath>/iso/latest</rootpath> <rootpath>/iso/latest</rootpath>
<tarball flags="regex,latest">{regex%tarball_i686}</tarball> <tarball flags="regex,latest">{regex%tarball_i686}</tarball>
<checksum hash_algo="sha512" <checksum hash_algo="sha512"
explicit="yes">cf83e1357eefb8bdf1542850d66d8007d620e4050b5715dc83f4a921d36ce9ce47d0d13c5d85f2b0ff8318d2877eec2f63b931bd47417a81a538327af927da3e</checksum> explicit="yes">
cf83e1357eefb8bdf1542850d66d8007d620e4050b5715dc83f4a921d36ce9ce47d0d13c5d85f2b0ff8318d2877eec2f63b931bd47417a81a538327af927da3e
</checksum>
<sig keys="248BF41F9BDD61D41D060AE774EDA3C6B06D0506" <sig keys="248BF41F9BDD61D41D060AE774EDA3C6B06D0506"
keyserver="hkp://pool.sks-keyservers.net" keyserver="hkp://pool.sks-keyservers.net"
flags="regex,latest">{regex%sig_i686}</sig> flags="regex,latest">{regex%sig_i686}
</sig>
</source> </source>
</sources> </sources>
<build its_full_of_stars="yes"> <build its_full_of_stars="yes">
@ -95,7 +107,7 @@
</paths> </paths>
<basedistro>archlinux</basedistro> <basedistro>archlinux</basedistro>
</build> </build>
<iso sign="yes" multi_arch="yes" /> <iso sign="yes" multi_arch="yes"/>
<ipxe sign="yes" iso="yes"> <ipxe sign="yes" iso="yes">
<uri>{xpath%//meta/dev/website/text()}/ipxe</uri> <uri>{xpath%//meta/dev/website/text()}/ipxe</uri>
</ipxe> </ipxe>
@ -109,7 +121,7 @@
then provide a path. then provide a path.
e.g.: e.g.:
<csr>{xpath%build/paths/ssl/text()}/ca.csr</csr> --> <csr>{xpath%build/paths/ssl/text()}/ca.csr</csr> -->
<csr /> <csr/>
<!-- If you use an index file (or want to) to serialize client certificates, specify it here. --> <!-- If you use an index file (or want to) to serialize client certificates, specify it here. -->
<!-- It must conform to CADB spec (https://pki-tutorial.readthedocs.io/en/latest/cadb.html). --> <!-- It must conform to CADB spec (https://pki-tutorial.readthedocs.io/en/latest/cadb.html). -->
<!-- You should probably also specify a serial file if so. --> <!-- You should probably also specify a serial file if so. -->
@ -121,7 +133,8 @@
be (securely) prompted for the passphrase to unlock it/add a passphrase to it. --> be (securely) prompted for the passphrase to unlock it/add a passphrase to it. -->
<key cipher="none" <key cipher="none"
passphrase="none" passphrase="none"
keysize="4096">{xpath%../../../build/paths/pki/text()}/ca.key</key> keysize="4096">{xpath%../../../build/paths/pki/text()}/ca.key
</key>
<subject> <subject>
<commonName>domain.tld</commonName> <commonName>domain.tld</commonName>
<countryName>XX</countryName> <countryName>XX</countryName>
@ -133,11 +146,14 @@
</subject> </subject>
</ca> </ca>
<client> <client>
<cert hash_algo="sha512">{xpath%../../../build/paths/pki/text()}/{xpath%../../../meta/names/uxname/text()}.crt</cert> <cert hash_algo="sha512">
<csr /> {xpath%../../../build/paths/pki/text()}/{xpath%../../../meta/names/uxname/text()}.crt
</cert>
<csr/>
<key cipher="none" <key cipher="none"
passphrase="none" passphrase="none"
keysize="4096">{xpath%//build/paths/pki/text()}/{xpath%../../../meta/names/uxname/text()}.key</key> keysize="4096">{xpath%//build/paths/pki/text()}/{xpath%../../../meta/names/uxname/text()}.key
</key>
<subject> <subject>
<commonName>some client name</commonName> <commonName>some client name</commonName>
<countryName>XX</countryName> <countryName>XX</countryName>
@ -159,7 +175,9 @@
<key algo="rsa" keysize="4096" expire="0"> <key algo="rsa" keysize="4096" expire="0">
<name>{xpath%../../../meta/dev/author/text()}</name> <name>{xpath%../../../meta/dev/author/text()}</name>
<email>{xpath%../../../meta/dev/email/text()}</email> <email>{xpath%../../../meta/dev/email/text()}</email>
<comment>for {xpath%../../../meta/names/pname/text()} [autogenerated] | {xpath%../../../meta/uri/text()} | {xpath%../../../meta/desc/text()}</comment> <comment>for {xpath%../../../meta/names/pname/text()} [autogenerated] | {xpath%../../../meta/uri/text()}
| {xpath%../../../meta/desc/text()}
</comment>
</key> </key>
</gpg> </gpg>
<sync> <sync>
@ -168,7 +186,8 @@
<tftp enabled="yes">/tftproot/{xpath%../../meta/names/uxname/text()}</tftp> <tftp enabled="yes">/tftproot/{xpath%../../meta/names/uxname/text()}</tftp>
<iso enabled="yes">/srv/http/isos/{xpath%../../meta/names/uxname/text()}</iso> <iso enabled="yes">/srv/http/isos/{xpath%../../meta/names/uxname/text()}</iso>
<gpg enabled="yes" <gpg enabled="yes"
format="asc">/srv/http/{xpath%../../meta/names/uxname/text()}/pubkey.asc</gpg> format="asc">/srv/http/{xpath%../../meta/names/uxname/text()}/pubkey.asc
</gpg>
<rsync enabled="yes"> <rsync enabled="yes">
<user>root</user> <user>root</user>
<host>mirror.domain.tld</host> <host>mirror.domain.tld</host>