i should commit this.
This commit is contained in:
parent
b134ee67bd
commit
9f74e97c45
690
bdisk/bdisk.xsd
690
bdisk/bdisk.xsd
@ -3,9 +3,247 @@
|
||||
targetNamespace="http://bdisk.square-r00t.net/"
|
||||
xmlns="http://bdisk.square-r00t.net/"
|
||||
elementFormDefault="qualified">
|
||||
|
||||
<!-- CUSTOM TYPES -->
|
||||
<!-- t_btag_uri: a string that will allow btags (xpath or variable only) or a URI string (but NOT a URN). -->
|
||||
<!-- We can't use xs:anyURI because it is too loose (allows things like relative paths, etc.) -->
|
||||
<!-- but ALSO too restrictive in that btags fail validation ({ and } are invalid for anyURI, -->
|
||||
<!-- ironically). -->
|
||||
<xs:simpleType name="t_btag_uri">
|
||||
<xs:restriction base="xs:string">
|
||||
<xs:pattern value="\w+:(/?/?)[^\s]+"/>
|
||||
<xs:pattern value=".*\{variable%[A-Za-z0-9_]\}.*"/>
|
||||
<xs:pattern value=".*\{xpath%[A-Za-z0-9_/\(\)\.\*@\-]+\}.*"/>
|
||||
</xs:restriction>
|
||||
</xs:simpleType>
|
||||
<!-- END t_btag_uri -->
|
||||
|
||||
<!-- t_filename: a POSIX fully-portable filename. -->
|
||||
<xs:simpleType name="t_filename">
|
||||
<xs:restriction base="xs:string">
|
||||
<xs:pattern value="([a-z0-9._-]+){1,255}"/>
|
||||
<xs:pattern value=".*\{variable%[A-Za-z0-9_]\}.*"/>
|
||||
<xs:pattern value=".*\{xpath%[A-Za-z0-9_/\(\)\.\*@\-]+\}.*"/>
|
||||
<!-- We don't allow (string)(regex) or (regex)(string) or (string)(regex)(string) or multiple regexes -->
|
||||
<!-- because that's just... not feasible to manage from a parsing perspective. -->
|
||||
<xs:pattern value="\{regex%.+\}"/>
|
||||
</xs:restriction>
|
||||
</xs:simpleType>
|
||||
<!-- END t_filename -->
|
||||
|
||||
<!-- t_gpg_keyid: a set of various patterns that match GPG key IDs. -->
|
||||
<xs:simpleType name="t_gpg_keyid">
|
||||
<xs:restriction base="xs:string">
|
||||
<xs:pattern value="(none|new)"/>
|
||||
<xs:pattern value="(auto|default)"/>
|
||||
<xs:pattern value="(0x)?[0-9A-Fa-f]{40}"/>
|
||||
<xs:pattern value="(0x)?[0-9A-Fa-f]{16}"/>
|
||||
<xs:pattern value="(0x)?[0-9A-Fa-f]{8}"/>
|
||||
<xs:pattern value="([0-9A-Fa-f ]{4}){5} ?([0-9A-Fa-f ]{4}){4}[0-9A-Fa-f]{4}"/>
|
||||
</xs:restriction>
|
||||
</xs:simpleType>
|
||||
<!-- END t_gpg_keyid -->
|
||||
|
||||
<!-- t_gpg_keyid_list: a type for a list of key IDs. -->
|
||||
<xs:simpleType name="t_gpg_keyid_list">
|
||||
<xs:list itemType="t_gpg_keyid"/>
|
||||
</xs:simpleType>
|
||||
<!-- END t_gpg_key_list -->
|
||||
|
||||
<!-- t_net_loc: a remote host. Used for PKI Subject's commonName and host for rsync. -->
|
||||
<xs:simpleType name="t_net_loc">
|
||||
<xs:restriction base="xs:string">
|
||||
<xs:pattern
|
||||
value="(([a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9\-]*[a-zA-Z0-9])\.)*([A-Za-z0-9]|[A-Za-z0-9][A-Za-z0-9\-]*[A-Za-z0-9])"/>
|
||||
</xs:restriction>
|
||||
</xs:simpleType>
|
||||
<!-- END t_net_loc -->
|
||||
|
||||
<!-- t_pass_hash_algo: used for t_password. -->
|
||||
<xs:simpleType name="t_pass_hash_algo">
|
||||
<xs:restriction base="xs:string">
|
||||
<xs:enumeration value="des"/>
|
||||
<xs:enumeration value="md5"/>
|
||||
<xs:enumeration value="sha256"/>
|
||||
<xs:enumeration value="sha512"/>
|
||||
</xs:restriction>
|
||||
</xs:simpleType>
|
||||
<!-- END t_pass_hash_algo -->
|
||||
|
||||
<!-- t_pass_salt: used for t_password. -->
|
||||
<xs:simpleType name="t_pass_salt">
|
||||
<xs:restriction base="xs:string">
|
||||
<xs:pattern value="($[156]($rounds=[0-9]+)?$[a-zA-Z0-9./]{1,16}$?|auto|)"/>
|
||||
<xs:pattern value="\{variable%[A-Za-z0-9_]\}"/>
|
||||
<xs:pattern value="\{xpath%[A-Za-z0-9_\(\)\.\*\-/]+\}"/>
|
||||
</xs:restriction>
|
||||
</xs:simpleType>
|
||||
<!-- END t_pass_salt -->
|
||||
|
||||
<!-- t_password: used for rootpass and user/password elements. -->
|
||||
<xs:complexType name="t_password">
|
||||
<!-- The below will need some fleshing out and testing. It may not be possible strictly via XSD. -->
|
||||
<!-- TODO: restrict the value further with a union or multi-group regex that checks for a valid length? -->
|
||||
<!-- des: ????? -->
|
||||
<!-- md5: "[a-zA-Z0-9./]{22}" -->
|
||||
<!-- sha256: "[a-zA-Z0-9./]{43}" -->
|
||||
<!-- sha512: "[a-zA-Z0-9./]{86}" -->
|
||||
<xs:simpleContent>
|
||||
<xs:extension base="xs:string">
|
||||
<xs:attribute name="hash_algo" type="t_pass_hash_algo"/>
|
||||
<xs:attribute name="hashed" type="xs:boolean" use="required"/>
|
||||
<xs:attribute name="salt" type="t_pass_salt"/>
|
||||
</xs:extension>
|
||||
</xs:simpleContent>
|
||||
</xs:complexType>
|
||||
<!-- END t_password -->
|
||||
|
||||
<!-- t_path: for specifying subdirectories (either local filesystem or remote paths). -->
|
||||
<xs:simpleType name="t_path">
|
||||
<xs:restriction base="xs:string">
|
||||
<!-- We include blank to operate on default actions (or default filepaths). -->
|
||||
<xs:pattern value=""/>
|
||||
<xs:pattern value="(.+)/([^/]+)"/>
|
||||
<xs:pattern value="((.+)/([^/]+))?\{variable%[A-Za-z0-9_]\}((.+)/([^/]+))?"/>
|
||||
<xs:pattern value="((.+)/([^/]+))?\{xpath%[A-Za-z0-9_\(\)\.\*\-/]+\}((.+)/([^/]+))?"/>
|
||||
</xs:restriction>
|
||||
</xs:simpleType>
|
||||
<!-- END t_path -->
|
||||
|
||||
<!-- t_pki_cert: used for pki/ca/cert and pki/client/cert. -->
|
||||
<xs:complexType name="t_pki_cert">
|
||||
<xs:simpleContent>
|
||||
<xs:extension base="t_path">
|
||||
<xs:attribute name="hash_algo" use="required">
|
||||
<xs:simpleType>
|
||||
<xs:restriction base="xs:string">
|
||||
<xs:enumeration value="blake2b512"/>
|
||||
<xs:enumeration value="blake2s256"/>
|
||||
<xs:enumeration value="gost"/>
|
||||
<xs:enumeration value="md4"/>
|
||||
<xs:enumeration value="md5"/>
|
||||
<xs:enumeration value="mdc2"/>
|
||||
<xs:enumeration value="rmd160"/>
|
||||
<xs:enumeration value="sha1"/>
|
||||
<xs:enumeration value="sha224"/>
|
||||
<xs:enumeration value="sha256"/>
|
||||
<xs:enumeration value="sha384"/>
|
||||
<xs:enumeration value="sha512"/>
|
||||
<xs:enumeration value="none"/>
|
||||
</xs:restriction>
|
||||
</xs:simpleType>
|
||||
</xs:attribute>
|
||||
</xs:extension>
|
||||
</xs:simpleContent>
|
||||
</xs:complexType>
|
||||
<!-- END t_pki_cert -->
|
||||
|
||||
<!-- t_pki_key: used for pki/ca/key and pki/client/key -->
|
||||
<xs:complexType name="t_pki_key">
|
||||
<xs:simpleContent>
|
||||
<xs:extension base="t_path">
|
||||
<xs:attribute name="cipher" use="required">
|
||||
<xs:simpleType>
|
||||
<xs:restriction base="xs:string">
|
||||
<xs:enumeration value="aes128"/>
|
||||
<xs:enumeration value="aes192"/>
|
||||
<xs:enumeration value="bf"/>
|
||||
<xs:enumeration value="blowfish"/>
|
||||
<xs:enumeration value="camellia128"/>
|
||||
<xs:enumeration value="camellia192"/>
|
||||
<xs:enumeration value="camellia256"/>
|
||||
<xs:enumeration value="des"/>
|
||||
<xs:enumeration value="rc2"/>
|
||||
<xs:enumeration value="seed"/>
|
||||
<xs:enumeration value="none"/>
|
||||
</xs:restriction>
|
||||
</xs:simpleType>
|
||||
</xs:attribute>
|
||||
<xs:attribute name="passphrase" type="xs:string"/>
|
||||
<xs:attribute name="keysize"
|
||||
type="xs:positiveInteger"/>
|
||||
</xs:extension>
|
||||
</xs:simpleContent>
|
||||
</xs:complexType>
|
||||
<!-- END t_pki_key -->
|
||||
|
||||
<!-- t_pki_subject: used for pki/ca/subject and pki/client/subject -->
|
||||
<xs:complexType name="t_pki_subject">
|
||||
<xs:all>
|
||||
<!-- .../SUBJECT/COMMONNAME -->
|
||||
<xs:element name="commonName" type="t_net_loc"/>
|
||||
<!-- END .../SUBJECT/COMMONNAME -->
|
||||
<!-- .../SUBJECT/COUNTRYNAME -->
|
||||
<xs:element name="countryName">
|
||||
<xs:simpleType>
|
||||
<xs:restriction base="xs:string">
|
||||
<!-- We can't validate an actual ISO-3166 ALPHA-2 code, but we can validate the format. -->
|
||||
<!-- TODO: maybe cron the generation of an external namespace? -->
|
||||
<xs:pattern value="[A-Z]{2}"/>
|
||||
</xs:restriction>
|
||||
</xs:simpleType>
|
||||
</xs:element>
|
||||
<!-- END .../SUBJECT/COUNTRYNAME -->
|
||||
<!-- .../SUBJECT/LOCALITYNAME -->
|
||||
<xs:element name="localityName" type="xs:string"/>
|
||||
<!-- END .../SUBJECT/LOCALITYNAME -->
|
||||
<!-- .../SUBJECT/STATEORPROVINCENAME -->
|
||||
<xs:element name="stateOrProvinceName"
|
||||
type="xs:string"/>
|
||||
<!-- END .../SUBJECT/STATEORPROVINCENAME -->
|
||||
<!-- .../SUBJECT/ORGANIZATION -->
|
||||
<xs:element name="organization" type="xs:string"/>
|
||||
<!-- END .../SUBJECT/ORGANIZATION -->
|
||||
<!-- .../SUBJECT/ORGANIZATIONALUNITNAME -->
|
||||
<xs:element name="organizationalUnitName"
|
||||
type="xs:string"/>
|
||||
<!-- END .../SUBJECT/ORGANIZATIONALUNITNAME -->
|
||||
<!-- .../SUBJECT/EMAILADDRESS -->
|
||||
<xs:element name="emailAddress" type="xs:string"/>
|
||||
<!-- END .../SUBJECT/EMAILADDRESS -->
|
||||
</xs:all>
|
||||
</xs:complexType>
|
||||
<!-- END t_pki_subject -->
|
||||
|
||||
<!-- t_remote_file: an element that lets us define both a file pattern for remote content and flags attribute. -->
|
||||
<xs:complexType name="t_remote_file">
|
||||
<xs:simpleContent>
|
||||
<xs:extension base="t_filename">
|
||||
<xs:attribute name="flags" type="t_remote_file_flags" use="optional"/>
|
||||
</xs:extension>
|
||||
</xs:simpleContent>
|
||||
</xs:complexType>
|
||||
<!-- END t_remote_file -->
|
||||
|
||||
<!-- t_remote_file_flags: a type to match a list of known flags. -->
|
||||
<xs:simpleType name="t_remote_file_flags">
|
||||
<xs:list>
|
||||
<xs:simpleType>
|
||||
<xs:restriction base="xs:string">
|
||||
<!-- Currently we only support two flags. -->
|
||||
<xs:enumeration value="regex"/>
|
||||
<xs:enumeration value="latest"/>
|
||||
</xs:restriction>
|
||||
</xs:simpleType>
|
||||
</xs:list>
|
||||
</xs:simpleType>
|
||||
<!-- END t_remote_file_flags -->
|
||||
|
||||
<!-- t_username: enforce a POSIX-compliant username. Used for user/username elements. -->
|
||||
<xs:simpleType name="t_username">
|
||||
<xs:restriction base="xs:string">
|
||||
<xs:pattern value="[a-z_]([a-z0-9_-]{0,31}|[a-z0-9_-]{0,30}$)"/>
|
||||
<xs:pattern value="\{variable%[A-Za-z0-9_]\}"/>
|
||||
<xs:pattern value="\{xpath%[A-Za-z0-9_\(\)\.\*\-/]+\}"/>
|
||||
</xs:restriction>
|
||||
</xs:simpleType>
|
||||
<!-- END t_username -->
|
||||
<!-- END CUSTOM TYPES -->
|
||||
|
||||
<!-- ROOT ELEMENT ("BDISK") -->
|
||||
<xs:element name="bdisk">
|
||||
<xs:complexType>
|
||||
<!-- Should this be xs:sequence instead? -->
|
||||
<xs:choice>
|
||||
<!-- BDISK/PROFILE -->
|
||||
<xs:element name="profile" maxOccurs="unbounded" minOccurs="1">
|
||||
@ -23,8 +261,9 @@
|
||||
<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:pattern value="[A-Z0-9]{1,8}"/>
|
||||
<xs:pattern value="\{variable%[A-Za-z0-9_]\}"/>
|
||||
<xs:pattern value="\{xpath%[A-Za-z0-9_\(\)\.\*\-/]+\}"/>
|
||||
</xs:restriction>
|
||||
</xs:simpleType>
|
||||
</xs:element>
|
||||
@ -33,8 +272,12 @@
|
||||
<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})"/>
|
||||
<!-- refer to the 2009 POSIX spec, "3.282 Portable Filename Character Set" -->
|
||||
<!-- http://pubs.opengroup.org/onlinepubs/9699919799/basedefs/V1_chap03.html#tag_03_282 -->
|
||||
<!-- (We use this string to name some files.) -->
|
||||
<xs:pattern value="([a-z0-9._-]+){1,255}"/>
|
||||
<xs:pattern value="\{variable%[A-Za-z0-9_]\}"/>
|
||||
<xs:pattern value="\{xpath%[A-Za-z0-9_\(\)\.\*\-/]+\}"/>
|
||||
</xs:restriction>
|
||||
</xs:simpleType>
|
||||
</xs:element>
|
||||
@ -43,6 +286,7 @@
|
||||
<xs:element name="pname" maxOccurs="1" minOccurs="1">
|
||||
<xs:simpleType>
|
||||
<xs:restriction base="xs:string">
|
||||
<!-- TODO: Can I use UTF-8 instead? -->
|
||||
<!-- https://stackoverflow.com/a/9805789/733214 -->
|
||||
<xs:pattern value="\p{IsBasicLatin}*"/>
|
||||
</xs:restriction>
|
||||
@ -57,10 +301,30 @@
|
||||
<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"/>
|
||||
<xs:element name="dev" maxOccurs="1" minOccurs="1">
|
||||
<xs:complexType>
|
||||
<xs:all>
|
||||
<!-- BDISK/PROFILE/META/DEV/AUTHOR -->
|
||||
<xs:element name="author" maxOccurs="1" minOccurs="1"
|
||||
type="xs:string"/>
|
||||
<!-- END BDISK/PROFILE/META/DEV/AUTHOR -->
|
||||
<!-- BDISK/PROFILE/META/DEV/EMAIL -->
|
||||
<!-- The following does NOT WORK. Shame, really. -->
|
||||
<!-- It seems to be an invalid pattern per my XSD validator (xmllint). -->
|
||||
<!--<xs:pattern value="([!#-'*+/-9=?A-Z^-~-]+(\.[!#-'*+/-9=?A-Z^-~-]+)*|"([]!#-[^-~ \t]|(\\[\t -~]))+")@([!#-'*+/-9=?A-Z^-~-]+(\.[!#-'*+/-9=?A-Z^-~-]+)*|\[[\t -Z^-~]*])"/>-->
|
||||
<xs:element name="email" maxOccurs="1" minOccurs="1"
|
||||
type="xs:string"/>
|
||||
<!-- END BDISK/PROFILE/META/DEV/EMAIL -->
|
||||
<!-- BDISK/PROFILE/META/DEV/WEBSITE -->
|
||||
<xs:element name="website" maxOccurs="1" minOccurs="1"
|
||||
type="t_btag_uri"/>
|
||||
<!-- END BDISK/PROFILE/META/DEV/WEBSITE -->
|
||||
</xs:all>
|
||||
</xs:complexType>
|
||||
</xs:element>
|
||||
<!-- END BDISK/PROFILE/META/DEV -->
|
||||
<!-- BDISK/PROFILE/META/URI -->
|
||||
<xs:element name="uri" maxOccurs="1" minOccurs="1" type="xs:anyURI"/>
|
||||
<xs:element name="uri" maxOccurs="1" minOccurs="1" type="t_btag_uri"/>
|
||||
<!-- END BDISK/PROFILE/META/URI -->
|
||||
<!-- BDISK/PROFILE/META/VER -->
|
||||
<xs:element name="ver" maxOccurs="1" minOccurs="1" type="xs:string"/>
|
||||
@ -114,29 +378,427 @@
|
||||
</xs:element>
|
||||
<!-- END BDISK/PROFILE/META -->
|
||||
<!-- BDISK/PROFILE/ACCOUNTS -->
|
||||
<xs:element name="accounts" maxOccurs="1" minOccurs="1"/>
|
||||
<xs:element name="accounts" maxOccurs="1" minOccurs="1">
|
||||
<xs:complexType>
|
||||
<xs:sequence>
|
||||
<!-- BDISK/PROFILE/ACCOUNTS/ROOTPASS -->
|
||||
<xs:element name="rootpass" maxOccurs="1" minOccurs="1" type="t_password"/>
|
||||
<!-- END BDISK/PROFILE/ACCOUNTS/ROOTPASS -->
|
||||
<!-- BDISK/PROFILE/ACCOUNTS/USER -->
|
||||
<xs:element name="user" maxOccurs="unbounded" minOccurs="0">
|
||||
<xs:complexType>
|
||||
<xs:all>
|
||||
<!-- BDISK/PROFILE/ACCOUNTS/USER/USERNAME -->
|
||||
<xs:element name="username" type="t_username" minOccurs="1"
|
||||
maxOccurs="1"/>
|
||||
<!-- END BDISK/PROFILE/ACCOUNTS/USER/USERNAME -->
|
||||
<!-- BDISK/PROFILE/ACCOUNTS/USER/COMMENT -->
|
||||
<xs:element name="comment" type="xs:string" maxOccurs="1"
|
||||
minOccurs="0"/>
|
||||
<!-- END BDISK/PROFILE/ACCOUNTS/USER/COMMENT -->
|
||||
<!-- BDISK/PROFILE/ACCOUNTS/USER/PASSWORD -->
|
||||
<xs:element name="password" type="t_password" maxOccurs="1"
|
||||
minOccurs="1"/>
|
||||
<!-- END BDISK/PROFILE/ACCOUNTS/USER/PASSWORD -->
|
||||
</xs:all>
|
||||
<xs:attribute name="sudo" type="xs:boolean" use="optional"/>
|
||||
</xs:complexType>
|
||||
</xs:element>
|
||||
<!-- END BDISK/PROFILE/ACCOUNTS/USER -->
|
||||
</xs:sequence>
|
||||
</xs:complexType>
|
||||
</xs:element>
|
||||
<!-- END BDISK/PROFILE/ACCOUNTS -->
|
||||
<!-- BDISK/PROFILE/BUILD-->
|
||||
<xs:element name="build" maxOccurs="1" minOccurs="1"/>
|
||||
<!-- BDISK/PROFILE/SOURCES -->
|
||||
<xs:element name="sources" maxOccurs="1" minOccurs="1">
|
||||
<xs:complexType>
|
||||
<xs:sequence>
|
||||
<!-- BDisk only supports two different architectures (x86/i686 and x86_64, respectively) currently. -->
|
||||
<!-- TODO: future improvements may let us include e.g. two different x86_64 environments (e.g. CentOS and Debian on the same media), but this is like, still in development stages. -->
|
||||
<!-- BDISK/PROFILE/SOURCES/SOURCE -->
|
||||
<xs:element name="source" minOccurs="1" maxOccurs="2">
|
||||
<xs:complexType>
|
||||
<xs:all>
|
||||
<!-- We cheat here. TECHNICALLY it should ONLY be scheme://location (no /path...), but there isn't a data type for that. -->
|
||||
<!-- Currently we enforce only one item. Future BDisk versions may be able to make use of multiple <mirror>s and select best one based on speed. -->
|
||||
<!-- BDISK/PROFILE/SOURCES/SOURCE/MIRROR -->
|
||||
<xs:element name="mirror" type="t_btag_uri" maxOccurs="1"
|
||||
minOccurs="1"/>
|
||||
<!-- END BDISK/PROFILE/SOURCES/SOURCE/MIRROR -->
|
||||
<!-- BDISK/PROFILE/SOURCES/SOURCE/ROOTPATH -->
|
||||
<xs:element name="rootpath" maxOccurs="1" minOccurs="1"
|
||||
type="t_path"/>
|
||||
<!-- END BDISK/PROFILE/SOURCES/SOURCE/ROOTPATH -->
|
||||
<!-- BDISK/PROFILE/SOURCES/SOURCE/TARBALL -->
|
||||
<xs:element name="tarball" maxOccurs="1" minOccurs="1"
|
||||
type="t_remote_file"/>
|
||||
<!-- END BDISK/PROFILE/SOURCES/SOURCE/TARBALL -->
|
||||
<!-- BDISK/PROFILE/SOURCES/SOURCE/CHECKSUM -->
|
||||
<xs:element name="checksum" maxOccurs="1" minOccurs="0">
|
||||
<xs:complexType>
|
||||
<xs:simpleContent>
|
||||
<xs:extension base="t_remote_file">
|
||||
<!-- There is NO way we can validate this, because it will vary based on the algorithms supported by the build host. -->
|
||||
<xs:attribute name="hash_algo" type="xs:string" use="required"/>
|
||||
<xs:attribute name="explicit" type="xs:boolean" use="required"/>
|
||||
</xs:extension>
|
||||
</xs:simpleContent>
|
||||
</xs:complexType>
|
||||
</xs:element>
|
||||
<!-- END BDISK/PROFILE/SOURCES/SOURCE/CHECKSUM -->
|
||||
<!-- BDISK/PROFILE/SOURCES/SOURCE/SIG -->
|
||||
<xs:element name="sig" maxOccurs="1" minOccurs="0">
|
||||
<xs:complexType>
|
||||
<xs:simpleContent>
|
||||
<xs:extension base="t_remote_file">
|
||||
<!-- Required; otherwise there's no point using it. -->
|
||||
<xs:attribute name="keys" type="t_gpg_keyid_list" use="required"/>
|
||||
<xs:attribute name="keyserver" type="t_btag_uri"/>
|
||||
</xs:extension>
|
||||
</xs:simpleContent>
|
||||
</xs:complexType>
|
||||
</xs:element>
|
||||
<!-- END BDISK/PROFILE/SOURCES/SOURCE/SIG-->
|
||||
</xs:all>
|
||||
<xs:attribute name="arch">
|
||||
<xs:simpleType>
|
||||
<xs:restriction base="xs:string">
|
||||
<xs:pattern value="(i686|x86(_64)?|32|64)"/>
|
||||
</xs:restriction>
|
||||
</xs:simpleType>
|
||||
</xs:attribute>
|
||||
</xs:complexType>
|
||||
</xs:element>
|
||||
<!-- END BDISK/PROFILE/SOURCES/SOURCE -->
|
||||
</xs:sequence>
|
||||
</xs:complexType>
|
||||
</xs:element>
|
||||
<!-- END BDISK/PROFILE/SOURCES -->
|
||||
<!-- BDISK/PROFILE/BUILD -->
|
||||
<xs:element name="build" maxOccurs="1" minOccurs="1">
|
||||
<xs:complexType>
|
||||
<xs:all>
|
||||
<!-- BDISK/PROFILE/BUILD/PATHS -->
|
||||
<xs:element name="paths">
|
||||
<xs:complexType>
|
||||
<xs:all>
|
||||
<!-- BDISK/PROFILE/BUILD/PATHS/BASE -->
|
||||
<xs:element name="base" maxOccurs="1" minOccurs="1" type="t_path"/>
|
||||
<!-- END BDISK/PROFILE/BUILD/PATHS/BASE -->
|
||||
<!-- BDISK/PROFILE/BUILD/PATHS/CACHE -->
|
||||
<xs:element name="cache" maxOccurs="1" minOccurs="1" type="t_path"/>
|
||||
<!-- END BDISK/PROFILE/BUILD/PATHS/CACHE -->
|
||||
<!-- BDISK/PROFILE/BUILD/PATHS/CHROOT -->
|
||||
<xs:element name="chroot" maxOccurs="1" minOccurs="1"
|
||||
type="t_path"/>
|
||||
<!-- END BDISK/PROFILE/BUILD/PATHS/CHROOT -->
|
||||
<!-- BDISK/PROFILE/BUILD/PATHS/OVERLAY -->
|
||||
<xs:element name="overlay" maxOccurs="1" minOccurs="1"
|
||||
type="t_path"/>
|
||||
<!-- END BDISK/PROFILE/BUILD/PATHS/OVERLAY -->
|
||||
<!-- BDISK/PROFILE/BUILD/PATHS/TEMPLATES -->
|
||||
<xs:element name="templates" maxOccurs="1" minOccurs="1"
|
||||
type="t_path"/>
|
||||
<!-- END BDISK/PROFILE/BUILD/PATHS/TEMPLATES -->
|
||||
<!-- BDISK/PROFILE/BUILD/PATHS/MOUNT -->
|
||||
<xs:element name="mount" maxOccurs="1" minOccurs="1" type="t_path"/>
|
||||
<!-- END BDISK/PROFILE/BUILD/PATHS/MOUNT -->
|
||||
<!-- BDISK/PROFILE/BUILD/PATHS/DISTROS -->
|
||||
<xs:element name="distros" maxOccurs="1" minOccurs="1"
|
||||
type="t_path"/>
|
||||
<!-- END BDISK/PROFILE/BUILD/PATHS/DISTROS -->
|
||||
<!-- BDISK/PROFILE/BUILD/PATHS/DEST -->
|
||||
<xs:element name="dest" maxOccurs="1" minOccurs="1" type="t_path"/>
|
||||
<!-- END BDISK/PROFILE/BUILD/PATHS/DEST -->
|
||||
<!-- BDISK/PROFILE/BUILD/PATHS/ISO -->
|
||||
<xs:element name="iso" maxOccurs="1" minOccurs="1" type="t_path"/>
|
||||
<!-- END BDISK/PROFILE/BUILD/PATHS/ISO -->
|
||||
<!-- BDISK/PROFILE/BUILD/PATHS/HTTP -->
|
||||
<xs:element name="http" maxOccurs="1" minOccurs="1" type="t_path"/>
|
||||
<!-- END BDISK/PROFILE/BUILD/PATHS/HTTP -->
|
||||
<!-- BDISK/PROFILE/BUILD/PATHS/TFTP -->
|
||||
<xs:element name="tftp" maxOccurs="1" minOccurs="1" type="t_path"/>
|
||||
<!-- END BDISK/PROFILE/BUILD/PATHS/TFTP -->
|
||||
<!-- EBDISK/PROFILE/BUILD/PATHS/PKI -->
|
||||
<xs:element name="pki" maxOccurs="1" minOccurs="1" type="t_path"/>
|
||||
<!-- END BDISK/PROFILE/BUILD/PATHS/PKI -->
|
||||
</xs:all>
|
||||
</xs:complexType>
|
||||
</xs:element>
|
||||
<!-- END BDISK/PROFILE/BUILD/PATHS -->
|
||||
<!-- BDISK/PROFILE/BUILD/BASEDISTRO -->
|
||||
<xs:element name="basedistro"/>
|
||||
<!-- END BDISK/PROFILE/BUILD/BASEDISTRO -->
|
||||
</xs:all>
|
||||
<xs:attribute name="its_full_of_stars" type="xs:boolean"/>
|
||||
</xs:complexType>
|
||||
</xs:element>
|
||||
<!-- END BDISK/PROFILE/BUILD -->
|
||||
<!-- BDISK/PROFILE/ISO -->
|
||||
<xs:element name="iso" maxOccurs="1" minOccurs="1"/>
|
||||
<xs:element name="iso" maxOccurs="1" minOccurs="1">
|
||||
<xs:complexType>
|
||||
<xs:attribute name="sign" type="xs:boolean"/>
|
||||
<xs:attribute name="multi_arch">
|
||||
<xs:simpleType>
|
||||
<xs:restriction base="xs:string">
|
||||
<xs:enumeration value="yes"/>
|
||||
<xs:enumeration value="no"/>
|
||||
<xs:enumeration value="true"/>
|
||||
<xs:enumeration value="false"/>
|
||||
<xs:enumeration value="x86_64"/>
|
||||
<xs:enumeration value="x86"/>
|
||||
<xs:enumeration value="64"/>
|
||||
<xs:enumeration value="32"/>
|
||||
<xs:enumeration value="i686"/>
|
||||
</xs:restriction>
|
||||
</xs:simpleType>
|
||||
</xs:attribute>
|
||||
</xs:complexType>
|
||||
</xs:element>
|
||||
<!-- END BDISK/PROFILE/ISO -->
|
||||
<!-- BDISK/PROFILE/IPXE -->
|
||||
<xs:element name="ipxe" maxOccurs="1" minOccurs="1"/>
|
||||
<xs:element name="ipxe" maxOccurs="1" minOccurs="1">
|
||||
<xs:complexType>
|
||||
<xs:all>
|
||||
<!-- BDISK/PROFILE/IPXE/URI -->
|
||||
<xs:element name="uri" type="t_btag_uri" maxOccurs="1" minOccurs="1"/>
|
||||
<!-- END BDISK/PROFILE/IPXE/URI -->
|
||||
</xs:all>
|
||||
<xs:attribute name="sign" type="xs:boolean"/>
|
||||
<xs:attribute name="iso" type="xs:boolean"/>
|
||||
</xs:complexType>
|
||||
</xs:element>
|
||||
<!-- END BDISK/PROFILE/IPXE -->
|
||||
<!-- BDISK/PROFILE/GPG -->
|
||||
<xs:element name="gpg" maxOccurs="1" minOccurs="1"/>
|
||||
<xs:element name="gpg" maxOccurs="1" minOccurs="1">
|
||||
<xs:complexType>
|
||||
<xs:sequence>
|
||||
<!-- BDISK/PROFILE/GPG/KEY -->
|
||||
<xs:element name="key" minOccurs="0" maxOccurs="unbounded">
|
||||
<xs:complexType>
|
||||
<xs:all>
|
||||
<!-- BDISK/PROFILE/GPG/KEY/NAME -->
|
||||
<xs:element name="name" type="xs:normalizedString" maxOccurs="1"
|
||||
minOccurs="1"/>
|
||||
<!-- END BDISK/PROFILE/GPG/KEY/NAME -->
|
||||
<!-- BDISK/PROFILE/GPG/KEY/EMAIL -->
|
||||
<xs:element name="email" type="xs:normalizedString" maxOccurs="1"
|
||||
minOccurs="1"/>
|
||||
<!-- END BDISK/PROFILE/GPG/KEY/EMAIL -->
|
||||
<!-- BDISK/PROFILE/GPG/KEY/COMMENT -->
|
||||
<xs:element name="comment" type="xs:string" maxOccurs="1"
|
||||
minOccurs="0"/>
|
||||
<!-- END BDISK/PROFILE/GPG/KEY/COMMENT -->
|
||||
</xs:all>
|
||||
<xs:attribute name="algo">
|
||||
<xs:simpleType>
|
||||
<xs:restriction base="xs:string">
|
||||
<xs:enumeration value="rsa"/>
|
||||
<xs:enumeration value="dsa"/>
|
||||
</xs:restriction>
|
||||
</xs:simpleType>
|
||||
</xs:attribute>
|
||||
<!-- We COULD constrain this further, but it's conditional upon the algo type. So we'll do that in BDisk itself. -->
|
||||
<!-- But it may be possible? https://stackoverflow.com/a/39045446/733214 -->
|
||||
<xs:attribute name="keysize" type="xs:positiveInteger"/>
|
||||
<!-- XSD doesn't have a datatype for Epoch vs. 0 (for no expire). -->
|
||||
<xs:attribute name="expire">
|
||||
<xs:simpleType>
|
||||
<!--This is xs:integer instead of xs:positiveInteger because 0 will fail validation then. -->
|
||||
<xs:restriction base="xs:integer">
|
||||
<xs:pattern value="(0|[0-9]{10})"/>
|
||||
</xs:restriction>
|
||||
</xs:simpleType>
|
||||
</xs:attribute>
|
||||
</xs:complexType>
|
||||
</xs:element>
|
||||
<!-- END BDISK/PROFILE/GPG/KEY -->
|
||||
</xs:sequence>
|
||||
<xs:attribute name="keyid" type="t_gpg_keyid"/>
|
||||
<xs:attribute name="publish" type="xs:boolean"/>
|
||||
<xs:attribute name="prompt_passphrase" type="xs:boolean"/>
|
||||
<xs:attribute name="gnupghome">
|
||||
<xs:simpleType>
|
||||
<xs:restriction base="xs:string">
|
||||
<xs:pattern value="(.+)/([^/]+)"/>
|
||||
<xs:pattern
|
||||
value="((.+)/([^/]+))?\{variable%[A-Za-z0-9_]\}((.+)/([^/]+))?"/>
|
||||
<xs:pattern
|
||||
value="((.+)/([^/]+))?\{xpath%[A-Za-z0-9_\(\)\.\*\-/]+\}((.+)/([^/]+))?"/>
|
||||
<xs:pattern value="(none|)"/>
|
||||
<xs:pattern value="(auto|default)"/>
|
||||
</xs:restriction>
|
||||
</xs:simpleType>
|
||||
</xs:attribute>
|
||||
</xs:complexType>
|
||||
</xs:element>
|
||||
<!-- END BDISK/PROFILE/GPG -->
|
||||
<!-- BDISK/PROFILE/PKI -->
|
||||
<xs:element name="pki" maxOccurs="1" minOccurs="1"/>
|
||||
<xs:element name="pki" maxOccurs="1" minOccurs="0">
|
||||
<xs:complexType>
|
||||
<xs:sequence>
|
||||
<!-- BDISK/PROFILE/PKI/CA -->
|
||||
<xs:element name="ca" maxOccurs="1" minOccurs="1">
|
||||
<xs:complexType>
|
||||
<xs:all>
|
||||
<!-- BDISK/PROFILE/PKI/CA/CERT -->
|
||||
<xs:element name="cert" maxOccurs="1" minOccurs="1"
|
||||
type="t_pki_cert"/>
|
||||
<!-- END BDISK/PROFILE/PKI/CA/CERT -->
|
||||
<!-- BDISK/PROFILE/PKI/CA/CSR -->
|
||||
<xs:element name="csr" maxOccurs="1" minOccurs="0" type="t_path"/>
|
||||
<!-- END BDISK/PROFILE/PKI/CA/CSR -->
|
||||
<!-- BDISK/PROFILE/PKI/CA/INDEX -->
|
||||
<xs:element name="index" maxOccurs="1" minOccurs="0" type="t_path"/>
|
||||
<!-- END BDISK/PROFILE/PKI/CA/INDEX -->
|
||||
<!-- BDISK/PROFILE/PKI/CA/SERIAL -->
|
||||
<xs:element name="serial" maxOccurs="1" minOccurs="0"
|
||||
type="t_path"/>
|
||||
<!-- END BDISK/PROFILE/PKI/CA/SERIAL -->
|
||||
<!-- BDISK/PROFILE/PKI/CA/KEY -->
|
||||
<xs:element name="key" minOccurs="1" maxOccurs="1"
|
||||
type="t_pki_key"/>
|
||||
<!-- END BDISK/PROFILE/PKI/CA/CSR -->
|
||||
<!-- BDISK/PROFILE/PKI/CA/SUBJECT -->
|
||||
<xs:element name="subject" maxOccurs="1" minOccurs="0"
|
||||
type="t_pki_subject"/>
|
||||
<!-- END BDISK/PROFILE/PKI/CA/SUBJECT -->
|
||||
</xs:all>
|
||||
</xs:complexType>
|
||||
</xs:element>
|
||||
<!-- END BDISK/PROFILE/PKI/CA -->
|
||||
<!-- BDISK/PROFILE/PKI/CLIENT -->
|
||||
<xs:element name="client" maxOccurs="1" minOccurs="1">
|
||||
<xs:complexType>
|
||||
<xs:all>
|
||||
<!-- BDISK/PROFILE/PKI/CLIENT/CERT -->
|
||||
<xs:element name="cert" maxOccurs="1" minOccurs="1"
|
||||
type="t_pki_cert"/>
|
||||
<!-- END BDISK/PROFILE/PKI/CLIENT/CERT -->
|
||||
<!-- BDISK/PROFILE/PKI/CLIENT/CSR -->
|
||||
<xs:element name="csr" maxOccurs="1" minOccurs="0" type="t_path"/>
|
||||
<!-- END BDISK/PROFILE/PKI/CLIENT/CSR -->
|
||||
<!-- BDISK/PROFILE/PKI/CLIENT/KEY -->
|
||||
<xs:element name="key" minOccurs="1" maxOccurs="1"
|
||||
type="t_pki_key"/>
|
||||
<!-- END BDISK/PROFILE/PKI/CLIENT/CSR -->
|
||||
<!-- BDISK/PROFILE/PKI/CLIENT/SUBJECT -->
|
||||
<xs:element name="subject" maxOccurs="1" minOccurs="0"
|
||||
type="t_pki_subject"/>
|
||||
<!-- END BDISK/PROFILE/PKI/CLIENT/SUBJECT -->
|
||||
</xs:all>
|
||||
</xs:complexType>
|
||||
</xs:element>
|
||||
<!-- END BDISK/PROFILE/PKI/CLIENT -->
|
||||
</xs:sequence>
|
||||
<xs:attribute name="overwrite" type="xs:boolean"/>
|
||||
</xs:complexType>
|
||||
</xs:element>
|
||||
<!-- END BDISK/PROFILE/PKI -->
|
||||
<!-- BDISK/PROFILE/SYNC -->
|
||||
<xs:element name="sync" maxOccurs="1" minOccurs="1"/>
|
||||
<xs:element name="sync" maxOccurs="1" minOccurs="1">
|
||||
<xs:complexType>
|
||||
<xs:all>
|
||||
<!-- BDISK/PROFILE/SYNC/IPXE -->
|
||||
<xs:element name="ipxe">
|
||||
<xs:complexType>
|
||||
<xs:simpleContent>
|
||||
<xs:extension base="t_path">
|
||||
<xs:attribute name="enabled" type="xs:boolean"/>
|
||||
</xs:extension>
|
||||
</xs:simpleContent>
|
||||
</xs:complexType>
|
||||
</xs:element>
|
||||
<!-- END BDISK/PROFILE/SYNC/IPXE -->
|
||||
<!-- BDISK/PROFILE/SYNC/TFTP -->
|
||||
<xs:element name="tftp">
|
||||
<xs:complexType>
|
||||
<xs:simpleContent>
|
||||
<xs:extension base="t_path">
|
||||
<xs:attribute name="enabled" type="xs:boolean"/>
|
||||
</xs:extension>
|
||||
</xs:simpleContent>
|
||||
</xs:complexType>
|
||||
</xs:element>
|
||||
<!-- END BDISK/PROFILE/SYNC/TFTP -->
|
||||
<!-- BDISK/PROFILE/SYNC/ISO -->
|
||||
<xs:element name="iso">
|
||||
<xs:complexType>
|
||||
<xs:simpleContent>
|
||||
<xs:extension base="t_path">
|
||||
<xs:attribute name="enabled" type="xs:boolean"/>
|
||||
</xs:extension>
|
||||
</xs:simpleContent>
|
||||
</xs:complexType>
|
||||
</xs:element>
|
||||
<!-- END BDISK/PROFILE/SYNC/ISO -->
|
||||
<!-- BDISK/PROFILE/SYNC/GPG -->
|
||||
<xs:element name="gpg">
|
||||
<xs:complexType>
|
||||
<xs:simpleContent>
|
||||
<xs:extension base="t_path">
|
||||
<xs:attribute name="enabled" type="xs:boolean"/>
|
||||
<xs:attribute name="format">
|
||||
<xs:simpleType>
|
||||
<xs:restriction base="xs:string">
|
||||
<xs:enumeration value="asc"/>
|
||||
<xs:enumeration value="bin"/>
|
||||
</xs:restriction>
|
||||
</xs:simpleType>
|
||||
</xs:attribute>
|
||||
</xs:extension>
|
||||
</xs:simpleContent>
|
||||
</xs:complexType>
|
||||
</xs:element>
|
||||
<!-- END BDISK/PROFILE/SYNC/GPG -->
|
||||
<!-- BDISK/PROFILE/SYNC/RSYNC -->
|
||||
<xs:element name="rsync">
|
||||
<xs:complexType>
|
||||
<xs:sequence>
|
||||
<!-- BDISK/PROFILE/SYNC/RSYNC/USER -->
|
||||
<xs:element name="user" type="t_username"/>
|
||||
<!-- END BDISK/PROFILE/SYNC/RSYNC/USER -->
|
||||
<!-- BDISK/PROFILE/SYNC/RSYNC/HOST -->
|
||||
<xs:element name="host" type="t_net_loc"/>
|
||||
<!-- END BDISK/PROFILE/SYNC/RSYNC/HOST -->
|
||||
<!-- BDISK/PROFILE/SYNC/RSYNC/PORT -->
|
||||
<xs:element name="port">
|
||||
<xs:simpleType>
|
||||
<xs:restriction base="xs:positiveInteger">
|
||||
<xs:minInclusive value="1"/>
|
||||
<xs:maxInclusive value="65535"/>
|
||||
</xs:restriction>
|
||||
</xs:simpleType>
|
||||
</xs:element>
|
||||
<!-- END BDISK/PROFILE/SYNC/RSYNC/PORT -->
|
||||
<xs:choice>
|
||||
<!-- BDISK/PROFILE/SYNC/RSYNC/PUBKEY -->
|
||||
<xs:element name="pubkey" type="t_path"/>
|
||||
<!-- END BDISK/PROFILE/SYNC/RSYNC/PUBKEY -->
|
||||
<!-- BDISK/PROFILE/SYNC/RSYNC/PUBKEY -->
|
||||
<xs:element name="password"/>
|
||||
<!-- END BDISK/PROFILE/SYNC/RSYNC/PUBKEY -->
|
||||
</xs:choice>
|
||||
</xs:sequence>
|
||||
<xs:attribute name="enabled" type="xs:boolean"/>
|
||||
</xs:complexType>
|
||||
</xs:element>
|
||||
<!-- END BDISK/PROFILE/SYNC/IPXE -->
|
||||
</xs:all>
|
||||
</xs:complexType>
|
||||
</xs:element>
|
||||
<!-- END BDISK/PROFILE/SYNC -->
|
||||
</xs:all>
|
||||
<xs:attribute name="id" type="xs:positiveInteger"/>
|
||||
<xs:attribute name="name" type="xs:string"/>
|
||||
<xs:attribute name="uuid">
|
||||
<xs:simpleType>
|
||||
<xs:restriction base="xs:string">
|
||||
<xs:pattern
|
||||
value="[0-9a-f]{8}\-[0-9a-f]{4}\-4[0-9a-f]{3}\-[89ab][0-9a-f]{3}\-[0-9a-f]{12}"/>
|
||||
</xs:restriction>
|
||||
</xs:simpleType>
|
||||
</xs:attribute>
|
||||
</xs:complexType>
|
||||
</xs:element>
|
||||
<!-- END BDISK/PROFILE -->
|
||||
|
@ -4,7 +4,7 @@
|
||||
# Go figure.
|
||||
|
||||
import confparse
|
||||
import crypt
|
||||
import datetime
|
||||
import getpass
|
||||
import os
|
||||
import utils
|
||||
@ -134,7 +134,12 @@ class ConfGenerator(object):
|
||||
self.cfg = c.xml
|
||||
self.append = True
|
||||
else:
|
||||
self.cfg = lxml.etree.Element('bdisk')
|
||||
_ns = {None: 'http://bdisk.square-r00t.net/',
|
||||
'xsi': 'http://www.w3.org/2001/XMLSchema-instance'}
|
||||
_xsi = {
|
||||
'{http://www.w3.org/2001/XMLSchema-instance}schemaLocation':
|
||||
'http://bdisk.square-r00t.net bdisk.xsd'}
|
||||
self.cfg = lxml.etree.Element('bdisk', nsmap = _ns, attrib = _xsi)
|
||||
self.append = False
|
||||
self.profile = lxml.etree.Element('profile')
|
||||
self.cfg.append(self.profile)
|
||||
@ -155,6 +160,13 @@ class ConfGenerator(object):
|
||||
self.get_pki()
|
||||
self.get_gpg()
|
||||
self.get_sync()
|
||||
# TODO: make this more specific (script? gui? web? etc.)
|
||||
# and append comment to bdisk element
|
||||
_comment = lxml.etree.Comment(
|
||||
'Generated {0} by BDisk configuration generator'.format(
|
||||
str(datetime.datetime.now())
|
||||
)
|
||||
)
|
||||
except KeyboardInterrupt:
|
||||
exit('\n\nCaught KeyboardInterrupt; quitting...')
|
||||
return()
|
||||
@ -472,7 +484,7 @@ class ConfGenerator(object):
|
||||
print('Invalid selection. Starting over.')
|
||||
continue
|
||||
chksum.attrib['hash_algo'] = checksum_type
|
||||
chksum.attrib['explicit'] = "no"
|
||||
chksum.attrib['explicit'] = "false"
|
||||
chksum.text = checksum['full_url']
|
||||
else:
|
||||
# Maybe it's a digest string.
|
||||
@ -505,7 +517,7 @@ class ConfGenerator(object):
|
||||
continue
|
||||
else:
|
||||
checksum_type = checksum_type[0]
|
||||
chksum.attrib['explicit'] = "yes"
|
||||
chksum.attrib['explicit'] = "true"
|
||||
chksum.text = checksum
|
||||
chksum.attrib['hash_algo'] = checksum_type
|
||||
print('\n++ SOURCES || {0} || GPG ++'.format(arch.upper()))
|
||||
@ -597,7 +609,7 @@ class ConfGenerator(object):
|
||||
usage = (
|
||||
'{0} for yes, {1} for no...\n'))
|
||||
if _chk_optimizations:
|
||||
build.attrib['its_full_of_stars'] = 'yes'
|
||||
build.attrib['its_full_of_stars'] = 'true'
|
||||
print('\n++ BUILD || PATHS ++')
|
||||
# Thankfully, we can simplify a lot of this.
|
||||
_dir_strings = {'base': ('the base directory (used for files that are '
|
||||
@ -678,9 +690,9 @@ class ConfGenerator(object):
|
||||
self.profile.append(iso)
|
||||
# We have more than one arch, so we need to ask how they want to handle
|
||||
# it.
|
||||
_ma_strings = {'yes': ('a multi-arch ISO (both architectures on one '
|
||||
_ma_strings = {'true': ('a multi-arch ISO (both architectures on one '
|
||||
'ISO)'),
|
||||
'no': ('separate image files for '
|
||||
'false': ('separate image files for '
|
||||
'{0}').format(' and '.join(_arches))}
|
||||
for a in _arches:
|
||||
_ma_strings[a] = 'only build an image file for {0}'.format(a)
|
||||
@ -712,7 +724,7 @@ class ConfGenerator(object):
|
||||
'option to configure it a bit later).\nWould you like to sign '
|
||||
'the ISO/USB image files with GPG?\n'), usage = (
|
||||
'{0} for yes, {1} for no...\n'))
|
||||
_gpg_sign = ('yes' if _gpg_input else 'no')
|
||||
_gpg_sign = ('true' if _gpg_input else 'false')
|
||||
iso.attrib['sign'] = _gpg_sign
|
||||
self.profile.append(iso)
|
||||
return()
|
||||
@ -727,21 +739,21 @@ class ConfGenerator(object):
|
||||
'see the manual for more information). Would you like to '
|
||||
'build iPXE support?\n'), usage = (
|
||||
'{0} for yes, {1} for no...\n'))
|
||||
_ipxe = ('yes' if _ipxe else 'no')
|
||||
if _ipxe == 'yes':
|
||||
_ipxe = ('true' if _ipxe else 'true')
|
||||
if _ipxe == 'true':
|
||||
print('\n++ iPXE || MINI-ISO ++')
|
||||
_iso = prompt.confirm_or_no(prompt = (
|
||||
'\nWould you like to build a "mini-ISO" (see the manual) for '
|
||||
'bootstrapping iPXE booting from USB or optical media?\n'),
|
||||
usage = ('{0} for yes, {1} for no...\n'))
|
||||
ipxe.attrib['iso'] = ('yes' if _iso else 'no')
|
||||
ipxe.attrib['iso'] = ('true' if _iso else 'false')
|
||||
print('\n++ iPXE || SIGNING ++')
|
||||
_sign = prompt.confirm_or_no(prompt = (
|
||||
'\nBDisk can sign the mini-ISO and other relevant files for '
|
||||
'iPXE builds using GPG. Would you like to sign the iPXE build '
|
||||
'distributables? (You\'ll have the chance to configure GPG '
|
||||
'later).\n'), usage = ('{0} for yes, {1} for no...\n'))
|
||||
ipxe.attrib['sign'] = ('yes' if _sign else 'no')
|
||||
ipxe.attrib['sign'] = ('true' if _sign else 'false')
|
||||
_uri = None
|
||||
while not _uri:
|
||||
print('\n++ iPXE || URL ++')
|
||||
@ -756,7 +768,7 @@ class ConfGenerator(object):
|
||||
else:
|
||||
uri = lxml.etree.SubElement(ipxe, 'uri')
|
||||
uri.text = _uri
|
||||
if _ipxe == 'yes':
|
||||
if _ipxe == 'true':
|
||||
self.profile.append(ipxe)
|
||||
return()
|
||||
|
||||
@ -782,7 +794,7 @@ class ConfGenerator(object):
|
||||
'wish to keep persistent keys and certs), you should '
|
||||
'DEFINITELY answer no here.\n'),
|
||||
usage = ('{0} for yes, {1} for no...\n'))
|
||||
pki.attrib['overwrite'] = ('yes' if _overwrite else 'no')
|
||||
pki.attrib['overwrite'] = ('true' if _overwrite else 'false')
|
||||
for x in ('ca', 'client'):
|
||||
print('\n++ SSL/TLS PKI || {0} ++'.format(x.upper()))
|
||||
_x = None
|
||||
@ -806,7 +818,7 @@ class ConfGenerator(object):
|
||||
for x in _xpaths:
|
||||
_x = self.profile.xpath(x)
|
||||
for a in _x:
|
||||
if a == 'yes':
|
||||
if a == 'true':
|
||||
_sigchk = True
|
||||
break
|
||||
if _sigchk:
|
||||
@ -850,7 +862,7 @@ class ConfGenerator(object):
|
||||
'\nWould you like to push the key to the SKS keyserver pool '
|
||||
'(making it much easier for end-users to look it up)?\n'),
|
||||
usage = ('{0} for yes, {1} for no...\n'))
|
||||
gpg.attrib['publish'] = ('yes' if _gpgpublish else 'no')
|
||||
gpg.attrib['publish'] = ('true' if _gpgpublish else 'false')
|
||||
print('\n++ GPG || PASSWORD HANDLING ++')
|
||||
_gpgpass_prompt = prompt.confirm_or_no(prompt = (
|
||||
'\nWould you like BDisk to prompt you for a passphrase? If not, '
|
||||
@ -858,7 +870,8 @@ class ConfGenerator(object):
|
||||
'the configuration (HIGHLY unrecommended) or use a blank '
|
||||
'passphrase (also HIGHLY unrecommended).\n'),
|
||||
usage = ('{0} for yes, {1} for no...\n'))
|
||||
gpg.attrib['prompt_passphrase'] = ('yes' if _gpgpass_prompt else 'no')
|
||||
gpg.attrib['prompt_passphrase'] = ('true' if _gpgpass_prompt else
|
||||
'false')
|
||||
_pass = None
|
||||
if not _gpgpass_prompt:
|
||||
while not _pass:
|
||||
@ -923,7 +936,7 @@ class ConfGenerator(object):
|
||||
'\nWould you like to sync {0}?\n'.format(_syncs[s])),
|
||||
usage = ('{0} for yes, {1} for no...\n'))
|
||||
elem = lxml.etree.SubElement(sync, s)
|
||||
elem.attrib['enabled'] = ('yes' if _item_sync_chk else 'no')
|
||||
elem.attrib['enabled'] = ('true' if _item_sync_chk else 'false')
|
||||
if not _item_sync_chk:
|
||||
continue
|
||||
if s == 'gpg':
|
||||
|
@ -168,7 +168,7 @@ class Conf(object):
|
||||
## PROFILE/BUILD(/PATHS)
|
||||
self.cfg['build'] = {'paths': {}}
|
||||
build = self.profile.xpath('./build')[0]
|
||||
_optimize = build.get('its_full_of_stars', 'no')
|
||||
_optimize = build.get('its_full_of_stars', 'false')
|
||||
self.cfg['build']['optimize'] = transform.xml2py(_optimize)
|
||||
for path in build.xpath('./paths/*'):
|
||||
self.cfg['build']['paths'][path.tag] = path.text
|
||||
@ -185,7 +185,7 @@ class Conf(object):
|
||||
# We enable all features by default.
|
||||
elem = self.profile.xpath('./{0}'.format(x))[0]
|
||||
for a in self.cfg[x]:
|
||||
self.cfg[x][a] = transform.xml2py(elem.get(a, 'yes'))
|
||||
self.cfg[x][a] = transform.xml2py(elem.get(a, 'true'))
|
||||
if x == 'ipxe':
|
||||
self.cfg[x]['uri'] = elem.xpath('./uri/text()')[0]
|
||||
return()
|
||||
|
@ -15,6 +15,7 @@ import uuid
|
||||
import validators
|
||||
import zlib
|
||||
import lxml.etree
|
||||
import lxml.objectify
|
||||
from bs4 import BeautifulSoup
|
||||
from collections import OrderedDict
|
||||
from dns import resolver
|
||||
@ -446,12 +447,12 @@ class transform(object):
|
||||
def py2xml(self, value, attrib = True):
|
||||
if value in (False, ''):
|
||||
if attrib:
|
||||
return("no")
|
||||
return("false")
|
||||
else:
|
||||
return(None)
|
||||
elif isinstance(value, bool):
|
||||
# We handle the False case above.
|
||||
return("yes")
|
||||
return("true")
|
||||
elif isinstance(value, str):
|
||||
return(value)
|
||||
else:
|
||||
@ -469,7 +470,6 @@ class transform(object):
|
||||
text_out = re.sub('[^\w]', '', text_out)
|
||||
return(text_out)
|
||||
|
||||
# noinspection PyDictCreation
|
||||
def url_to_dict(self, orig_url, no_None = False):
|
||||
def _getuserinfo(uinfo_str):
|
||||
if len(uinfo_str) == 0:
|
||||
@ -659,8 +659,8 @@ class transform(object):
|
||||
return(acct)
|
||||
|
||||
def xml2py(self, value, attrib = True):
|
||||
yes = re.compile('^\s*(y(es)?|true|1)\s*$', re.IGNORECASE)
|
||||
no = re.compile('^\s*(no?|false|0)\s*$', re.IGNORECASE)
|
||||
yes = re.compile('^\s*(true|1)\s*$', re.IGNORECASE)
|
||||
no = re.compile('^\s*(false|0)\s*$', re.IGNORECASE)
|
||||
none = re.compile('^\s*(none|)\s*$', re.IGNORECASE)
|
||||
if no.search(value):
|
||||
if attrib:
|
||||
@ -819,12 +819,18 @@ class xml_supplicant(object):
|
||||
# This is retained so we can "refresh" the profile if needed.
|
||||
self.orig_profile = profile
|
||||
try:
|
||||
self.xml = lxml.etree.fromstring(raw)
|
||||
self.orig_xml = lxml.etree.fromstring(raw)
|
||||
# We need to strip the naked namespace for XPath to work.
|
||||
self.xml = copy.deepcopy(self.orig_xml)
|
||||
self.roottree = self.xml.getroottree()
|
||||
self.tree = self.roottree.getroot()
|
||||
self.strip_naked_ns()
|
||||
except lxml.etree.XMLSyntaxError:
|
||||
raise ValueError('The configuration provided does not seem to be '
|
||||
'valid')
|
||||
self.get_profile(profile = profile)
|
||||
self.xml = lxml.etree.fromstring(raw)
|
||||
# This is disabled; we set it above.
|
||||
#self.xml = lxml.etree.fromstring(raw)
|
||||
self.fmt = XPathFmt()
|
||||
self.max_recurse = int(self.profile.xpath(
|
||||
'//meta/max_recurse/text()')[0])
|
||||
@ -969,6 +975,23 @@ class xml_supplicant(object):
|
||||
).format(element.text))
|
||||
return(path)
|
||||
|
||||
def return_naked_ns(self):
|
||||
# It's so stupid I have to do this.
|
||||
return(self.orig_xml.nsmap)
|
||||
|
||||
def strip_naked_ns(self):
|
||||
# I cannot *believe* that LXML doesn't have this built-in, considering
|
||||
# how common naked namespaces are.
|
||||
# https://stackoverflow.com/a/18160164/733214
|
||||
for elem in self.roottree.getiterator():
|
||||
if not hasattr(elem.tag, 'find'):
|
||||
continue
|
||||
i = elem.tag.find('}')
|
||||
if i >= 0:
|
||||
elem.tag = elem.tag[i + 1:]
|
||||
lxml.objectify.deannotate(self.roottree, cleanup_namespaces = True)
|
||||
return()
|
||||
|
||||
def substitute(self, element, recurse_count = 0):
|
||||
if recurse_count >= self.max_recurse:
|
||||
return(element)
|
||||
|
@ -1,286 +1,285 @@
|
||||
<?xml version='1.0' encoding='UTF-8'?>
|
||||
<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>
|
||||
<name>BDisk</name>
|
||||
<uxname>bdisk</uxname>
|
||||
<!-- Just like with previous versions of BDisk, you can reference other values...
|
||||
<bdisk xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://bdisk.square-r00t.net/" xsi:schemaLocation="http://bdisk.square-r00t.net bdisk.xsd">
|
||||
<profile name="default" id="1" uuid="8cdd6bcb-c147-4a63-9779-b5433c510dbc">
|
||||
<meta>
|
||||
<names>
|
||||
<name>BDISK</name>
|
||||
<uxname>bdisk</uxname>
|
||||
<!-- Just like with previous versions of BDisk, you can reference other values...
|
||||
but now with the neat benefits of XPath! Everything you could do in build.ini's and more.
|
||||
See https://www.w3schools.com/xml/xpath_syntax.asp
|
||||
If you need a literal curly brace, double them (e.g. for "{foo}", use "{{foo}}"),
|
||||
UNLESS it's in a <regexes><pattern> as part of the expression. Those are taken as literal strings. -->
|
||||
<pname>{xpath%../name/text()}</pname>
|
||||
</names>
|
||||
<desc>A rescue/restore live environment.</desc>
|
||||
<dev>
|
||||
<author>A. Dev Eloper</author>
|
||||
<email>dev@domain.tld</email>
|
||||
<website>https://domain.tld/~dev</website>
|
||||
</dev>
|
||||
<uri>https://domain.tld/projname</uri>
|
||||
<ver>1.0.0</ver>
|
||||
<!-- This is the VERY FIRST value parsed, and is required. It controls how many levels of {xpath%...} to recurse. -->
|
||||
<!-- If the maximum level is reached, the substitution will evaluate as blank. -->
|
||||
<max_recurse>5</max_recurse>
|
||||
<!-- You need to store regex patterns here and reference them in a special way later, and it's only valid for certain
|
||||
<pname>{xpath%../name/text()}</pname>
|
||||
</names>
|
||||
<desc>A rescue/restore live environment.</desc>
|
||||
<dev>
|
||||
<author>A. Dev Eloper</author>
|
||||
<email>dev@domain.tld</email>
|
||||
<website>https://domain.tld/~dev</website>
|
||||
</dev>
|
||||
<uri>https://domain.tld/projname</uri>
|
||||
<ver>1.0.0</ver>
|
||||
<!-- This is the VERY FIRST value parsed, and is required. It controls how many levels of {xpath%...} to recurse. -->
|
||||
<!-- If the maximum level is reached, the substitution will evaluate as blank. -->
|
||||
<max_recurse>5</max_recurse>
|
||||
<!-- You need to store regex patterns here and reference them in a special way later, and it's only valid for certain
|
||||
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="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>
|
||||
<!-- You can also define variables. NO xpath or regex btags, and they can't be used within other btags! -->
|
||||
<variables>
|
||||
<variable id="bdisk_root">/var/tmp/BDisk</variable>
|
||||
</variables>
|
||||
</meta>
|
||||
<accounts>
|
||||
<!-- Salted/hashed password is "test" -->
|
||||
<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: -->
|
||||
<!-- <username>{xpath%//profile[@name='another_profile']/meta/names/uxname"}</username> -->
|
||||
<comment>{xpath%//meta/dev/author/text()}</comment>
|
||||
<password hashed="no" hash_algo="sha512" 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>
|
||||
</user>
|
||||
</accounts>
|
||||
<sources>
|
||||
<source arch="x86_64">
|
||||
<mirror>http://archlinux.mirror.domain.tld</mirror>
|
||||
<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" keyserver="hkp://pool.sks-keyservers.net" 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>
|
||||
<sig keys="248BF41F9BDD61D41D060AE774EDA3C6B06D0506" keyserver="hkp://pool.sks-keyservers.net" flags="regex,latest">{regex%sig_i686}</sig>
|
||||
</source>
|
||||
</sources>
|
||||
<build its_full_of_stars="yes">
|
||||
<paths>
|
||||
<base>{variable%bdisk_root}/base</base>
|
||||
<cache>{variable%bdisk_root}/cache</cache>
|
||||
<chroot>{variable%bdisk_root}/chroots</chroot>
|
||||
<overlay>{variable%bdisk_root}/overlay</overlay>
|
||||
<templates>{variable%bdisk_root}/templates</templates>
|
||||
<mount>/mnt/{xpath%//meta/names/uxname/text()}</mount>
|
||||
<distros>{variable%bdisk_root}/distros</distros>
|
||||
<dest>{variable%bdisk_root}/results</dest>
|
||||
<iso>{variable%bdisk_root}/iso_overlay</iso>
|
||||
<http>{variable%bdisk_root}/http</http>
|
||||
<tftp>{variable%bdisk_root}/tftp</tftp>
|
||||
<pki>{variable%bdisk_root}/pki</pki>
|
||||
</paths>
|
||||
<basedistro>archlinux</basedistro>
|
||||
</build>
|
||||
<iso sign="yes" multi_arch="yes"/>
|
||||
<ipxe sign="yes" iso="yes">
|
||||
<uri>{xpath%//meta/dev/website/text()}/ipxe</uri>
|
||||
</ipxe>
|
||||
<pki overwrite="no">
|
||||
<!-- http://ipxe.org/crypto -->
|
||||
<ca>
|
||||
<cert hash_algo="sha512">{xpath%../../../build/paths/pki/text()}/ca.crt</cert>
|
||||
<!-- If csr is self-enclosed (<csr />), we'll just generate and use a CSR in-memory.
|
||||
<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="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>
|
||||
<!-- You can also define variables. NO xpath or regex btags, and they can't be used within other btags! -->
|
||||
<variables>
|
||||
<variable id="bdisk_root">/var/tmp/BDisk</variable>
|
||||
</variables>
|
||||
</meta>
|
||||
<accounts>
|
||||
<!-- Salted/hashed password is "test" -->
|
||||
<rootpass hashed="true">$6$7KfIdtHTcXwVrZAC$LZGNeMNz7v5o/cYuA48FAxtZynpIwO5B1CPGXnOW5kCTVpXVt4SypRqfM.AoKkFt/O7MZZ8ySXJmxpELKmdlF1</rootpass>
|
||||
<user sudo="true">
|
||||
<username>{xpath%//meta/names/uxname/text()}</username>
|
||||
<!-- You can also use substitution from different profiles in this same configuration: -->
|
||||
<!-- <username>{xpath%//profile[@name='another_profile']/meta/names/uxname"}</username> -->
|
||||
<comment>{xpath%//meta/dev/author/text()}</comment>
|
||||
<password hashed="false" hash_algo="sha512" salt="auto">testpassword</password>
|
||||
</user>
|
||||
<user sudo="false">
|
||||
<username>testuser</username>
|
||||
<comment>Test User</comment>
|
||||
<password hashed="false" hash_algo="sha512" salt="auto">anothertestpassword</password>
|
||||
</user>
|
||||
</accounts>
|
||||
<sources>
|
||||
<source arch="x86_64">
|
||||
<mirror>http://archlinux.mirror.domain.tld</mirror>
|
||||
<rootpath>/iso/latest</rootpath>
|
||||
<tarball flags="regex,latest">{regex%tarball_x86_64}</tarball>
|
||||
<checksum hash_algo="sha1" explicit="false">sha1sums.txt</checksum>
|
||||
<sig keys="7F2D434B9741E8AC" keyserver="hkp://pool.sks-keyservers.net" 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="true">cf83e1357eefb8bdf1542850d66d8007d620e4050b5715dc83f4a921d36ce9ce47d0d13c5d85f2b0ff8318d2877eec2f63b931bd47417a81a538327af927da3e</checksum>
|
||||
<sig keys="248BF41F9BDD61D41D060AE774EDA3C6B06D0506" keyserver="hkp://pool.sks-keyservers.net" flags="regex,latest">{regex%sig_i686}</sig>
|
||||
</source>
|
||||
</sources>
|
||||
<build its_full_of_stars="true">
|
||||
<paths>
|
||||
<base>{variable%bdisk_root}/base</base>
|
||||
<cache>{variable%bdisk_root}/cache</cache>
|
||||
<chroot>{variable%bdisk_root}/chroots</chroot>
|
||||
<overlay>{variable%bdisk_root}/overlay</overlay>
|
||||
<templates>{variable%bdisk_root}/templates</templates>
|
||||
<mount>/mnt/{xpath%//meta/names/uxname/text()}</mount>
|
||||
<distros>{variable%bdisk_root}/distros</distros>
|
||||
<dest>{variable%bdisk_root}/results</dest>
|
||||
<iso>{variable%bdisk_root}/iso_overlay</iso>
|
||||
<http>{variable%bdisk_root}/http</http>
|
||||
<tftp>{variable%bdisk_root}/tftp</tftp>
|
||||
<pki>{variable%bdisk_root}/pki</pki>
|
||||
</paths>
|
||||
<basedistro>archlinux</basedistro>
|
||||
</build>
|
||||
<iso sign="true" multi_arch="true"/>
|
||||
<ipxe sign="true" iso="true">
|
||||
<uri>{xpath%//meta/dev/website/text()}/ipxe</uri>
|
||||
</ipxe>
|
||||
<pki overwrite="no">
|
||||
<!-- http://ipxe.org/crypto -->
|
||||
<ca>
|
||||
<cert hash_algo="sha512">{xpath%../../../build/paths/pki/text()}/ca.crt</cert>
|
||||
<!-- If csr is self-enclosed (<csr />), we'll just generate and use a CSR in-memory.
|
||||
Assuming we need to generate a certificate, anyways.
|
||||
If you want to write it out to disk (for debugging, etc.) OR use one already generated,
|
||||
then provide a path.
|
||||
e.g.:
|
||||
<csr>{xpath%build/paths/ssl/text()}/ca.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. -->
|
||||
<!-- Both of these are entirely optional if you aren't using an existing PKI. -->
|
||||
<index>{xpath%../../../build/paths/pki/text()}/index.txt</index>
|
||||
<serial>{xpath%../../../build/paths/pki/text()}/serial</serial>
|
||||
<!-- If you specify a cipher, the key will be encrypted to the passphrase provided by the passphrase attribute.
|
||||
<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. -->
|
||||
<!-- Both of these are entirely optional if you aren't using an existing PKI. -->
|
||||
<index>{xpath%../../../build/paths/pki/text()}/index.txt</index>
|
||||
<serial>{xpath%../../../build/paths/pki/text()}/serial</serial>
|
||||
<!-- If you specify a cipher, the key will be encrypted to the passphrase provided by the passphrase attribute.
|
||||
If the key is encrypted (either a pre-existing or a created one) but passphrase is not provided, you will
|
||||
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>
|
||||
<subject>
|
||||
<commonName>domain.tld</commonName>
|
||||
<countryName>XX</countryName>
|
||||
<localityName>Some City</localityName>
|
||||
<stateOrProvinceName>Some State</stateOrProvinceName>
|
||||
<organization>Some Org, Inc.</organization>
|
||||
<organizationalUnitName>Department Name</organizationalUnitName>
|
||||
<emailAddress>{xpath%../../../../meta/dev/email/text()}</emailAddress>
|
||||
</subject>
|
||||
</ca>
|
||||
<client>
|
||||
<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>
|
||||
<subject>
|
||||
<commonName>some client name</commonName>
|
||||
<countryName>XX</countryName>
|
||||
<localityName>Some City</localityName>
|
||||
<stateOrProvinceName>Some State</stateOrProvinceName>
|
||||
<organization>Some Org, Inc.</organization>
|
||||
<organizationalUnitName>Department Name</organizationalUnitName>
|
||||
<emailAddress>{xpath%../../../../meta/dev/email/text()}</emailAddress>
|
||||
</subject>
|
||||
</client>
|
||||
</pki>
|
||||
<!-- If prompt_passphrase is "no" and passphrase attribute is not given for a gpg element, we will try to use a
|
||||
<key cipher="none" passphrase="none" keysize="4096">{xpath%../../../build/paths/pki/text()}/ca.key</key>
|
||||
<subject>
|
||||
<commonName>domain.tld</commonName>
|
||||
<countryName>XX</countryName>
|
||||
<localityName>Some City</localityName>
|
||||
<stateOrProvinceName>Some State</stateOrProvinceName>
|
||||
<organization>Some Org, Inc.</organization>
|
||||
<organizationalUnitName>Department Name</organizationalUnitName>
|
||||
<emailAddress>{xpath%../../../../meta/dev/email/text()}</emailAddress>
|
||||
</subject>
|
||||
</ca>
|
||||
<client>
|
||||
<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>
|
||||
<subject>
|
||||
<commonName>some client name</commonName>
|
||||
<countryName>XX</countryName>
|
||||
<localityName>Some City</localityName>
|
||||
<stateOrProvinceName>Some State</stateOrProvinceName>
|
||||
<organization>Some Org, Inc.</organization>
|
||||
<organizationalUnitName>Department Name</organizationalUnitName>
|
||||
<emailAddress>{xpath%../../../../meta/dev/email/text()}</emailAddress>
|
||||
</subject>
|
||||
</client>
|
||||
</pki>
|
||||
<!-- If prompt_passphrase is "no" and passphrase attribute is not given for a gpg element, we will try to use a
|
||||
blank passphrase for all operations. -->
|
||||
<gpg keyid="none" gnupghome="none" publish="no" prompt_passphrase="no">
|
||||
<!-- The below is only used if we are generating a key (i.e. keyid="none"). -->
|
||||
<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>
|
||||
</key>
|
||||
</gpg>
|
||||
<sync>
|
||||
<!-- ipxe includes the http directory. or should, anyways. -->
|
||||
<ipxe enabled="yes">/srv/http/{xpath%../../meta/names/uxname/text()}</ipxe>
|
||||
<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>
|
||||
<rsync enabled="yes">
|
||||
<user>root</user>
|
||||
<host>mirror.domain.tld</host>
|
||||
<port>22</port>
|
||||
<pubkey>~/.ssh/id_ed25519</pubkey>
|
||||
</rsync>
|
||||
</sync>
|
||||
</profile>
|
||||
<profile name="alternate" id="2" uuid="2ed07c19-2071-4d66-8569-da40475ba716">
|
||||
<meta>
|
||||
<names>
|
||||
<name>AnotherCD</name>
|
||||
<uxname>bdisk_alt</uxname>
|
||||
<pname>{xpath%../name/text()}</pname>
|
||||
</names>
|
||||
<desc>Another rescue/restore live environment.</desc>
|
||||
<dev>
|
||||
<author>Another Dev Eloper</author>
|
||||
<!-- You can reference other profiles within the same configuration. -->
|
||||
<email>{xpath%//profile[@name="default"]/meta/dev/email/text()}</email>
|
||||
<website>{xpath%//profile[@name="default"]/meta/dev/website/text()}</website>
|
||||
</dev>
|
||||
<uri>https://domain.tld/projname</uri>
|
||||
<ver>0.0.1</ver>
|
||||
<max_recurse>5</max_recurse>
|
||||
<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="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>
|
||||
<variables>
|
||||
<variable id="bdisk_root">/var/tmp/BDisk</variable>
|
||||
</variables>
|
||||
</meta>
|
||||
<accounts>
|
||||
<rootpass hashed="no">atotallyinsecurepassword</rootpass>
|
||||
<user sudo="no">
|
||||
<username>testuser</username>
|
||||
<comment>Test User</comment>
|
||||
<password hashed="no" hash_algo="sha512" salt="auto">atestpassword</password>
|
||||
</user>
|
||||
</accounts>
|
||||
<sources>
|
||||
<source arch="x86_64">
|
||||
<mirror>http://archlinux.mirror.domain.tld</mirror>
|
||||
<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" keyserver="hkp://pool.sks-keyservers.net" 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>
|
||||
<sig keys="248BF41F9BDD61D41D060AE774EDA3C6B06D0506" keyserver="hkp://pool.sks-keyservers.net" flags="regex,latest">{regex%sig_i686}</sig>
|
||||
</source>
|
||||
</sources>
|
||||
<build its_full_of_stars="yes">
|
||||
<paths>
|
||||
<base>{variable%bdisk_root}/base</base>
|
||||
<cache>{variable%bdisk_root}/cache</cache>
|
||||
<chroot>{variable%bdisk_root}/chroots</chroot>
|
||||
<overlay>{variable%bdisk_root}/overlay</overlay>
|
||||
<templates>{variable%bdisk_root}/templates</templates>
|
||||
<mount>/mnt/{xpath%//meta/names/uxname/text()}</mount>
|
||||
<distros>{variable%bdisk_root}/distros</distros>
|
||||
<dest>{variable%bdisk_root}/results</dest>
|
||||
<iso>{variable%bdisk_root}/iso_overlay</iso>
|
||||
<http>{variable%bdisk_root}/http</http>
|
||||
<tftp>{variable%bdisk_root}/tftp</tftp>
|
||||
<pki>{variable%bdisk_root}/pki</pki>
|
||||
</paths>
|
||||
<basedistro>archlinux</basedistro>
|
||||
</build>
|
||||
<iso sign="yes" multi_arch="yes"/>
|
||||
<ipxe sign="yes" iso="yes">
|
||||
<uri>{xpath%//meta/dev/website/text()}/ipxe</uri>
|
||||
</ipxe>
|
||||
<pki overwrite="no">
|
||||
<ca>
|
||||
<cert hash_algo="sha512">{xpath%../../../build/paths/pki/text()}/ca.crt</cert>
|
||||
<csr/>
|
||||
<index>{xpath%../../../build/paths/pki/text()}/index.txt</index>
|
||||
<serial>{xpath%../../../build/paths/pki/text()}/serial</serial>
|
||||
<key cipher="none" passphrase="none" keysize="4096">{xpath%../../../build/paths/pki/text()}/ca.key</key>
|
||||
<subject>
|
||||
<commonName>domain.tld</commonName>
|
||||
<countryName>XX</countryName>
|
||||
<localityName>Some City</localityName>
|
||||
<stateOrProvinceName>Some State</stateOrProvinceName>
|
||||
<organization>Some Org, Inc.</organization>
|
||||
<organizationalUnitName>Department Name</organizationalUnitName>
|
||||
<emailAddress>{xpath%../../../../meta/dev/email/text()}</emailAddress>
|
||||
</subject>
|
||||
</ca>
|
||||
<client>
|
||||
<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>
|
||||
<subject>
|
||||
<commonName>some client name</commonName>
|
||||
<countryName>XX</countryName>
|
||||
<localityName>Some City</localityName>
|
||||
<stateOrProvinceName>Some State</stateOrProvinceName>
|
||||
<organization>Some Org, Inc.</organization>
|
||||
<organizationalUnitName>Department Name</organizationalUnitName>
|
||||
<emailAddress>{xpath%../../../../meta/dev/email/text()}</emailAddress>
|
||||
</subject>
|
||||
</client>
|
||||
</pki>
|
||||
<gpg keyid="none" gnupghome="none" publish="no" prompt_passphrase="no">
|
||||
<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>
|
||||
</key>
|
||||
</gpg>
|
||||
<sync>
|
||||
<ipxe enabled="yes">/srv/http/{xpath%../../meta/names/uxname/text()}</ipxe>
|
||||
<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>
|
||||
<rsync enabled="yes">
|
||||
<user>root</user>
|
||||
<host>mirror.domain.tld</host>
|
||||
<port>22</port>
|
||||
<pubkey>~/.ssh/id_ed25519</pubkey>
|
||||
</rsync>
|
||||
</sync>
|
||||
</profile>
|
||||
<gpg keyid="none" gnupghome="none" publish="no" prompt_passphrase="no">
|
||||
<!-- The below is only used if we are generating a key (i.e. keyid="none"). -->
|
||||
<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>
|
||||
</key>
|
||||
</gpg>
|
||||
<sync>
|
||||
<!-- ipxe includes the http directory. or should, anyways. -->
|
||||
<ipxe enabled="true">/srv/http/{xpath%../../meta/names/uxname/text()}</ipxe>
|
||||
<tftp enabled="true">/tftproot/{xpath%../../meta/names/uxname/text()}</tftp>
|
||||
<iso enabled="true">/srv/http/isos/{xpath%../../meta/names/uxname/text()}</iso>
|
||||
<gpg enabled="true" format="asc">/srv/http/{xpath%../../meta/names/uxname/text()}/pubkey.asc</gpg>
|
||||
<rsync enabled="true">
|
||||
<user>root</user>
|
||||
<host>mirror.domain.tld</host>
|
||||
<port>22</port>
|
||||
<pubkey>~/.ssh/id_ed25519</pubkey>
|
||||
</rsync>
|
||||
</sync>
|
||||
</profile>
|
||||
<profile name="alternate" id="2" uuid="2ed07c19-2071-4d66-8569-da40475ba716">
|
||||
<meta>
|
||||
<names>
|
||||
<name>AnotherCD</name>
|
||||
<uxname>bdisk_alt</uxname>
|
||||
<pname>{xpath%../name/text()}</pname>
|
||||
</names>
|
||||
<desc>Another rescue/restore live environment.</desc>
|
||||
<dev>
|
||||
<author>Another Dev Eloper</author><!-- You can reference other profiles within the same configuration. -->
|
||||
<email>{xpath%//profile[@name="default"]/meta/dev/email/text()}</email>
|
||||
<website>{xpath%//profile[@name="default"]/meta/dev/website/text()}</website>
|
||||
</dev>
|
||||
<uri>https://domain.tld/projname</uri>
|
||||
<ver>0.0.1</ver>
|
||||
<max_recurse>5</max_recurse>
|
||||
<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="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>
|
||||
<variables>
|
||||
<variable id="bdisk_root">/var/tmp/BDisk</variable>
|
||||
</variables>
|
||||
</meta>
|
||||
<accounts>
|
||||
<rootpass hashed="false">atotallyinsecurepassword</rootpass>
|
||||
<user sudo="false">
|
||||
<username>testuser</username>
|
||||
<comment>Test User</comment>
|
||||
<password hashed="false" hash_algo="sha512" salt="auto">atestpassword</password>
|
||||
</user>
|
||||
</accounts>
|
||||
<sources>
|
||||
<source arch="x86_64">
|
||||
<mirror>http://archlinux.mirror.domain.tld</mirror>
|
||||
<rootpath>/iso/latest</rootpath>
|
||||
<tarball flags="regex,latest">{regex%tarball_x86_64}</tarball>
|
||||
<checksum hash_algo="sha1" explicit="false">sha1sums.txt</checksum>
|
||||
<sig keys="7F2D434B9741E8AC" keyserver="hkp://pool.sks-keyservers.net" 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="true">cf83e1357eefb8bdf1542850d66d8007d620e4050b5715dc83f4a921d36ce9ce47d0d13c5d85f2b0ff8318d2877eec2f63b931bd47417a81a538327af927da3e</checksum>
|
||||
<sig keys="248BF41F9BDD61D41D060AE774EDA3C6B06D0506" keyserver="hkp://pool.sks-keyservers.net" flags="regex,latest">{regex%sig_i686}</sig>
|
||||
</source>
|
||||
</sources>
|
||||
<build its_full_of_stars="true">
|
||||
<paths>
|
||||
<base>{variable%bdisk_root}/base</base>
|
||||
<cache>{variable%bdisk_root}/cache</cache>
|
||||
<chroot>{variable%bdisk_root}/chroots</chroot>
|
||||
<overlay>{variable%bdisk_root}/overlay</overlay>
|
||||
<templates>{variable%bdisk_root}/templates</templates>
|
||||
<mount>/mnt/{xpath%//meta/names/uxname/text()}</mount>
|
||||
<distros>{variable%bdisk_root}/distros</distros>
|
||||
<dest>{variable%bdisk_root}/results</dest>
|
||||
<iso>{variable%bdisk_root}/iso_overlay</iso>
|
||||
<http>{variable%bdisk_root}/http</http>
|
||||
<tftp>{variable%bdisk_root}/tftp</tftp>
|
||||
<pki>{variable%bdisk_root}/pki</pki>
|
||||
</paths>
|
||||
<basedistro>archlinux</basedistro>
|
||||
</build>
|
||||
<iso sign="true" multi_arch="true"/>
|
||||
<ipxe sign="true" iso="true">
|
||||
<uri>{xpath%//meta/dev/website/text()}/ipxe</uri>
|
||||
</ipxe>
|
||||
<pki overwrite="no">
|
||||
<ca>
|
||||
<cert hash_algo="sha512">{xpath%../../../build/paths/pki/text()}/ca.crt</cert>
|
||||
<csr/>
|
||||
<index>{xpath%../../../build/paths/pki/text()}/index.txt</index>
|
||||
<serial>{xpath%../../../build/paths/pki/text()}/serial</serial>
|
||||
<key cipher="none" passphrase="none" keysize="4096">{xpath%../../../build/paths/pki/text()}/ca.key</key>
|
||||
<subject>
|
||||
<commonName>domain.tld</commonName>
|
||||
<countryName>XX</countryName>
|
||||
<localityName>Some City</localityName>
|
||||
<stateOrProvinceName>Some State</stateOrProvinceName>
|
||||
<organization>Some Org, Inc.</organization>
|
||||
<organizationalUnitName>Department Name</organizationalUnitName>
|
||||
<emailAddress>{xpath%../../../../meta/dev/email/text()}</emailAddress>
|
||||
</subject>
|
||||
</ca>
|
||||
<client>
|
||||
<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>
|
||||
<subject>
|
||||
<commonName>some client name</commonName>
|
||||
<countryName>XX</countryName>
|
||||
<localityName>Some City</localityName>
|
||||
<stateOrProvinceName>Some State</stateOrProvinceName>
|
||||
<organization>Some Org, Inc.</organization>
|
||||
<organizationalUnitName>Department Name</organizationalUnitName>
|
||||
<emailAddress>{xpath%../../../../meta/dev/email/text()}</emailAddress>
|
||||
</subject>
|
||||
</client>
|
||||
</pki>
|
||||
<gpg keyid="none" gnupghome="none" publish="no" prompt_passphrase="no">
|
||||
<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>
|
||||
</key>
|
||||
</gpg>
|
||||
<sync>
|
||||
<ipxe enabled="true">/srv/http/{xpath%../../meta/names/uxname/text()}</ipxe>
|
||||
<tftp enabled="true">/tftproot/{xpath%../../meta/names/uxname/text()}</tftp>
|
||||
<iso enabled="true">/srv/http/isos/{xpath%../../meta/names/uxname/text()}</iso>
|
||||
<gpg enabled="true" format="asc">/srv/http/{xpath%../../meta/names/uxname/text()}/pubkey.asc</gpg>
|
||||
<rsync enabled="true">
|
||||
<user>root</user>
|
||||
<host>mirror.domain.tld</host>
|
||||
<port>22</port>
|
||||
<pubkey>~/.ssh/id_ed25519</pubkey>
|
||||
</rsync>
|
||||
</sync>
|
||||
</profile>
|
||||
</bdisk>
|
||||
|
@ -1,13 +1,34 @@
|
||||
#!/usr/bin/env python3.6
|
||||
|
||||
import copy
|
||||
from lxml import etree
|
||||
from lxml import etree, objectify
|
||||
|
||||
parser = etree.XMLParser(remove_blank_text = True)
|
||||
#parser = etree.XMLParser(remove_blank_text = True)
|
||||
parser = etree.XMLParser(remove_blank_text = False)
|
||||
|
||||
# We need to append to a new root because you can't edit nsmap, and you can't
|
||||
# xpath on an element with a naked namespace (e.g. 'xlmns="..."').
|
||||
ns = {None: 'http://bdisk.square-r00t.net/',
|
||||
'xsi': 'http://www.w3.org/2001/XMLSchema-instance'}
|
||||
xsi = {'{http://www.w3.org/2001/XMLSchema-instance}schemaLocation':
|
||||
'http://bdisk.square-r00t.net bdisk.xsd'}
|
||||
new_cfg = etree.Element('bdisk', nsmap = ns, attrib = xsi)
|
||||
new_cfg.text = '\n '
|
||||
|
||||
with open('single_profile.xml', 'rb') as f:
|
||||
xml = etree.fromstring(f.read(), parser)
|
||||
|
||||
|
||||
roottree = xml.getroottree()
|
||||
for elem in roottree.getiterator():
|
||||
if not hasattr(elem.tag, 'find'):
|
||||
continue
|
||||
i = elem.tag.find('}')
|
||||
if i >= 0:
|
||||
elem.tag = elem.tag[i + 1:]
|
||||
objectify.deannotate(roottree, cleanup_namespaces = True)
|
||||
|
||||
|
||||
single_profile = xml.xpath('/bdisk/profile[1]')[0]
|
||||
alt_profile = copy.deepcopy(single_profile)
|
||||
for c in alt_profile.xpath('//comment()'):
|
||||
@ -42,18 +63,22 @@ for e in accounts.iter():
|
||||
if e.tag in accounts_tags:
|
||||
e.text = accounts_tags[e.tag]
|
||||
if e.tag == 'rootpass':
|
||||
e.attrib['hashed'] = 'no'
|
||||
e.attrib['hashed'] = 'false'
|
||||
elif e.tag == 'user':
|
||||
e.attrib['sudo'] = 'no'
|
||||
e.attrib['sudo'] = 'false'
|
||||
# Delete the second user
|
||||
accounts.remove(accounts[2])
|
||||
author = alt_profile.xpath('/profile/meta/dev/author')[0]
|
||||
author.addnext(etree.Comment(
|
||||
' You can reference other profiles within the same configuration. '))
|
||||
xml.append(alt_profile)
|
||||
#xml.append(alt_profile)
|
||||
|
||||
for child in xml.xpath('/bdisk/profile'):
|
||||
new_cfg.append(copy.deepcopy(child))
|
||||
new_cfg.append(alt_profile)
|
||||
|
||||
with open('multi_profile.xml', 'wb') as f:
|
||||
f.write(etree.tostring(xml,
|
||||
f.write(etree.tostring(new_cfg,
|
||||
pretty_print = True,
|
||||
encoding = 'UTF-8',
|
||||
xml_declaration = True))
|
||||
|
@ -1,11 +1,12 @@
|
||||
<?xml version="1.0" encoding="UTF-8" ?>
|
||||
<bdisk xmlns:bdisk="http://bdisk.square-r00t.net/"
|
||||
<bdisk xmlns="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>
|
||||
<name>BDisk</name>
|
||||
<name>BDISK</name>
|
||||
<!--<name>{xpath%../uxname/text()}</name>-->
|
||||
<uxname>bdisk</uxname>
|
||||
<!-- Just like with previous versions of BDisk, you can reference other values...
|
||||
but now with the neat benefits of XPath! Everything you could do in build.ini's and more.
|
||||
@ -29,8 +30,7 @@
|
||||
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>
|
||||
@ -41,56 +41,48 @@
|
||||
</meta>
|
||||
<accounts>
|
||||
<!-- Salted/hashed password is "test" -->
|
||||
<rootpass hashed="yes">
|
||||
$6$7KfIdtHTcXwVrZAC$LZGNeMNz7v5o/cYuA48FAxtZynpIwO5B1CPGXnOW5kCTVpXVt4SypRqfM.AoKkFt/O7MZZ8ySXJmxpELKmdlF1
|
||||
</rootpass>
|
||||
<user sudo="yes">
|
||||
<rootpass hashed="true">$6$7KfIdtHTcXwVrZAC$LZGNeMNz7v5o/cYuA48FAxtZynpIwO5B1CPGXnOW5kCTVpXVt4SypRqfM.AoKkFt/O7MZZ8ySXJmxpELKmdlF1</rootpass>
|
||||
<user sudo="true">
|
||||
<username>{xpath%//meta/names/uxname/text()}</username>
|
||||
<!-- You can also use substitution from different profiles in this same configuration: -->
|
||||
<!-- <username>{xpath%//profile[@name='another_profile']/meta/names/uxname"}</username> -->
|
||||
<comment>{xpath%//meta/dev/author/text()}</comment>
|
||||
<password hashed="no"
|
||||
<password hashed="false"
|
||||
hash_algo="sha512"
|
||||
salt="auto">testpassword
|
||||
</password>
|
||||
salt="auto">testpassword</password>
|
||||
</user>
|
||||
<user sudo="no">
|
||||
<user sudo="false">
|
||||
<username>testuser</username>
|
||||
<name>Test User</name>
|
||||
<password hashed="no"
|
||||
<comment>Test User</comment>
|
||||
<password hashed="false"
|
||||
hash_algo="sha512"
|
||||
salt="auto">anothertestpassword
|
||||
</password>
|
||||
salt="auto">anothertestpassword</password>
|
||||
</user>
|
||||
</accounts>
|
||||
<sources>
|
||||
<source arch="x86_64">
|
||||
<mirror>http://archlinux.mirror.domain.tld</mirror>
|
||||
<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"
|
||||
explicit="no">sha1sums.txt
|
||||
</checksum>
|
||||
explicit="false"
|
||||
flags="latest">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>
|
||||
<tarball flags="regex latest">{regex%tarball_i686}</tarball>
|
||||
<checksum hash_algo="sha512"
|
||||
explicit="yes">
|
||||
cf83e1357eefb8bdf1542850d66d8007d620e4050b5715dc83f4a921d36ce9ce47d0d13c5d85f2b0ff8318d2877eec2f63b931bd47417a81a538327af927da3e
|
||||
</checksum>
|
||||
explicit="true">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">
|
||||
<build its_full_of_stars="true">
|
||||
<paths>
|
||||
<base>{variable%bdisk_root}/base</base>
|
||||
<cache>{variable%bdisk_root}/cache</cache>
|
||||
@ -107,11 +99,11 @@
|
||||
</paths>
|
||||
<basedistro>archlinux</basedistro>
|
||||
</build>
|
||||
<iso sign="yes" multi_arch="yes"/>
|
||||
<ipxe sign="yes" iso="yes">
|
||||
<iso sign="true" multi_arch="true"/>
|
||||
<ipxe sign="true" iso="true">
|
||||
<uri>{xpath%//meta/dev/website/text()}/ipxe</uri>
|
||||
</ipxe>
|
||||
<pki overwrite="no">
|
||||
<pki overwrite="false">
|
||||
<!-- http://ipxe.org/crypto -->
|
||||
<ca>
|
||||
<cert hash_algo="sha512">{xpath%../../../build/paths/pki/text()}/ca.crt</cert>
|
||||
@ -133,8 +125,7 @@
|
||||
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>
|
||||
@ -146,16 +137,13 @@
|
||||
</subject>
|
||||
</ca>
|
||||
<client>
|
||||
<cert hash_algo="sha512">
|
||||
{xpath%../../../build/paths/pki/text()}/{xpath%../../../meta/names/uxname/text()}.crt
|
||||
</cert>
|
||||
<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>
|
||||
<commonName>website.tld</commonName>
|
||||
<countryName>XX</countryName>
|
||||
<localityName>Some City</localityName>
|
||||
<stateOrProvinceName>Some State</stateOrProvinceName>
|
||||
@ -169,26 +157,23 @@
|
||||
blank passphrase for all operations. -->
|
||||
<gpg keyid="none"
|
||||
gnupghome="none"
|
||||
publish="no"
|
||||
prompt_passphrase="no">
|
||||
publish="false"
|
||||
prompt_passphrase="false">
|
||||
<!-- The below is only used if we are generating a key (i.e. keyid="none"). -->
|
||||
<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>
|
||||
<!-- ipxe includes the http directory. or should, anyways. -->
|
||||
<ipxe enabled="yes">/srv/http/{xpath%../../meta/names/uxname/text()}</ipxe>
|
||||
<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>
|
||||
<rsync enabled="yes">
|
||||
<ipxe enabled="true">/srv/http/{xpath%../../meta/names/uxname/text()}</ipxe>
|
||||
<tftp enabled="true">/tftproot/{xpath%../../meta/names/uxname/text()}</tftp>
|
||||
<iso enabled="true">/srv/http/isos/{xpath%../../meta/names/uxname/text()}</iso>
|
||||
<gpg enabled="true"
|
||||
format="asc">/srv/http/{xpath%../../meta/names/uxname/text()}/pubkey.asc</gpg>
|
||||
<rsync enabled="true">
|
||||
<user>root</user>
|
||||
<host>mirror.domain.tld</host>
|
||||
<port>22</port>
|
||||
|
Loading…
Reference in New Issue
Block a user