Compare commits

..

2 Commits

Author SHA1 Message Date
eaf6ffdbef update 2023-12-31 07:39:01 +00:00
f2575772ec roles/ansible-gentoo_install/ 2023-12-31 03:19:26 +00:00
20 changed files with 740 additions and 106 deletions

View File

@ -1,5 +1,5 @@
[defaults]
log_path = var/tmp/2023/12/30/pentoo/base_proxy_toxcore.log
log_path = var/tmp/2023/12/31/pentoo/base_proxy_toxcore.log
callback_plugins = ./lib/plugins/
# /i/data/DevOps/net/Http/docs.ansible.com/ansible/intro_configuration.html
# http://docs.ansible.com/ansible/intro_configuration.html#command-warnings

View File

@ -112,12 +112,6 @@
that:
- "{{ansible_connection in BOX_ANSIBLE_CONNECTIONS}}"
- name: "we will use sudo and make it a prerequisite"
shell: |
which sudo || exit 1
# "check ansible_python_interpreter"
"{{ansible_python_interpreter|default('python3')}}" --version
# required
tags: always
check_mode: false
@ -184,6 +178,20 @@
check_mode: false
when: ansible_connection == 'libvirt_qemu'
- block:
# after spinup
- name: "we will use sudo and make it a prerequisite"
shell: |
[ -z "$TMPDIR" ] || [ -d "$TMPDIR" ] || mkdir -p "$TMPDIR"
which sudo || exit 1
# "check ansible_python_interpreter"
"{{ansible_python_interpreter|default('python3')}}" --version
# required
tags: always
check_mode: false
# # required?
# tags: always
# check_mode: false
@ -202,10 +210,10 @@
when:
- "'proxy' in ROLES"
- role: ansible-gentoo_install
when:
# BOX_OS_FAMILY == 'Gentoo' or BOX_GENTOO_FROM_MP != '' ?
- ( ansible_connection == 'local' and nbd_disk|default('') != '' ) or (ansible_connection == 'chroot' )
# - role: ansible-gentoo_install
# when:
# # BOX_OS_FAMILY == 'Gentoo' or BOX_GENTOO_FROM_MP != '' ?
# - ( ansible_connection == 'local' and nbd_disk|default('') != '' ) or (ansible_connection == 'chroot' )
- role: toxcore
tags: always

View File

@ -219,12 +219,6 @@ all:
BOX_ALSO_USERS:
- gentoo
BOX_PROXY_MODE: "{{lookup('env', 'MODE'|default('tor'}}"
BOX_NBD_DEV: nbd1
BOX_NBD_MP: /mnt/gentoo
BOX_NBD_FILES: "/i/data/Agile/tmp/Topics/GentooImgr"
BOX_NBD_BASE_QCOW: "/g/Agile/tmp/Topics/GentooImgr/gentoo.qcow2"
BOX_NBD_OVERLAY_NAME: "gentoo1"
BOX_NBD_OVERLAY_QCOW: "/o/var/lib/libvirt/images/gentoo1.qcow2"
BOX_GENTOO_FROM_MP: "/mnt/linuxPen19"
linuxPen19:
@ -251,12 +245,6 @@ all:
BOX_BASE_FEATURES: []
BOX_TOXCORE_FEATURES: ['nbd', 'libvirt', 'docker']
BOX_PROXY_MODE: "{{lookup('env', 'MODE'|default('tor'}}"
BOX_NBD_DEV: nbd1
BOX_NBD_MP: /mnt/gentoo
BOX_NBD_OVERLAY_NAME: "gentoo1"
BOX_NBD_BASE_QCOW: "/g/Agile/tmp/Topics/GentooImgr/gentoo.qcow2"
BOX_NBD_OVERLAY_QCOW: "/o/var/lib/libvirt/images/gentoo1.qcow2"
BOX_NBD_FILES: "/i/data/Agile/tmp/Topics/GentooImgr"
# linux_chroot_group vars
vars:
@ -271,7 +259,7 @@ all:
# for a non-root login: ansible_ssh_extra_args: "--userspec=foo:adm"
vars: # linux_unix_group
# toxcore
BOX_NBD_DEV: nbd1
BOX_NBD_DEV: nbd3
BOX_NBD_MP: /mnt/gentoo
BOX_NBD_OVERLAY_NAME: "gentoo1"
BOX_NBD_FILES: "/i/data/Agile/tmp/Topics/GentooImgr"
@ -281,18 +269,21 @@ all:
BOX_NBD_BASE_PROFILE: openrc
BOX_NBD_BASE_DIR: "/a/tmp/GentooImgr"
BOX_NBD_BASE_QCOW: "{{BOX_NBD_BASE_DIR}}/gentoo.qcow2"
# BOX_NBD_OVERLAY_QCOW: "/o/var/lib/libvirt/images/gentoo1.qcow2"
BOX_NBD_OVERLAY_QCOW: "/o/var/lib/libvirt/images/gentoo1.qcow2"
BOX_NBD_BASE_PUBKEY: "/root/.ssh/id_rsa-ansible.pub"
# libvirt overlay
BOX_NBD_OVERLAY_DIR: "/a/tmp/GentooImgr/create-vm"
BOX_NBD_LOGLEVEL: 10
BOX_NBD_OVERLAY_GB: "20"
BOX_NBD_OVERLAY_CPUS: 1
BOX_NBD_OVERLAY_RAM: 2048
BOX_NBD_OVERLAY_BR: virbr1
# unused?
BOX_NBD_OVERLAY_NETWORK: default
# plaintext
BOX_NBD_OVERLAY_PASS: "gentoo"
BOX_GENTOOIMGR_CONFIGFILE: "/g/Agile/tmp/Topics/GentooImgr/base.json"
vars:
@ -386,18 +377,25 @@ all:
BOX_NBD_MP: ""
BOX_NBD_FILES: ""
BOX_NBD_LOGLEVEL: 20
BOX_NBD_PORTAGE_FILE: "{{AGI_NBD_FILES}}/portage-20231223.tar.xz"
BOX_NBD_STAGE3_FILE: "{{AGI_NBD_FILES}}/stage3-amd64-openrc-20231217T170203Z.tar.xz"
BOX_NBD_KERNEL_DIR: /usr/src/linux
BOX_NBD_BASE_PROFILE: openrc
BOX_NBD_BASE_DIR: ""
BOX_NBD_BASE_QCOW: ""
BOX_NBD_BASE_PUBKEY: "/root/.ssh/id_rsa-ansible.pub"
BOX_NBD_BASE_PUBKEY: ""
# libvirt overlay
BOX_NBD_OVERLAY_QCOW: ""
BOX_NBD_OVERLAY_DIR: ""
BOX_NBD_OVERLAY_BR: ""
BOX_NBD_OVERLAY_GB: "20"
BOX_NBD_OVERLAY_NAME: "gentoo1"
BOX_NBD_OVERLAY_NAME: ""
BOX_NBD_OVERLAY_CPUS: 1
BOX_NBD_OVERLAY_RAM: 2048
# plaintext
BOX_NBD_OVERLAY_PASS: ""
BOX_GENTOOIMGR_CONFIGFILE: ""
# Controls what compression method is used for new-style ansible modules when
# they are sent to the remote system. The compression types depend on having

View File

@ -11,6 +11,7 @@ import pathlib
import traceback
# in the library
mod_path = ''
if os.environ.get('PLAY_ANSIBLE_SRC',''):
# running from source
mod_path = os.environ.get('PLAY_ANSIBLE_SRC','')
@ -152,11 +153,17 @@ from ansible.module_utils.basic import AnsibleModule
def run_module():
# define available arguments/parameters a user can pass to the module
#? default config from __file__ ?
if mod_path and os.path.isdir(mod_path):
def_config = os.path.join(mod_path, 'configs', 'base.json')
else:
# WARN:
def_config = 'base.json'
module_args = dict(
action=dict(type='str', required=True),
loglevel=dict(type='int', required=False, default=logging.INFO),
threads=dict(type='int', required=False, default=1),
config=dict(type='str', default='cloud.json', required=False),
config=dict(type='path', default=def_config, required=True),
profile=dict(type='str', required=False),
kernel_dir=dict(type='path', required=False),
portage=dict(type='path', required=False),
@ -204,6 +211,8 @@ def run_module():
try:
from gentooimgr.__main__ import main
retval = main(oargs)
# should be 0
# is stdout already in result? how can it be?
except Exception as e:
result['message'] = str(e)
e = traceback.print_exc()
@ -214,7 +223,8 @@ def run_module():
# use whatever logic you need to determine whether or not this module
# made any modifications to your target
if dArgs['action'] in ['status']:
# build run test chroot unchroot status clean kernel shrink
if oargs.action in ['status', '']:
result['changed'] = False
else:
result['changed'] = True
@ -227,7 +237,6 @@ def run_module():
def main():
run_module()
if __name__ == '__main__':
main()

View File

@ -8,8 +8,11 @@ AGI_NBD_MP: "{{BOX_NBD_MP|default('/mnt/gentoo')}}"
AGI_NBD_FILES: "{{BOX_NBD_FILES}}"
AGI_GENTOO_FROM_MP: "{{BOX_GENTOO_FROM_MP}}"
AGI_GENTOOIMGR_CONFIGFILE: "{{AGI_NBD_FILES}}/base.json"
AGI_PROXY_MODE: "{{PROXY_MODE|default('')}}"
AGI_use_local_kernel: false
AGI_install_disklabel: msdos
AGI_install_timezone: UTC
AGI_install_locales:

View File

@ -0,0 +1,183 @@
# -*- mode: yaml; indent-tabs-mode: nil; tab-width: 2; coding: utf-8-unix -*-
---
- name: "DEBUG: ansible-gentoo_install local"
debug:
verbosity: 0
msg: "DEBUG: ansible-gentoo_install local BOX_NBD_DEV={{BOX_NBD_DEV}}"
check_mode: no
- assert:
that:
- "'{{BOX_NBD_DEV}}' != ''"
when: ansible_connection in ['local', 'chroot']
- set_fact:
AGI_use_local_kernel: true
when:
- ansible_distribution == 'Gentoo' or BOX_GENTOO_FROM_MP not in ['/', '']
- set_fact:
AGI_PROXY_MODE: "{{PROXY_MODE|default('')}}"
when:
- PROXY_MODE|default('') != ''
check_mode: no
- set_fact:
AGI_PROXY_MODE: "{{BOX_PROXY_MODE|default('')}}"
when:
- AGI_PROXY_MODE == ''
check_mode: no
- block:
- name: check for mounted disk
shell: |
grep '/dev/{{AGI_NBD_DEV}}' /proc/mounts && exit 0
ps ax | grep -v grep | \
grep "qemu-nbd.*/dev/nbd.*{{BOX_NBD_BASE_QCOW}}" && \
echo WARN looks like theres an active nbd mount of \
"${BOX_NBD_BASE_QCOW}" && exit 1
exit 2
failed_when: false
changed_when: false
register: check_mounted_disk
check_mode: no
- name: partition if disk not mounted
fail:
msg: "looks like theres an active nbd mount of {{BOX_NBD_BASE_QCOW}}"
when:
- check_mounted_disk.rc == 1
check_mode: no
- name: partition if disk not mounted or active
include: disk.yml
when:
- check_mounted_disk.rc > 1
check_mode: no
- name: mount root partition
mount:
name: "{{AGI_NBD_MP}}"
src: "{{ AGI_install_disk }}p3"
fstype: ext4
state: mounted
check_mode: false
- name: create /boot mountpoint
file:
path: "{{AGI_NBD_MP}}/boot"
state: directory
check_mode: false
- name: mount boot partition
mount:
name: "{{AGI_NBD_MP}}/boot"
src: "{{ AGI_install_disk }}p1"
fstype: ext2
state: mounted
check_mode: false
- include: tarball.yml
- include: copy.yml
when: AGI_use_local_kernel
- name: mount distfiles
delegate_to: localhost
shell: |
[ -d "{{MOUNT_GENTOO_DISTFILES_ARCHIVES}}" ] || exit 1
grep {{MOUNT_GENTOO_DISTFILES_ARCHIVES}} /proc/mounts && exit 0
[ -d {{AGI_NBD_MP}}/usr/portage/ ] || exit 0
[ -d {{AGI_NBD_MP}}/usr/portage/distfiles ] || mkdir {{AGI_NBD_MP}}/usr/portage/distfiles
mount --bind {{MOUNT_GENTOO_DISTFILES_ARCHIVES}} {{AGI_NBD_MP}}/usr/portage/distfiles
when:
- "MOUNT_GENTOO_DISTFILES_ARCHIVES != ''"
- "AGI_NBD_MP != ''"
- include: chroot.yml
delegate_to: localhost
when: ansible_connection in ['chroot', 'local'] # libvirt?
- block:
- name: check chroot wrapper installed
shell: |
[ -x /var/tmp/chroot_wrapper.sh ] || exit 1
df /mnt/gentoo || exit 2
/var/tmp/chroot_wrapper.sh /bin/df | grep /mnt/gentoo && exit 4
exit 0
register: chroot_out
check_mode: false
- name: enable chroot wrapper
set_fact:
ansible_shell_executable: /var/tmp/chroot_wrapper.sh
old_ansible_python_interpreter: "{{ansible_python_interpreter}}"
ansible_python_interpreter: "/usr/bin/python3"
check_mode: false
when: ansible_connection in ['local']
- block:
- include: portage.yml
- include: misc.yml
- include: network.yml
- include: kernel.yml
when: not AGI_use_local_kernel
- include: bootloader.yml
- include: daemons.yml
# - include: finish.yml
check_mode: false
when:
- "ansible_connection in ['chroot'] or (ansible_connection in ['local'] or and chroot_out.rc|default(1) == 0)"
rescue:
- debug:
msg: "ERROR: error during chroot execution"
- name: disable chroot wrapper
set_fact:
ansible_shell_executable: /bin/sh
ansible_python_interpreter: "{{old_ansible_python_interpreter}}"
when:
- "ansible_connection in ['local'] and chroot_out.rc|default(1) == 0"
check_mode: false
- name: unmount filesystems
mount:
name: "{{AGI_NBD_MP}}/{{ item }}"
state: unmounted
with_items:
- proc
- sys
- dev/pts
- dev/shm
- dev
- boot
- ''
loop_control:
label: "{{AGI_NBD_MP}}/{{ item }}"
when:
- "ansible_connection in ['local'] and chroot_out.rc|default(1) == 0"
- false # leave it mounted for testing
- name: dismount any other mounts
shell: |
if [ -z "{{MOUNT_GENTOO_DISTFILES_ARCHIVES}}" ] && \
[ -d "{{MOUNT_GENTOO_DISTFILES_ARCHIVES}}" ] && \
grep {{MOUNT_GENTOO_DISTFILES_ARCHIVES}} /proc/mounts ; then
umount {{MOUNT_GENTOO_DISTFILES_ARCHIVES}}
fi
df -a | grep "{{AGI_NBD_MP}}" | sed -e 's/.* //' | tac | while read elt;do
umount $elt
done
base_chroot_unbind.bash "{{AGI_NBD_MP}}"
when:
- "ansible_connection in ['chroot'] or chroot_out.rc|default(1) == 0"
- false # leave it mounted for testing

View File

@ -0,0 +1 @@
root@pentoo.152064:1703733868

View File

@ -16,15 +16,6 @@
[ -d "{{AGI_GENTOO_FROM_MP}}" ] || exit 5
check_mode: false
- name: install to mp from source
delegate_to: localhost
shell: |
cd {{AGI_GENTOO_FROM_MP}}/usr/src/linux || exit 1
[ -d "{{AGI_NBD_MP}}/lib/modules" ] || mkdir "{{AGI_NBD_MP}}/lib/modules"
make INSTALL_PATH={{AGI_NBD_MP}}/boot install || exit 4
make INSTALL_MOD_PATH={{AGI_NBD_MP}} modules_install || exit 5
when: AGI_use_local_kernel
- name: resolve kernel symlink
shell: |
[ -h {{AGI_GENTOO_FROM_MP}}/usr/src/linux ] && \
@ -34,16 +25,26 @@
register: kernel_out
check_mode: false
- name: install to mp from source
delegate_to: localhost
shell: |
cd {{AGI_GENTOO_FROM_MP}}/usr/src/linux || exit 1
[ -d "{{AGI_NBD_MP}}/lib/modules" ] || mkdir "{{AGI_NBD_MP}}/lib/modules"
make INSTALL_PATH={{AGI_NBD_MP}}/boot install || exit 4
make INSTALL_MOD_PATH={{AGI_NBD_MP}} modules_install || exit 5
args:
creates: "{{AGI_NBD_MP}}/lib/modules/{{kernel_out.stdout}}"
when: AGI_use_local_kernel
- name: copy kernel sources
copy:
src: "{{AGI_GENTOO_FROM_MP}}/usr/src/{{kernel_out.stdout}}"
dest: "{{AGI_NBD_MP}}/usr/src"
remote_src: no
creates: "{{AGI_NBD_MP}}/usr/src/"
creates: "{{AGI_NBD_MP}}/usr/src/{{kernel_out.stdout}}"
when:
- kernel_out.rc|default(1) == 0
- AGI_use_local_kernel
- false # dunno where it went to
- name: resolve kver
shell: |
@ -102,13 +103,14 @@
- name: make directories
shell: |
cd {{AGI_GENTOO_FROM_MP}} || exit 1
for dir in {{AGI_bootstrap_dirs}}; do
[ -d "{{AGI_NBD_MP}}/{{dir}}" ] && continue
mkdir -p "{{AGI_NBD_MP}}/{{dir}}"
for dir in {{' '.join(AGI_bootstrap_dirs)}}; do
[ -d "{{AGI_NBD_MP}}/$dir" ] && continue
mkdir -p "{{AGI_NBD_MP}}/$dir"
done
for file in {{AGI_bootstrap_files}}; do
[ -f "{{AGI_NBD_MP}}/{{file}}" ] && continue
cp -np "$file" "{{AGI_NBD_MP}}/{{file}}"
for file in {{' '.join(AGI_bootstrap_files)}}; do
[ -f "{{AGI_NBD_MP}}/$file" ] && continue
cp -np "$file" "{{AGI_NBD_MP}}/$file"
done
ignore_errors: false
# dracut

View File

@ -79,6 +79,14 @@
check_mode: false
when: not ansible_check_mode
- name: label partitions
shell: |
partprobe
e2label {{ AGI_install_disk }}p3 root
e2label {{ AGI_install_disk }}p1 boot
mkswap -L swap "{{ AGI_install_disk }}p2"
sync
when: false
- block:
@ -96,13 +104,11 @@
{{ AGI_install_disk }}p2 : start= 821248, size= 4096000, type=82
{{ AGI_install_disk }}p3 : start= 4917248, size= 37025792, type=83
EOF
mke2fs {{ AGI_install_disk }}p1
mke2fs {{ AGI_install_disk }}p3
partprobe
mke2fs -L boot {{ AGI_install_disk }}p1
mke2fs -L root {{ AGI_install_disk }}p3
mkswap -L swap "{{ AGI_install_disk }}p2"
sync
when: true
- name: label partitions
shell: |
e2label {{ AGI_install_disk }}p3 root
e2label {{ AGI_install_disk }}p1 boot
mkswap -L swap "{{ AGI_install_disk }}p2"

View File

@ -78,6 +78,10 @@
state: mounted
check_mode: false
- include: tarball.yml
- include: copy.yml
when: AGI_use_local_kernel
- name: mount distfiles
delegate_to: localhost
shell: |
@ -89,11 +93,7 @@
when:
- "MOUNT_GENTOO_DISTFILES_ARCHIVES != ''"
- "AGI_NBD_MP != ''"
- false # let the tester take care of this
- include: tarball.yml
- include: copy.yml
when: AGI_use_local_kernel
- include: chroot.yml
delegate_to: localhost
@ -105,7 +105,7 @@
shell: |
[ -x /var/tmp/chroot_wrapper.sh ] || exit 1
df /mnt/gentoo || exit 2
/var/tmp/chroot_wrapper.sh df | grep /mnt/gentoo && exit 4
/var/tmp/chroot_wrapper.sh /bin/df | grep /mnt/gentoo && exit 4
exit 0
register: chroot_out
check_mode: false
@ -136,10 +136,10 @@
check_mode: false
when:
- "ansible_connection in ['chroot'] or chroot_out.rc|default(1) == 0"
- "ansible_connection in ['chroot'] or (ansible_connection in ['local'] or and chroot_out.rc|default(1) == 0)"
rescue:
- debug:
msg: "ERROR: "
msg: "ERROR: error during chroot execution"
- name: disable chroot wrapper
set_fact:
@ -177,6 +177,7 @@
df -a | grep "{{AGI_NBD_MP}}" | sed -e 's/.* //' | tac | while read elt;do
umount $elt
done
base_chroot_unbind.bash "{{AGI_NBD_MP}}"
when:
- "ansible_connection in ['chroot'] or chroot_out.rc|default(1) == 0"
- false # leave it mounted for testing

View File

@ -9,13 +9,6 @@
- set_fact:
AGI_target: Gentoo2
- name: "ansible-gentoo_install"
set_fact:
ansible_check_mode: false
when:
- "'ansible-gentoo_install' in ROLES"
- ansible_check_mode is true
- name: look for nbd partitions
shell: |
grep nbd /proc/partitions | head -1|sed -e 's/.* //'
@ -40,7 +33,7 @@
[ -d '{{PLAY_ANSIBLE_SRC}}/src/ansible_gentooimgr/gentooimgr' ] || exit 3
[ -f '{{PLAY_ANSIBLE_SRC}}/src/ansible_gentooimgr/gentooimgr/__init__.py' ] || exit 4
{{ansible_python_interpreter}} \
-c "import os sys; sys.path.append('{{PLAY_ANSIBLE_SRC}}/src/ansible_gentooimgr'); import gentooimgr; print(os.path.dirname(gentooimgr.__file__))"
-c "import os, sys; sys.path.append('{{PLAY_ANSIBLE_SRC}}/src/ansible_gentooimgr'); import gentooimgr; print(os.path.dirname(gentooimgr.__file__))" || exit 5
register: gentooimgr_out
check_mode: false
ignore_errors: true
@ -49,18 +42,72 @@
- name: set AGI_gentooimgr_configs
set_fact:
AGI_gentooimgr_configs: "{{gentooimgr_out.stdout}}/configs"
AGI_gentooimgr_configs: "{{gentooimgr_out.stdout_lines[-1]}}/configs"
- name: ansible_gentooimgr nbd status
- name: check for a gentooimgr base config
shell: |
if [ -z "{{BOX_NBD_DEV}}" ] ; then
echo ERROR: empty "BOX_NBD_DEV" - define it in hosts.yml
exit 1
fi
if ! grep -q "{{BOX_NBD_DEV}}" /proc/partitions ; then
echo ERROR: not mounted BOX_NBD_DEV="{{BOX_NBD_DEV}}" - use qemu-nbd
exit 2
fi
exit 0
- name: make a gentooimgr base config
shell: |
base=base.json
tofile="{{AGI_GENTOOIMGR_CONFIGFILE}}"
todir=`dirname "$tofile"`
[ -d $todir ] || mkdir $todir
if [ ! -f "$tofile" ] ; then
if [ -f "{{AGI_gentooimgr_configs}}/$base" ] ; then
cp -p "{{AGI_gentooimgr_configs}}/$base" "$tofile" || exit 2
else
echo WARN: FNF "{{AGI_gentooimgr_configs}}/$base"
# use base.json
fi
fi
# should operate on json with jq
# "imgsize": "20G",
# "memory": 4096,
# "mountpoint": "/mnt/gentoo",
# "imagename": null,
# "initsys": "openrc",
# "iso": null,
# "portage": null,
# "stage3": null,
# "partition": 1
if [ -f "$tofile" ] ; then
# but this is crucial
# "disk": "/dev/sda",
sed -i -e 's@"disk": ".*"@"disk": "'{{BOX_NBD_DEV}}'"@' $tofile
grep {{BOX_NBD_DEV}} $tofile || exit 4
fi
- name: check for library/ansible_gentooimgr.py
shell: |
# find it
[ -f '{{PLAY_ANSIBLE_SRC}}/library/ansible_gentooimgr.py' ] || exit 1
# run it
echo '{}' | \
{{ansible_python_interpreter}} \
'{{PLAY_ANSIBLE_SRC}}/library/ansible_gentooimgr.py' 2>&1| \
grep "Unable to figure out what parameters were passed" && exit 0
echo WARN: ansible_gentooimgr.py BROKEN
- name: ansible_gentooimgr NBD STATUS
ansible_gentooimgr:
action: status
loglevel: "{{BOX_NBD_LOGLEVEL}}"
threads: 1
config: base.config
config: "{{AGI_GENTOOIMGR_CONFIGFILE}}" # base.json - bare filename in configs
profile: "{{BOX_NBD_BASE_PROFILE}}"
kernel_dir: "{{BOX_NBD_KERNEL_DIR}}"
portage: '{{BOX_NBD_PORTAGE_FILE}}'
stage3: '{{BOX_NBD_STAGE3_FILE }}'
portage: "{{BOX_NBD_PORTAGE_FILE}}"
stage3: "{{BOX_NBD_STAGE3_FILE }}"
temporary_dir: "{{BOX_NBD_BASE_DIR}}"
download_dir: "{{AGI_NBD_FILES}}"
register: ansible_gentooimgr_out

View File

@ -12,20 +12,6 @@
[ -d "{{AGI_NBD_MP}}" ] || exit 3
check_mode: false
- name: gpg keys system
# Option --keyserver must be used to
environment: "{{proxy_env}}"
shell: |
/usr/bin/gpg --list-keys | grep "{{ item.uid }}" || \
/usr/bin/gpg --recv-keys \
--keyserver "{{ AGI_GPG_SERVER }}" "{{ item.uid }}"
with_items: "{{ agi_gpg_keys_system }}"
when:
- agi_gpg_keys_system|length > 0
- BASE_ARE_CONNECTED|default('') != ''
# FixMe:
ignore_errors: true
- name: check files dir
environment: "{{shell_env}}"
shell: |
@ -138,6 +124,20 @@
when:
- "ansible_distribution == 'Gentoo'"
- name: gpg keys system
# Option --keyserver must be used to
environment: "{{proxy_env}}"
shell: |
/usr/bin/gpg --list-keys | grep "{{ item.uid }}" || \
/usr/bin/gpg --recv-keys \
--keyserver "{{ AGI_GPG_SERVER }}" "{{ item.uid }}"
with_items: "{{ agi_gpg_keys_system }}"
when:
- agi_gpg_keys_system|length > 0
- BASE_ARE_CONNECTED|default('') != ''
# FixMe:
ignore_errors: true
- name: test portage tarball gpg our copy
environment: "{{shell_env}}"
shell: |
@ -145,6 +145,8 @@
gpg --list-keys | grep E1D6ABB63BFCFB4BA02FDF1CEC590EEAC9189250 || exit 2
gpg --verify "{{AGI_NBD_FILES}}/{{ latest_portage_tarball }}.gpgsig" \
"{{AGI_NBD_FILES}}/{{ latest_portage_tarball }}" || exit 3$?
# FixMe:
ignore_errors: true
- name: extract portage tarball
unarchive:

View File

@ -69,6 +69,7 @@ AGI_bootstrap_pkgs:
- sys-libs/gpm
- app-portage/eix
- www-client/lynx
- linux-firmware
AGI_cloud_pkgs:
# get these from base.json
@ -87,7 +88,6 @@ AGI_cloud_pkgs:
- pciutils
- net-misc/ntp
- net-fs/nfs-utils
- linux-firmware
# get these from config.json
- app-emulation/cloud-init
- sys-block/open-iscsi

View File

@ -114,7 +114,7 @@
df | grep /boot || mount /boot || exit 2
[ -d /boot/grub ] || exit 3
[ -f /boot/grub/grub.cfg ] || exit 4
[ -f /boot/grub/grub.cfg ] && cp -p /boot/grub/grub.cfg /boot/grub/grub.cfg.dst
[ -f /boot/grub/grub.cfg.dst ] || cp -p /boot/grub/grub.cfg /boot/grub/grub.cfg.dst
sed -e 's@ ro *$@ '"$LINE"' ro@' -i /boot/grub/grub.cfg
ignore_errors: true
@ -284,7 +284,19 @@
[ '{{BOX_NBD_OVERLAY_DIR}}' != '' ] || exit 2
[ '{{BOX_NBD_BASE_PUBKEY}}' != '' ] || exit 3
[ '{{BOX_NBD_BASE_QCOW}}' != '' ] || exit 4
[ -f '{{BOX_NBD_BASE_QCOW}}' ] || exit 5
[ '{{BOX_NBD_OVERLAY_RAM}}' != '' ] || exit 5
[ '{{BOX_NBD_OVERLAY_BR}}' != '' ] || exit 6
[ '{{BOX_NBD_OVERLAY_GB}}' != '' ] || exit 7
[ '{{BOX_NBD_OVERLAY_CPUS}}' != '' ] || exit 8
[ '{{BOX_NBD_OVERLAY_PASS}}' != '' ] || exit 9
if [ ! -f '{{BOX_NBD_BASE_QCOW}}' ] ; then
echo WARN: '{{BOX_NBD_BASE_QCOW}}' not built yet - skipping
exit 0
fi
if [ -z '{{BOX_NBD_BASE_PASS}}' ] ; then
echo WARN: 'BOX_NBD_BASE_PASS' empty
exit 10
fi
toxcore_create-vm.bash \
-n {{BOX_NBD_OVERLAY_NAME}} \
-k {{BOX_NBD_BASE_PUBKEY}} \
@ -293,8 +305,8 @@
-c {{BOX_NBD_OVERLAY_CPUS}} \
-r {{BOX_NBD_OVERLAY_RAM}} \
-d {{BOX_NBD_OVERLAY_DIR}} \
-b virbr0 \
-p gentoo \
-b {{BOX_NBD_OVERLAY_BR}} \
-p {{BOX_NBD_OVERLAY_PASS}} \
-o gentoo
ignore_errors: true
when:

View File

@ -40,7 +40,6 @@ toxcore_pkgs_inst:
- dev-python/requests
- gnome-base/dconf
- net-libs/gtk-vnc
- net-misc/spice-gtk
- sys-apps/dbus
- x11-libs/gtk+
- x11-libs/gtksourceview

View File

@ -2,16 +2,18 @@ GentooImgr: Gentoo Image Builder for Cloud and Turnkey ISO installers
=====================================================================
**This is a modified version of https://github.com/NucleaPeon/gentooimgr/
where we've modified the code a little to do use Python logging. We can
still use it for the build stage, but we think the install stage is better
done using ansible, hence the libvirt_cloud playbook.
where we've modified the code a little to do use Python logging and maybe fixed a bug or two. We can still use it for the build stage, but we think the install stage is better done using ansible, hence the libvirt_cloud playbook; you don't check return values in your install steps, and I'm confused on the precedence of the config json file.
I think you should merge args into the configjson object and have the code work only on the merged object: the precedence shouldn't be down in the code.
The code is a WIP so look to see if the repo is active. It's being supported as an ansible module using library/ansible_gentooimgr.py which is a work in progress; the idea is to use it for the build and status test? actions, but handle the install tasks using ansible.
Instead of using cloud-init, our approach is to build a base image with qemu-guest-agent installed which means you don't need cloud-init. That means you don't need 384 crates of opaque googled code. Apart from making the base smaller, it makes it auditable, I can't imaging why the libvirt base images on the Internet don't include qemu-guest-agent.........
Take any of the code you want back into your repo: I think the changes are all logging and bulletproofing. If you use ansible you can maintain the library file. If you don't maybe it a good time to look at it, because writing the install in Python will be painfully limiting, and it may take you a while to write tests.py.
Please wrap the code after if __name__ == "__main__" in __main__.py into a function that returns an int, 0 on success so it's callable from an import.
The code is in overlay/Linux/usr/local/src/ansible_gentooimgr
for reasons to do with how the ansible role transfers files.
The code is being supported as an ansible module using
library/ansible_gentooimgr.py which is a work in progress; the idea
is to use it for the build and status actions, but handle the install
tasks using ansible.
**

View File

@ -0,0 +1,360 @@
"""Configure a Gentoo guest with cloud image settings
This step keeps track of how far it's gotten, so re-running this command
will continue on if an error was to occur, unless --start-over flag is given.
"""
import os
import sys
import shutil
import configparser
from subprocess import Popen, PIPE
import logging
import traceback
import gentooimgr.config
import gentooimgr.configs
import gentooimgr.common
import gentooimgr.chroot
import gentooimgr.kernel
from gentooimgr import LOG
from gentooimgr import HERE
from gentooimgr.configs import *
FILES_DIR = os.path.join(HERE, "..")
def step1_diskprep(args, cfg):
LOG.info("\t:: Step 1: Disk Partitioning")
# http://rainbow.chard.org/2013/01/30/how-to-align-partitions-for-best-performance-using-parted/
# http://honglus.blogspot.com/2013/06/script-to-automatically-partition-new.html
cmds = [
['parted', '-s', f'{cfg.get("disk")}', 'mklabel', 'msdos'],
['parted', '-s', f'{cfg.get("disk")}', 'mkpart', 'primary', '2048s', '100%'],
['partprobe'],
['mkfs.ext4', '-FF', f'{cfg.get("disk")}{cfg.get("partition", 1)}']
]
for c in cmds:
proc = Popen(c, stdout=PIPE, stderr=PIPE)
stdout, stderr = proc.communicate()
completestep(1, "diskprep")
def step2_mount(args, cfg):
LOG.info(f'\t:: Step 2: Mounting {gentooimgr.config.GENTOO_MOUNT}')
proc = Popen(["mount", f'{cfg.get("disk")}{cfg.get("partition")}', cfg.get("mountpoint")])
proc.communicate()
completestep(2, "mount")
def step3_stage3(args, cfg):
LOG.info(f'\t:: Step 3: Stage3 Tarball')
stage3 = cfg.get("stage3") or args.stage3 # FIXME: auto detect stage3 images in mountpoint and add here
if not stage3:
stage3 = gentooimgr.common.stage3_from_dir(FILES_DIR)
proc = Popen(["tar", "xpf", os.path.abspath(stage3), "--xattrs-include='*.*'", "--numeric-owner", "-C",
f'{cfg.get("mountpoint")}'])
proc.communicate()
completestep(3, "stage3")
def step4_binds(args, cfg):
LOG.info(f'\t:: Step 4: Binding Filesystems')
gentooimgr.chroot.bind(verbose=False)
completestep(4, "binds")
def step5_portage(args, cfg):
LOG.info(f'\t:: Step 5: Portage')
portage = cfg.get("portage") or args.portage
if not portage:
portage = gentooimgr.common.portage_from_dir(FILES_DIR)
proc = Popen(["tar", "xpf", portage, "-C", f"{cfg.get('mountpoint')}/usr/"])
proc.communicate()
# Edit portage
portage_env = os.path.join(cfg.get("mountpoint"), 'etc', 'portage', 'env')
os.makedirs(portage_env, exist_ok=True)
with open(os.path.join(portage_env, 'singlejob.conf'), 'w') as f:
f.write('MAKEOPTS="-j1"\n')
env_path = os.path.join(cfg.get("mountpoint"), 'etc', 'portage', 'package.env')
with open(env_path, 'w') as f:
f.write("app-portage/eix singlejob.conf\ndev-util/maturin singlejob.conf\ndev-util/cmake singlejob.conf")
completestep(5, "portage")
def step6_licenses(args, cfg):
LOG.info(f'\t:: Step 6: Licenses')
license_path = os.path.join(cfg.get("mountpoint"), 'etc', 'portage', 'package.license')
os.makedirs(license_path, exist_ok=True)
for f, licenses in cfg.get("licensefiles", {}).items():
with open(os.path.join(license_path, f), 'w') as f:
f.write('\n'.join(licenses))
completestep(6, "license")
def step7_repos(args, cfg):
LOG.info(f'\t:: Step 7: Repo Configuration')
repo_path = os.path.join(cfg.get("mountpoint"), 'etc', 'portage', 'repos.conf')
os.makedirs(repo_path, exist_ok=True)
# Copy from template
repo_file = os.path.join(repo_path, 'gentoo.conf')
shutil.copyfile(
os.path.join(cfg.get("mountpoint"), 'usr', 'share', 'portage', 'config', 'repos.conf'),
repo_file)
# Regex replace lines
cp = configparser.ConfigParser()
for repofile, data in cfg.get("repos", {}).items():
cp.read(cfg.get("mountpoint") + repofile) # repofile should be absolute path, do not use os.path.join.
for section, d in data.items():
if section in cp:
for key, val in d.items():
# Replace everything after the key with contents of value.
# Sed is simpler than using regex for this purpose.
cp.set(section, key, val)
else:
sys.stderr.write(f"\tWW No section {section} in {repofile}\n")
cp.write(open(cfg.get("mountpoint") + repofile, 'w'))
completestep(7, "repos")
def step8_resolv(args, cfg):
LOG.info(f'\t:: Step 8: Resolv')
proc = Popen(["cp", "--dereference", "/etc/resolv.conf", os.path.join(cfg.get("mountpoint"), 'etc')])
proc.communicate()
# Copy all step files and python module to new chroot
os.system(f"cp /tmp/*.step {cfg.get('mountpoint')}/tmp")
os.system(f"cp -r . {cfg.get('mountpoint')}/mnt/")
completestep(8, "resolv")
def step9_sync(args, cfg):
LOG.info(f"\t:: Step 9: sync")
LOG.info("\t\t:: Entering chroot")
os.chroot(cfg.get("mountpoint"))
os.chdir(os.sep)
os.system("source /etc/profile")
proc = Popen(["emerge", "--sync", "--quiet"])
proc.communicate()
LOG.info("\t\t:: Emerging base")
proc = Popen(["emerge", "--update", "--deep", "--newuse", "--keep-going", "@world"])
proc.communicate()
completestep(9, "sync")
def step10_emerge_pkgs(args, cfg):
LOG.info(f"\t:: Step 10: emerge pkgs")
packages = cfg.get("packages", {})
for oneshot_up in packages.get("oneshots", []):
proc = Popen(["emerge", "--oneshot", "--update", oneshot_up])
proc.communicate()
for single in packages.get("singles", []):
proc = Popen(["emerge", "-j1", single])
proc.communicate()
LOG.info(f"KERNEL PACKAGES {packages.get('kernel')}")
if packages.get("kernel", []):
cmd = ["emerge", "-j", str(args.threads)] + packages.get("kernel", [])
proc = Popen(cmd)
proc.communicate()
cmd = ["emerge", "-j", str(args.threads), "--keep-going"]
cmd += packages.get("keepgoing", [])
proc = Popen(cmd)
proc.communicate()
cmd = ["emerge", "-j", str(args.threads)]
cmd += packages.get("base", [])
cmd += packages.get("additional", [])
cmd += packages.get("bootloader", [])
LOG.info(cmd)
proc = Popen(cmd)
proc.communicate()
completestep(10, "pkgs")
def step11_kernel(args, cfg):
# at this point, genkernel will be installed
LOG.info(f"\t:: Step 11: kernel")
proc = Popen(["eselect", "kernel", "set", "1"])
proc.communicate()
if not args.kernel_dist:
os.chdir(args.kernel_dir)
threads = str(gentooimgr.config.THREADS)
gentooimgr.kernel.build_kernel(args, cfg)
completestep(11, "kernel")
def step12_grub(args, cfg):
LOG.info(f"\t:: Step 12: kernel")
proc = Popen(["grub-install", cfg.get('disk')])
proc.communicate()
code = proc.returncode
if code != 0:
sys.stderr.write(f"Failed to install grub on {cfg.get('disk')}\n")
sys.exit(code)
with open("/etc/default/grub", 'w') as f:
f.write(f"{gentooimgr.kernel.GRUB_CFG}")
proc = Popen(["grub-mkconfig", "-o", "/boot/grub/grub.cfg"])
proc.communicate()
completestep(12, "grub")
def step13_serial(args, cfg):
LOG.info(f"\t:: Step 13: Serial")
os.system("sed -i 's/^#s0:/s0:/g' /etc/inittab")
os.system("sed -i 's/^#s1:/s1:/g' /etc/inittab")
completestep(13, "serial")
def step14_services(args, cfg):
LOG.info(f"\t:: Step 14: Services")
for service in ["acpid", "syslog-ng", "cronie", "sshd", "cloud-init-local", "cloud-init", "cloud-config",
"cloud-final", "ntpd", "nfsclient"]:
if args.profile == "systemd":
proc = Popen(["systemctl", "enable", service])
else:
proc = Popen(["rc-update", "add", service, "default"])
proc.communicate()
completestep(14, "services")
def step15_ethnaming(args, cfg):
LOG.info(f"\t:: Step 15: Eth Naming")
completestep(15, "networking")
def step16_sysconfig(args, cfg):
LOG.info(f"\t:: Step 16: Sysconfig")
with open("/etc/timezone", "w") as f:
f.write("UTC")
proc = Popen(["emerge", "--config", "sys-libs/timezone-data"])
proc.communicate()
with open("/etc/locale.gen", "a") as f:
f.write("en_US.UTF-8 UTF-8\nen_US ISO-8859-1\n")
proc = Popen(["locale-gen"])
proc.communicate()
proc = Popen(["eselect", "locale", "set", "en_US.utf8"])
proc.communicate()
proc = Popen(["env-update"])
proc.communicate()
with open('/etc/sysctl.d/swappiness.conf', 'w') as f:
f.write("vm.swappiness = 0\n")
modloadpath = os.path.join(os.sep, 'etc', 'modules-load.d')
os.makedirs(modloadpath, exist_ok=True)
with open(os.path.join(modloadpath, 'cloud-modules.conf'), 'w') as f:
f.write('\n'.join(gentooimgr.config.CLOUD_MODULES))
cloudcfg = os.path.join(os.sep, 'etc', 'cloud')
if not os.path.exists(cloudcfg):
os.makedirs(cloudcfg, exist_ok=True)
os.makedirs(os.path.join(cloudcfg, 'templates'), exist_ok=True)
with open(os.path.join(cloudcfg, 'cloud.cfg'), 'w') as cfg:
cfg.write(f"{CLOUD_YAML}")
os.chmod(os.path.join(cloudcfg, "cloud.cfg"), 0o644)
with open(os.path.join(cloudcfg, "templates", "hosts.gentoo.tmpl"), 'w') as tmpl:
tmpl.write(f"{HOST_TMPL}") # FIXME:
os.chmod(os.path.join(cloudcfg, "templates", "hosts.gentoo.tmpl"), 0o644)
proc = Popen("sed -i 's/domain_name\,\ domain_search\,\ host_name/domain_search/g' /etc/dhcpcd.conf", shell=True)
proc.communicate()
hostname = os.path.join(os.sep, 'etc', 'conf.d', 'hostname')
with open(hostname, 'w') as f:
f.write(f"{HOSTNAME}\n")
os.chmod(hostname, 0o644)
proc = Popen(["eix-update"])
proc.communicate()
os.remove(os.path.join(os.sep, 'etc', 'resolv.conf'))
completestep(16, "sysconfig")
def step17_fstab(args, cfg):
LOG.info(f"\t:: Step 17: fstab")
with open(os.path.join(os.sep, 'etc', 'fstab'), 'a') as fstab:
fstab.write(f"{cfg.get('disk')}\t/\text4\tdefaults,noatime\t0 1\n")
completestep(17, "fstab")
def completestep(step, stepname, prefix='/tmp'):
with open(os.path.join(prefix, f"{step}.step"), 'w') as f:
f.write("done.") # text in this file is not currently used.
def getlaststep(prefix='/tmp'):
i = 1
found = False
while not found:
if os.path.exists(f"{i}.step"):
i += 1
else:
found = True
return i
def stepdone(step, prefix='/tmp'):
return os.path.exists(os.path.join(prefix, f"{step}.step"))
def configure(args, config: dict):
# Load configuration
if not os.path.exists(gentooimgr.config.GENTOO_MOUNT):
if not args.force:
# We aren't in a gentoo live cd are we?
sys.stderr.write("Your system doesn't look like a gentoo live cd, exiting for safety.\n"
"If you want to continue, use --force option and re-run `python -m gentooimgr install` with your configuration\n")
sys.exit(1)
else:
# Assume we are root as per live cd, otherwise user should run this as root as a secondary confirmation
os.makedirs(gentooimgr.config.GENTOO_MOUNT)
# disk prep
cfg = config
# must be root for linux-6.1.52-pentoo/certs/signing_key.pem
if not stepdone(1): step1_diskprep(args, cfg)
# mount root
if not stepdone(2): step2_mount(args, cfg)
# extract stage
if not stepdone(3): step3_stage3(args, cfg)
# mount binds
if not stepdone(4): step4_binds(args, cfg)
# extract portage
if not stepdone(5): step5_portage(args, cfg)
# Set licenses
if not stepdone(6): step6_licenses(args, cfg)
# repos.conf
if not stepdone(7): step7_repos(args, cfg)
# portage env files and resolv.conf
if not stepdone(8): step8_resolv(args, cfg)
# emerge --sync
if not stepdone(9): step9_sync(args, cfg)
# bindist
if not stepdone(10): step10_emerge_pkgs(args, cfg)
# emerge packages
# configure & emerge kernel (use cloud configuration too)
if not stepdone(11): step11_kernel(args, cfg)
# grub
if not stepdone(12): step12_grub(args, cfg)
# enable serial console
if not stepdone(13): step13_serial(args, cfg)
# services
if not stepdone(14): step14_services(args, cfg)
# eth0 naming
# timezone
if not stepdone(15): step15_ethnaming(args, cfg)
# locale
# set some sysctl things
# set some dhcp things
# hostname
if not stepdone(16): step16_sysconfig(args, cfg)
# fstab
if not stepdone(17): step17_fstab(args, cfg)
# copy cloud cfg?
gentooimgr.chroot.unbind()
# Finish install processes like emaint and eix-update and news read

View File

@ -0,0 +1 @@
root@pentoo.152064:1703733868

View File

@ -165,7 +165,7 @@ if __name__ == "__main__":
args = parser.parse_args()
assert args.loglevel < 59
if coloredlogs:
if coloredlogs is not None:
# https://pypi.org/project/coloredlogs/
coloredlogs.install(level=args.loglevel,
logger=LOG,

View File

@ -8,7 +8,7 @@ import gentooimgr.qemu as qemu
import gentooimgr.common
import requests
def build(args: argparse.Namespace, config: dict) -> None:
def build(args: argparse.Namespace, config: dict) -> str:
LOG.info(": build")
iso = config.get("iso") or download.download(args)