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" ?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
targetNamespace="http://bdisk.square-r00t.net"
xmlns="http://bdisk.square-r00t.net"
targetNamespace="http://bdisk.square-r00t.net/"
xmlns="http://bdisk.square-r00t.net/"
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'?>
<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">
<meta>
<names>

View File

@ -1,5 +1,7 @@
<?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">
<meta>
<names>
@ -27,7 +29,8 @@
items. See the manual for more information. NO btags within the patterns is allowed. -->
<regexes>
<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="sig_i686">archlinux-bootstrap-[0-9]{4}\.[0-9]{2}\.[0-9]{2}-i686\.tar\.gz\.sig$</pattern>
</regexes>
@ -38,7 +41,9 @@
</meta>
<accounts>
<!-- 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">
<username>{xpath%//meta/names/uxname/text()}</username>
<!-- You can also use substitution from different profiles in this same configuration: -->
@ -46,14 +51,16 @@
<comment>{xpath%//meta/dev/author/text()}</comment>
<password hashed="no"
hash_algo="sha512"
salt="auto">testpassword</password>
salt="auto">testpassword
</password>
</user>
<user sudo="no">
<username>testuser</username>
<name>Test User</name>
<password hashed="no"
hash_algo="sha512"
salt="auto">anothertestpassword</password>
salt="auto">anothertestpassword
</password>
</user>
</accounts>
<sources>
@ -62,20 +69,25 @@
<rootpath>/iso/latest</rootpath>
<tarball flags="regex,latest">{regex%tarball_x86_64}</tarball>
<checksum hash_algo="sha1"
explicit="no">sha1sums.txt</checksum>
<sig keys="7F2D434B9741E8AC"
explicit="no">sha1sums.txt
</checksum>
<sig keys="7F2D434B9741E8AC"
keyserver="hkp://pool.sks-keyservers.net"
flags="regex,latest">{regex%sig_x86_64}</sig>
flags="regex,latest">{regex%sig_x86_64}
</sig>
</source>
<source arch="i686">
<mirror>http://archlinux32.mirror.domain.tld</mirror>
<rootpath>/iso/latest</rootpath>
<tarball flags="regex,latest">{regex%tarball_i686}</tarball>
<checksum hash_algo="sha512"
explicit="yes">cf83e1357eefb8bdf1542850d66d8007d620e4050b5715dc83f4a921d36ce9ce47d0d13c5d85f2b0ff8318d2877eec2f63b931bd47417a81a538327af927da3e</checksum>
explicit="yes">
cf83e1357eefb8bdf1542850d66d8007d620e4050b5715dc83f4a921d36ce9ce47d0d13c5d85f2b0ff8318d2877eec2f63b931bd47417a81a538327af927da3e
</checksum>
<sig keys="248BF41F9BDD61D41D060AE774EDA3C6B06D0506"
keyserver="hkp://pool.sks-keyservers.net"
flags="regex,latest">{regex%sig_i686}</sig>
flags="regex,latest">{regex%sig_i686}
</sig>
</source>
</sources>
<build its_full_of_stars="yes">
@ -95,7 +107,7 @@
</paths>
<basedistro>archlinux</basedistro>
</build>
<iso sign="yes" multi_arch="yes" />
<iso sign="yes" multi_arch="yes"/>
<ipxe sign="yes" iso="yes">
<uri>{xpath%//meta/dev/website/text()}/ipxe</uri>
</ipxe>
@ -109,7 +121,7 @@
then provide a path.
e.g.:
<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. -->
<!-- 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. -->
@ -121,7 +133,8 @@
be (securely) prompted for the passphrase to unlock it/add a passphrase to it. -->
<key cipher="none"
passphrase="none"
keysize="4096">{xpath%../../../build/paths/pki/text()}/ca.key</key>
keysize="4096">{xpath%../../../build/paths/pki/text()}/ca.key
</key>
<subject>
<commonName>domain.tld</commonName>
<countryName>XX</countryName>
@ -133,11 +146,14 @@
</subject>
</ca>
<client>
<cert hash_algo="sha512">{xpath%../../../build/paths/pki/text()}/{xpath%../../../meta/names/uxname/text()}.crt</cert>
<csr />
<cert hash_algo="sha512">
{xpath%../../../build/paths/pki/text()}/{xpath%../../../meta/names/uxname/text()}.crt
</cert>
<csr/>
<key cipher="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>
<commonName>some client name</commonName>
<countryName>XX</countryName>
@ -159,7 +175,9 @@
<key algo="rsa" keysize="4096" expire="0">
<name>{xpath%../../../meta/dev/author/text()}</name>
<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>
</gpg>
<sync>
@ -168,7 +186,8 @@
<tftp enabled="yes">/tftproot/{xpath%../../meta/names/uxname/text()}</tftp>
<iso enabled="yes">/srv/http/isos/{xpath%../../meta/names/uxname/text()}</iso>
<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">
<user>root</user>
<host>mirror.domain.tld</host>