holy cats. docs are finally done
and packaging commands/alternate packager reconfigured- though untested. bumping tag out of beta because nothing should(????) break.
This commit is contained in:
parent
fa61ea6400
commit
bad590518a
8
HOWTO
8
HOWTO
@ -1,8 +0,0 @@
|
||||
The following kernel parameters are supported:
|
||||
|
||||
aif aif=True do the same thing. if aif is False, it behaves as if aif is not specified. Enable AIF.
|
||||
aif_url path to install XML document. can be e.g.: http://domain.tld/aif.xml https://domain.tld/aif.xml ftp://domain.tld/aif.xml file:///tmp/aif.xml (note that local filesystem references are in relation to the system running the client) (note: HTTPS must be signed by a valid root CA)
|
||||
aif_username the username to use for HTTP/HTTPS Basic auth, HTTP/HTTPS Digest auth, or FTP/FTPS auth (must be specified to use Basic/Digest auth)
|
||||
aif_password the password to use for HTTP/HTTPS Basic auth, HTTP/HTTPS Digest auth, or FTP/FTPS auth (must be specified to use Basic/Digest auth)
|
||||
aif_auth either 'basic' or 'digest', for HTTP/HTTPS auth (ignored for other types). default, if others are specified, is basic.
|
||||
aif_realm the realm name for HTTP/HTTPS Digest auth (ignored for other types). leave unset to try whatever default realm is presented
|
10
aif.xsd
10
aif.xsd
@ -109,6 +109,12 @@
|
||||
</xs:restriction>
|
||||
</xs:simpleType>
|
||||
|
||||
<xs:simpleType name="scripttype">
|
||||
<xs:restriction base="xs:token">
|
||||
<xs:pattern value="(pre|post|pkg)" />
|
||||
</xs:restriction>
|
||||
</xs:simpleType>
|
||||
|
||||
<xs:simpleType name="bootloaders">
|
||||
<xs:restriction base="xs:token">
|
||||
<xs:pattern value="(grub|systemd|syslinux)" />
|
||||
@ -266,7 +272,6 @@
|
||||
<xs:element name="pacman" maxOccurs="1" minOccurs="1">
|
||||
<xs:complexType>
|
||||
<xs:sequence>
|
||||
<xs:element name="command" maxOccurs="1" minOccurs="0" />
|
||||
<xs:element name="repos" maxOccurs="1" minOccurs="1">
|
||||
<xs:complexType>
|
||||
<xs:sequence>
|
||||
@ -305,6 +310,7 @@
|
||||
</xs:complexType>
|
||||
</xs:element>
|
||||
</xs:sequence>
|
||||
<xs:attribute name="command" type="xs:string" />
|
||||
</xs:complexType>
|
||||
</xs:element>
|
||||
<!-- END PACMAN -->
|
||||
@ -325,7 +331,7 @@
|
||||
<xs:complexType>
|
||||
<xs:attribute name="uri" type="scripturi" use="required" />
|
||||
<xs:attribute name="order" type="xs:integer" use="required" />
|
||||
<xs:attribute name="bootstrap" type="xs:boolean" use="required" />
|
||||
<xs:attribute name="execution" type="xs:scripttype" use="required" />
|
||||
<xs:attribute name="user" type="xs:string" />
|
||||
<xs:attribute name="password" type="xs:string" />
|
||||
<xs:attribute name="realm" type="xs:string" />
|
||||
|
41
aifclient.py
41
aifclient.py
@ -306,10 +306,10 @@ class aif(object):
|
||||
for i in x:
|
||||
aifdict['software']['mirrors'].append(i.text)
|
||||
# Then the command
|
||||
if xmlobj.find('pacman/command') is None:
|
||||
aifdict['software']['command'] = False
|
||||
if 'command' in xmlobj.find('pacman').attrib:
|
||||
aifdict['software']['command'] = xmlobj.find('pacman').attrib['command']
|
||||
else:
|
||||
aifdict['software']['command'] = xmlobj.find('pacman/command').text
|
||||
aifdict['software']['command'] = False
|
||||
# And then the repo list.
|
||||
for x in xmlobj.findall('pacman/repos/repo'):
|
||||
repo = x.attrib['name']
|
||||
@ -348,11 +348,8 @@ class aif(object):
|
||||
scriptcontents = self.webFetch(x.attrib['uri'], auth).decode('utf-8')
|
||||
else:
|
||||
scriptcontents = self.webFetch(x.attrib['uri']).decode('utf-8')
|
||||
if x.attrib['bootstrap'].lower() in ('true', '1'):
|
||||
tempscriptdict['pre'][x.attrib['order']] = scriptcontents
|
||||
else:
|
||||
tempscriptdict['post'][x.attrib['order']] = scriptcontents
|
||||
for d in ('pre', 'post'):
|
||||
tempscriptdict[x.attrib['execution']][x.attrib['order']] = scriptcontents
|
||||
for d in ('pre', 'post', 'pkg'):
|
||||
keylst = list(tempscriptdict[d].keys())
|
||||
keylst.sort()
|
||||
for s in keylst:
|
||||
@ -782,7 +779,6 @@ class archInstall(object):
|
||||
return(bootcmds)
|
||||
|
||||
def scriptcmds(self, scripttype):
|
||||
# Pre-run/"booststrap" scripts
|
||||
t = scripttype
|
||||
if t in self.scripts.keys():
|
||||
for i, s in enumerate(self.scripts[t]):
|
||||
@ -793,11 +789,11 @@ class archInstall(object):
|
||||
f.write(s)
|
||||
os.chmod(filepath, 0o700)
|
||||
os.chown(filepath, 0, 0) # shouldn't be necessary, but just in case the umask's messed up or something.
|
||||
if t == 'pre':
|
||||
if t in ('pre', 'pkg'):
|
||||
# We want to run these right away.
|
||||
with open(logfile, 'a') as log:
|
||||
for i, s in enumerate(self.scripts['pre']):
|
||||
subprocess.call('/root/scripts/pre/{0}'.format(i),
|
||||
for i, s in enumerate(self.scripts[t]):
|
||||
subprocess.call('/root/scripts/{0}/{1}'.format(t, i),
|
||||
stdout = log,
|
||||
stderr = subprocess.STDOUT)
|
||||
return()
|
||||
@ -847,12 +843,9 @@ class archInstall(object):
|
||||
# This should be run in the chroot, unless we find a way to pacstrap
|
||||
# packages separate from chrooting
|
||||
if self.software['command']:
|
||||
pkgr = self.software['command']
|
||||
pkgr = shlex.split(self.software['command'])
|
||||
else:
|
||||
pkgr = 'pacman'
|
||||
pkgropts = ['--needed', '--noconfirm']
|
||||
if pkgr == 'apacman':
|
||||
pkgropts.extend(['--noedit', '--skipinteg'])
|
||||
pkgr = ['pacman', '--needed', '--noconfirm', '-S']
|
||||
if self.software['packages']:
|
||||
for p in self.software['packages'].keys():
|
||||
if self.software['packages'][p]['repo']:
|
||||
@ -860,11 +853,8 @@ class archInstall(object):
|
||||
self.software['packages'][p])
|
||||
else:
|
||||
pkgname = p
|
||||
cmd = [pkgr]
|
||||
for o in pkgropts:
|
||||
cmd.append(o)
|
||||
cmd.extend(['-S', pkgname])
|
||||
pkgcmds.append(cmd)
|
||||
pkgr.append(pkgname)
|
||||
pkgcmds.append(pkgr)
|
||||
return(pkgcmds)
|
||||
|
||||
def serviceSetup(self):
|
||||
@ -903,6 +893,12 @@ class archInstall(object):
|
||||
with open(logfile, 'a') as log:
|
||||
for c in chrootcmds:
|
||||
subprocess.call(c, stdout = log, stderr = subprocess.STDOUT)
|
||||
if scripts['pkg']:
|
||||
self.scriptcmds('pkg')
|
||||
for i, s in enumerate(scripts['pkg']):
|
||||
subprocess.call('/root/scripts/pkg/{0}'.format(i),
|
||||
stdout = log,
|
||||
stderr = subprocess.STDOUT)
|
||||
for p in pkgcmds:
|
||||
subprocess.call(p, stdout = log, stderr = subprocess.STDOUT)
|
||||
for b in bootcmds:
|
||||
@ -946,6 +942,7 @@ def main():
|
||||
with open(logfile, 'a') as log:
|
||||
pprint.pprint(instconf, stream = log)
|
||||
runInstall(instconf)
|
||||
subprocess.call(['reboot'])
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
|
@ -409,12 +409,22 @@ The `/aif/system/service` element holds information about services that should e
|
||||
|======================
|
||||
|
||||
=== `<pacman>`
|
||||
The `/aif/pacman` element contains the <<code_repos_code, repos>>, <<code_repo_code, repos/repo>>, <<code_mirrorlist_code, mirrorlist>>, <<code_mirror_code, mirrorlist/mirror>>, <<code_software_code, software>>, <<code_package_code, software/packages>>, and <<code_command_code, command>> elements.
|
||||
The `/aif/pacman` element contains the <<code_repos_code, repos>>, <<code_repo_code, repos/repo>>, <<code_mirrorlist_code, mirrorlist>>, <<code_mirror_code, mirrorlist/mirror>>, <<code_software_code, software>>, and <<code_package_code, software/packages>> elements.
|
||||
|
||||
==== `<command>`
|
||||
NOTE: This is currently kind of useless. I need to implement a pre-package-installation <<code_scripts_code, hook script>> first. I promise it's coming.
|
||||
[options="header"]
|
||||
|======================
|
||||
^|Attribute ^|Value
|
||||
^m|command |The command to use to install a package
|
||||
|======================
|
||||
|
||||
If you configured an alternate package utility, you can specify the command here. Note that it should be configured/called with necessary options to avoid the necessity of user involvement (since that's the entire point of AIF-NG).
|
||||
[[command]]
|
||||
If you configured an alternate package utility (using a `execution="pkg"` <<code_script_code, script>> entry), you can specify the command here. Note that it should be configured/called with necessary options to avoid the necessity of user involvement (since that's the entire point of AIF-NG). e.g.:
|
||||
|
||||
<aif ... >
|
||||
...
|
||||
<pacman command="apacman --needed --noconfirm --noedit --skipinteg -S">
|
||||
...
|
||||
</aif>
|
||||
|
||||
==== `<repos>`
|
||||
The `/aif/pacman/repos` element contains one (or more) <<code_repo_code, repo>> element(s).
|
||||
@ -476,7 +486,15 @@ The `/aif/scripts/script` elements specify scripts to be run at different stages
|
||||
^m|user |Same behavior as <<starting_an_install, `aif_user`>> but for fetching this script (see also <<aif_url, further notes>> on this)
|
||||
^m|password |Same behavior as <<starting_an_install, `aif_password`>> but for fetching this script (see also <<aif_url, further notes>> on this)
|
||||
^m|realm |Same behavior as <<starting_an_install, `aif_realm`>> but for fetching this script (see also <<aif_url, further notes>> on this)
|
||||
^m|bootstrap |A boolean; if `1`/`true` then we will run this script before even formatting <<code_disk_code, disks>>; otherwise if it's `0`/`false` then we would run it *inside* the chroot environment as the very last thing
|
||||
^m|execution |(see <<script_types, below>>)
|
||||
|======================
|
||||
|
||||
NOTE: The `bootstrap` attribute is subject to change to something more flexible to allow more flexibility in when the scripts are executed. Expect this to happen soon, so be aware.
|
||||
|
||||
[[script_types]]
|
||||
There are several script types availabe for `execution`. Currently, these are:
|
||||
|
||||
* pre
|
||||
* pkg
|
||||
* post
|
||||
|
||||
*pre* scripts are run (in numerical `order`) before the disks are even formatted. *pkg* scripts are run (in numerical `order`) right before the <<code_package_code, packages>> are installed (this allows you to configure an <<command, alternate packager>> such as https://aur.archlinux.org/packages/apacman/[apacman^]) - these are run *inside* the chroot of the new install. *pre* scripts are run inside the chroot like *pkg*, but are executed very last thing, just before the reboot.
|
||||
|
77
sampledict
77
sampledict
@ -1,77 +0,0 @@
|
||||
{'disk': {'/dev/sda': {'fmt': 'gpt',
|
||||
'parts': {'1': {'fstype': 'ef00',
|
||||
'num': '1',
|
||||
'size': '10%',
|
||||
'start': '0%'},
|
||||
'2': {'fstype': '8300',
|
||||
'num': '2',
|
||||
'size': '80%',
|
||||
'start': '10%'},
|
||||
'3': {'fstype': '8200',
|
||||
'num': '3',
|
||||
'size': '10%',
|
||||
'start': '80%'}}}},
|
||||
'mount': {'1': {'device': '/dev/sda2',
|
||||
'fstype': None,
|
||||
'mountpt': '/mnt',
|
||||
'opts': None},
|
||||
'2': {'device': '/dev/sda1',
|
||||
'fstype': None,
|
||||
'mountpt': '/mnt/boot',
|
||||
'opts': None},
|
||||
'3': {'device': '/dev/sda3',
|
||||
'fstype': None,
|
||||
'mountpt': 'swap',
|
||||
'opts': None}},
|
||||
'network': {'hostname': 'aiftest.square-r00t.net',
|
||||
'ifaces': {'auto': {'ipv4': {'addresses': ['auto'],
|
||||
'gw': False,
|
||||
'resolvers': False},
|
||||
'resolvers': []}}},
|
||||
'scripts': {'post': {}, 'pre': {}},
|
||||
'software': {'mirrors': ['http://mirrors.advancedhosters.com/archlinux/$repo/os/$arch',
|
||||
'http://mirrors.advancedhosters.com/archlinux/$repo/os/$arch',
|
||||
'http://mirror.us.leaseweb.net/archlinux/$repo/os/$arch',
|
||||
'http://ftp.osuosl.org/pub/archlinux/$repo/os/$arch',
|
||||
'http://arch.mirrors.ionfish.org/$repo/os/$arch',
|
||||
'http://mirrors.gigenet.com/archlinux/$repo/os/$arch',
|
||||
'http://mirror.jmu.edu/pub/archlinux/$repo/os/$arch'],
|
||||
'packages': {'sed': {'repo': 'core'}},
|
||||
'repos': {'archlinuxfr': {'enabled': False,
|
||||
'mirror': 'http://repo.archlinux.fr/$arch',
|
||||
'siglevel': 'Optional TrustedOnly'},
|
||||
'community': {'enabled': True,
|
||||
'mirror': 'file:///etc/pacman.d/mirrorlist',
|
||||
'siglevel': 'default'},
|
||||
'core': {'enabled': True,
|
||||
'mirror': 'file:///etc/pacman.d/mirrorlist',
|
||||
'siglevel': 'default'},
|
||||
'extra': {'enabled': True,
|
||||
'mirror': 'file:///etc/pacman.d/mirrorlist',
|
||||
'siglevel': 'default'},
|
||||
'multilib': {'enabled': True,
|
||||
'mirror': 'file:///etc/pacman.d/mirrorlist',
|
||||
'siglevel': 'default'},
|
||||
'multilib-testing': {'enabled': False,
|
||||
'mirror': 'file:///etc/pacman.d/mirrorlist',
|
||||
'siglevel': 'default'},
|
||||
'testing': {'enabled': False,
|
||||
'mirror': 'file:///etc/pacman.d/mirrorlist',
|
||||
'siglevel': 'default'}}},
|
||||
'system': {'bootloader': {'efi': 'true', 'target': '/boot', 'type': 'grub'},
|
||||
'chrootpath': '/mnt',
|
||||
'kbd': False,
|
||||
'locale': 'en_US.UTF-8',
|
||||
'services': False,
|
||||
'timezone': 'EST5EDT'},
|
||||
'users': {'aifusr': {'comment': 'A test user for AIF.',
|
||||
'gid': None,
|
||||
'group': None,
|
||||
'home': {'create': True, 'path': '/opt/aifusr'},
|
||||
'password': '$6$WtxZKOyaahvvWQRG$TUys60kQhF0ffBdnDSJVTA.PovwCOajjMz8HEHL2H0ZMi0bFpDTQvKA7BqzM3nA.ZMAUxNjpJP1dG/eA78Zgw0',
|
||||
'sudo': True,
|
||||
'uid': None,
|
||||
'xgroup': {'admins': {'create': True, 'gid': False},
|
||||
'users': {'create': False, 'gid': False},
|
||||
'wheel': {'create': False, 'gid': False}}},
|
||||
'root': {'password': '$6$3YPpiS.l3SQC6ELe$NQ4qMvcDpv5j1cCM6AGNc5Hyg.rsvtzCt2VWlSbuZXCGg2GB21CMUN8TMGS35tdUezZ/n9y3UFGlmLRVWXvZR.'}}}
|
Loading…
Reference in New Issue
Block a user