add
This commit is contained in:
parent
06cffbdbd7
commit
d6e3e05796
0
__init__.py
Normal file
0
__init__.py
Normal file
@ -1,4 +1,6 @@
|
|||||||
import sys
|
import sys
|
||||||
|
from subprocess import Popen, PIPE
|
||||||
|
|
||||||
import gentooimgr.chroot
|
import gentooimgr.chroot
|
||||||
|
|
||||||
def command(config, *args):
|
def command(config, *args):
|
||||||
|
@ -15,9 +15,8 @@ def older_than_a_day(fullpath):
|
|||||||
return time.time() - filetime > (gentooimgr.config.DAY_IN_SECONDS *
|
return time.time() - filetime > (gentooimgr.config.DAY_IN_SECONDS *
|
||||||
gentooimgr.config.DAYS)
|
gentooimgr.config.DAYS)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
def find_iso(download_dir):
|
def find_iso(download_dir):
|
||||||
|
LOG.info(f"Looking for iso in {download_dir}")
|
||||||
name = None
|
name = None
|
||||||
ext = None
|
ext = None
|
||||||
found = []
|
found = []
|
||||||
@ -34,9 +33,10 @@ def make_iso_from_dir(mydir):
|
|||||||
path to iso that was created or NoneType if mydir is not found
|
path to iso that was created or NoneType if mydir is not found
|
||||||
"""
|
"""
|
||||||
if not os.path.exists(mydir):
|
if not os.path.exists(mydir):
|
||||||
|
LOG.warn(f"\t:: dir not found {mydir}")
|
||||||
return
|
return
|
||||||
|
|
||||||
print(f"\t:: Making ISO with dir of {mydir}")
|
LOG.info(f"\t:: Making ISO with dir of {mydir}")
|
||||||
path = os.path.join(mydir, "..", "cloudgen.iso")
|
path = os.path.join(mydir, "..", "cloudgen.iso")
|
||||||
proc = Popen(["mkisofs",
|
proc = Popen(["mkisofs",
|
||||||
"--input-charset", "utf-8",
|
"--input-charset", "utf-8",
|
||||||
@ -52,15 +52,17 @@ def make_iso_from_dir(mydir):
|
|||||||
|
|
||||||
return path
|
return path
|
||||||
|
|
||||||
def portage_from_dir(d, filename=None):
|
def portage_from_dir(download_dir, filename=None):
|
||||||
"""Find portage file from directory. Will do a check in os.listdir() for portage*.tar.bz2.
|
"""Find portage file from directory. Will do a check in os.listdir() for portage*.tar.bz2.
|
||||||
|
|
||||||
If a filename is provided, this function either returns that filename assuming it exists in d,
|
If a filename is provided, this function either returns that filename assuming it exists in d,
|
||||||
or return None. If filename is None, this looks through all entries for portage files and if
|
or return None. If filename is None, this looks through all entries for portage files and if
|
||||||
only one exists, returns it, otherwise None.
|
only one exists, returns it, otherwise None.
|
||||||
"""
|
"""
|
||||||
|
assert download_dir, f"empty {download_dir} for for portage"
|
||||||
|
LOG.info(f"Looking for portage in {download_dir}")
|
||||||
found = []
|
found = []
|
||||||
for f in os.listdir(d):
|
for f in os.listdir(download_dir):
|
||||||
if filename is not None:
|
if filename is not None:
|
||||||
if filename == f:
|
if filename == f:
|
||||||
found.append(f)
|
found.append(f)
|
||||||
@ -70,7 +72,7 @@ def portage_from_dir(d, filename=None):
|
|||||||
if len(found) > 1:
|
if len(found) > 1:
|
||||||
LOG.error("\tEE: More than one portage file exists, please specify the exact portage file with --portage [file] or remove all others\n")
|
LOG.error("\tEE: More than one portage file exists, please specify the exact portage file with --portage [file] or remove all others\n")
|
||||||
LOG.error(''.join([f"\t{f}\n" for f in found]))
|
LOG.error(''.join([f"\t{f}\n" for f in found]))
|
||||||
LOG.error(f"in {d}\n")
|
LOG.error(f"in {download_dir}\n")
|
||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
|
|
||||||
return found[0] if found else None
|
return found[0] if found else None
|
||||||
|
@ -72,7 +72,7 @@
|
|||||||
"syslog-ng": "default",
|
"syslog-ng": "default",
|
||||||
"cronie": "default",
|
"cronie": "default",
|
||||||
"acpid": "default",
|
"acpid": "default",
|
||||||
"ntp": "default"
|
"ntp": "default",
|
||||||
"qemu-guest-agent": "default"
|
"qemu-guest-agent": "default"
|
||||||
},
|
},
|
||||||
"iso": null,
|
"iso": null,
|
||||||
|
@ -151,7 +151,7 @@ def step10_emerge_pkgs(args, cfg):
|
|||||||
proc = Popen(["emerge", "-j1", single])
|
proc = Popen(["emerge", "-j1", single])
|
||||||
proc.communicate()
|
proc.communicate()
|
||||||
|
|
||||||
LOG.info("KERNEL PACKAGES", packages.get("kernel"))
|
LOG.info(f"KERNEL PACKAGES {packages.get('kernel')}")
|
||||||
if packages.get("kernel", []):
|
if packages.get("kernel", []):
|
||||||
cmd = ["emerge", "-j", str(args.threads)] + packages.get("kernel", [])
|
cmd = ["emerge", "-j", str(args.threads)] + packages.get("kernel", [])
|
||||||
proc = Popen(cmd)
|
proc = Popen(cmd)
|
||||||
|
@ -3,6 +3,8 @@ import os
|
|||||||
import sys
|
import sys
|
||||||
import argparse
|
import argparse
|
||||||
from subprocess import Popen, PIPE
|
from subprocess import Popen, PIPE
|
||||||
|
|
||||||
|
from gentooimgr import LOG
|
||||||
import gentooimgr.config
|
import gentooimgr.config
|
||||||
import gentooimgr.common
|
import gentooimgr.common
|
||||||
def create_image(args, config: dict, overwrite: bool = False) -> str:
|
def create_image(args, config: dict, overwrite: bool = False) -> str:
|
||||||
@ -36,6 +38,8 @@ def run_image(
|
|||||||
- mount_isos: list of iso paths to mount in qemu as disks.
|
- mount_isos: list of iso paths to mount in qemu as disks.
|
||||||
"""
|
"""
|
||||||
iso = config.get("iso")
|
iso = config.get("iso")
|
||||||
|
prefix = args.temporary_dir
|
||||||
|
LOG.info(f"iso from config {iso}")
|
||||||
if iso is None:
|
if iso is None:
|
||||||
iso = gentooimgr.common.find_iso(
|
iso = gentooimgr.common.find_iso(
|
||||||
os.path.join(
|
os.path.join(
|
||||||
@ -43,6 +47,13 @@ def run_image(
|
|||||||
".."
|
".."
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
LOG.info(f"iso from cwd {iso}")
|
||||||
|
if not iso:
|
||||||
|
prefix = config.get('temporary_dir')
|
||||||
|
iso = gentooimgr.common.find_iso(prefix)
|
||||||
|
LOG.info(f"iso from {prefix} {iso}")
|
||||||
|
|
||||||
|
assert iso, f"iso not found {iso}"
|
||||||
|
|
||||||
if isinstance(iso, list):
|
if isinstance(iso, list):
|
||||||
assert len(iso), f"iso list is empty {iso}"
|
assert len(iso), f"iso list is empty {iso}"
|
||||||
@ -55,6 +66,11 @@ def run_image(
|
|||||||
qmounts.append("-drive")
|
qmounts.append("-drive")
|
||||||
qmounts.append(f"file={i},media=cdrom")
|
qmounts.append(f"file={i},media=cdrom")
|
||||||
|
|
||||||
|
assert image, f"image is empty {image}"
|
||||||
|
if not os.path.exists(image):
|
||||||
|
if os.path.exists(os.path.join(prefix, image)):
|
||||||
|
image = os.path.join(prefix, image)
|
||||||
|
assert os.path.exists(image), f"image not found {image}"
|
||||||
threads = args.threads
|
threads = args.threads
|
||||||
cmd = [
|
cmd = [
|
||||||
"qemu-system-x86_64",
|
"qemu-system-x86_64",
|
||||||
@ -65,7 +81,6 @@ def run_image(
|
|||||||
"-drive", f"file={image},if=virtio,index=0",
|
"-drive", f"file={image},if=virtio,index=0",
|
||||||
"-cdrom", iso,
|
"-cdrom", iso,
|
||||||
"-net", "nic,model=virtio",
|
"-net", "nic,model=virtio",
|
||||||
"-net", "user",
|
|
||||||
"-vga", "virtio",
|
"-vga", "virtio",
|
||||||
"-cpu", "kvm64",
|
"-cpu", "kvm64",
|
||||||
"-chardev", "file,id=charserial0,path=gentoo.log",
|
"-chardev", "file,id=charserial0,path=gentoo.log",
|
||||||
@ -73,12 +88,14 @@ def run_image(
|
|||||||
"-chardev", "pty,id=charserial1",
|
"-chardev", "pty,id=charserial1",
|
||||||
"-device", "isa-serial,chardev=charserial1,id=serial1"
|
"-device", "isa-serial,chardev=charserial1,id=serial1"
|
||||||
]
|
]
|
||||||
|
# "-net", "user",
|
||||||
|
# -net user: network backend 'user' is not compiled into this binary"
|
||||||
|
|
||||||
cmd += qmounts
|
cmd += qmounts
|
||||||
print(cmd)
|
LOG.info(cmd)
|
||||||
proc = Popen(cmd, stderr=PIPE, stdout=PIPE)
|
proc = Popen(cmd, stderr=PIPE, stdout=PIPE)
|
||||||
stdout, stderr = proc.communicate()
|
stdout, stderr = proc.communicate()
|
||||||
if stderr:
|
if stderr:
|
||||||
sys.stderr.write(str(stderr))
|
LOG.error(str(stderr))
|
||||||
sys.stderr.write("\n")
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -23,6 +23,11 @@ def run(args, config: dict) -> None:
|
|||||||
assert os.path.isfile(main_iso), f"iso not found {main_iso}"
|
assert os.path.isfile(main_iso), f"iso not found {main_iso}"
|
||||||
LOG.info(args)
|
LOG.info(args)
|
||||||
LOG.info(f'iso={args.iso}')
|
LOG.info(f'iso={args.iso}')
|
||||||
|
if args.iso != config['iso']:
|
||||||
|
LOG.warn(f'iso={args.iso}')
|
||||||
|
config['iso'] = args.iso
|
||||||
|
else:
|
||||||
|
LOG.info(f'iso={args.iso}')
|
||||||
gentooimgr.qemu.run_image(
|
gentooimgr.qemu.run_image(
|
||||||
args,
|
args,
|
||||||
config,
|
config,
|
||||||
|
@ -17,14 +17,17 @@ Step 16: Sysconfig
|
|||||||
Step 17: fstab
|
Step 17: fstab
|
||||||
"""
|
"""
|
||||||
import os
|
import os
|
||||||
|
import sys
|
||||||
import json
|
import json
|
||||||
|
|
||||||
# from gentooimgr import LOG
|
# from gentooimgr import LOG
|
||||||
import gentooimgr.config
|
import gentooimgr.config
|
||||||
import gentooimgr.configs
|
import gentooimgr.configs
|
||||||
|
from gentooimgr import install
|
||||||
|
|
||||||
def print_template(args, configjson):
|
def print_template(args, configjson, prefix='/tmp'):
|
||||||
print(__doc__)
|
print(__doc__)
|
||||||
|
sys.stderr.write(f"the last step to succeed is {install.getlaststep(prefix)}\n")
|
||||||
print(f"the last step to succeed is {install.getlaststep(prefix)}\n")
|
print(f"the last step to succeed is {install.getlaststep(prefix)}\n")
|
||||||
print(f"""------------------------ STATUS ------------------------
|
print(f"""------------------------ STATUS ------------------------
|
||||||
|
|
||||||
|
189
library/ansible-keepassxc.py
Executable file
189
library/ansible-keepassxc.py
Executable file
@ -0,0 +1,189 @@
|
|||||||
|
#!/usr/bin/python
|
||||||
|
|
||||||
|
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
|
||||||
|
from __future__ import (absolute_import, division, print_function)
|
||||||
|
__metaclass__ = type
|
||||||
|
|
||||||
|
import os
|
||||||
|
import traceback
|
||||||
|
from ansible.module_utils.basic import AnsibleModule, missing_required_lib
|
||||||
|
|
||||||
|
IMPORT_ERR = None
|
||||||
|
try:
|
||||||
|
# import _argon2_xffi_bindings
|
||||||
|
import pykeepass as keepass
|
||||||
|
except ImportError:
|
||||||
|
IMPORT_ERR = traceback.format_exc()
|
||||||
|
|
||||||
|
DOCUMENTATION = r'''
|
||||||
|
---
|
||||||
|
module: ansible-keepassxc
|
||||||
|
|
||||||
|
short_description: Module to read credentials from KeePassXC
|
||||||
|
|
||||||
|
version_added: "0.0.1"
|
||||||
|
|
||||||
|
description: Module to read credentials from KeePassXC
|
||||||
|
|
||||||
|
options:
|
||||||
|
database:
|
||||||
|
description: Path to database file
|
||||||
|
required: true
|
||||||
|
type: str
|
||||||
|
password:
|
||||||
|
description: Database Password
|
||||||
|
required: true
|
||||||
|
type: str
|
||||||
|
keyfile:
|
||||||
|
description: Path to key file
|
||||||
|
required: false
|
||||||
|
type: str
|
||||||
|
entry:
|
||||||
|
description: Entry name for the attribute to fetch
|
||||||
|
required: true
|
||||||
|
type: str
|
||||||
|
group:
|
||||||
|
decription: Group name that the Entry belongs to
|
||||||
|
required: false
|
||||||
|
type: str
|
||||||
|
|
||||||
|
author:
|
||||||
|
- Jeremy Lumley (@jlumley)
|
||||||
|
'''
|
||||||
|
|
||||||
|
EXAMPLES = r'''
|
||||||
|
# Fetch the credentials for the server_1 entry in any group
|
||||||
|
- name: Fetch server_1 credentials
|
||||||
|
jlumley.jlumley.ansible-keepassxc:
|
||||||
|
database: "/secrets/db.kdbx"
|
||||||
|
password: "s3cure_p4550rd"
|
||||||
|
entry: "server_1"
|
||||||
|
|
||||||
|
# Fetch the reddit entry in the social group
|
||||||
|
- name: Fetching reddit credentials
|
||||||
|
jlumley.jlumley.ansible-keepassxc:
|
||||||
|
database: "/secrets/db.kdbx"
|
||||||
|
password: "sup3r_s3cure_p4550rd"
|
||||||
|
entry: "reddit"
|
||||||
|
group: "social"
|
||||||
|
|
||||||
|
# Fetch a custom strig attribute from the github entry
|
||||||
|
- name: Fetch Github API Token
|
||||||
|
jlumley.jlumley.ansible-keepassxc:
|
||||||
|
database: "/secrets/db.kdbx"
|
||||||
|
password: "d0pe_s3cure_p4550rd"
|
||||||
|
keyfile: "/secrets/top_secret_key"
|
||||||
|
entry: "github"
|
||||||
|
group: "development"
|
||||||
|
|
||||||
|
'''
|
||||||
|
|
||||||
|
RETURN = r'''
|
||||||
|
# Return values
|
||||||
|
username:
|
||||||
|
description: Username of entry if present
|
||||||
|
type: str
|
||||||
|
returned: always
|
||||||
|
sample: 's3cr3t_us3r'
|
||||||
|
password:
|
||||||
|
description: Password of entry if present
|
||||||
|
type: str
|
||||||
|
returned: always
|
||||||
|
sample: 's3cr3t_p455word'
|
||||||
|
url:
|
||||||
|
description: Url of entry if present
|
||||||
|
type: str
|
||||||
|
returned: always
|
||||||
|
sample: 'http://reddit.com'
|
||||||
|
custom_fields:
|
||||||
|
description: dictionary containing all custom fields
|
||||||
|
type: dict
|
||||||
|
returned: always
|
||||||
|
sample: False
|
||||||
|
no_log:
|
||||||
|
description: suppress logging of password
|
||||||
|
type: bool
|
||||||
|
returned: never
|
||||||
|
sample: False
|
||||||
|
'''
|
||||||
|
|
||||||
|
def run_module():
|
||||||
|
# define available arguments/parameters a user can pass to the module
|
||||||
|
module_args = dict(
|
||||||
|
database = dict(type='str', required=True),
|
||||||
|
password = dict(type='str', required=False,
|
||||||
|
default=os.environ.get('ANSIBLE_KEEPASSXC_PASSWORD')),
|
||||||
|
keyfile = dict(type='str', required=False, default=None),
|
||||||
|
entry = dict(type='str', required=True),
|
||||||
|
group = dict(type='str', required=False),
|
||||||
|
no_log = dict(type='bool', required=False, default=False),
|
||||||
|
)
|
||||||
|
|
||||||
|
# seed the result dict in the object
|
||||||
|
result = dict(
|
||||||
|
changed=False,
|
||||||
|
username='',
|
||||||
|
password='',
|
||||||
|
url='',
|
||||||
|
custom_fields={}
|
||||||
|
)
|
||||||
|
|
||||||
|
# Currently no support for a check_mode this maybe added later if
|
||||||
|
# functionality to modify the database is added later
|
||||||
|
module = AnsibleModule(
|
||||||
|
argument_spec=module_args,
|
||||||
|
supports_check_mode=False,
|
||||||
|
)
|
||||||
|
|
||||||
|
if IMPORT_ERR:
|
||||||
|
module.fail_json(
|
||||||
|
msg=missing_required_lib("pykeepass"),
|
||||||
|
exception=IMPORT_ERR
|
||||||
|
)
|
||||||
|
|
||||||
|
# unlock local keepass database
|
||||||
|
try:
|
||||||
|
kp = keepass.PyKeePass(
|
||||||
|
module.params['database'],
|
||||||
|
password=module.params['password'],
|
||||||
|
keyfile=module.params['keyfile'])
|
||||||
|
except keepass.exceptions.CredentialsError:
|
||||||
|
module.fail_json(msg='Invalid Credentials')
|
||||||
|
|
||||||
|
# find entry
|
||||||
|
entry = kp.find_entries(
|
||||||
|
title=module.params['entry'],
|
||||||
|
group=module.params['group']
|
||||||
|
)
|
||||||
|
|
||||||
|
# fail is entry is not present
|
||||||
|
if not entry:
|
||||||
|
module.fail_json(msg=f"Unable to find entry: {module.params['entry']}")
|
||||||
|
|
||||||
|
else:
|
||||||
|
entry = entry[0]
|
||||||
|
custom_field_keys = entry._get_string_field_keys(exclude_reserved=True)
|
||||||
|
custom_fields = dict()
|
||||||
|
for key in custom_field_keys:
|
||||||
|
custom_fields[key] = entry.get_custom_property(key)
|
||||||
|
result = dict (
|
||||||
|
changed=False,
|
||||||
|
username=entry.username,
|
||||||
|
password=entry.password,
|
||||||
|
url=entry.url,
|
||||||
|
custom_fields=custom_fields
|
||||||
|
)
|
||||||
|
|
||||||
|
# in the event of a successful module execution, you will want to
|
||||||
|
# simple AnsibleModule.exit_json(), passing the key/value results
|
||||||
|
module.exit_json(**result)
|
||||||
|
|
||||||
|
|
||||||
|
def main():
|
||||||
|
run_module()
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
main()
|
||||||
|
|
||||||
|
|
224
library/ansible_gentooimgr.py
Executable file
224
library/ansible_gentooimgr.py
Executable file
@ -0,0 +1,224 @@
|
|||||||
|
#!/usr/bin/python3
|
||||||
|
|
||||||
|
from __future__ import (absolute_import, division, print_function)
|
||||||
|
__metaclass__ = type
|
||||||
|
|
||||||
|
import os
|
||||||
|
import sys
|
||||||
|
import logging
|
||||||
|
from argparse import Namespace
|
||||||
|
import pathlib
|
||||||
|
import traceback
|
||||||
|
|
||||||
|
sys.path.append('/mnt/o/var/local/src/play_tox/src/ansible_gentooimgr')
|
||||||
|
# in the library
|
||||||
|
mod_path = os.path.dirname(os.path.realpath('__file__'))
|
||||||
|
mod_path = os.path.join(mod_path, 'src', 'ansible_gentooimgr')
|
||||||
|
assert os.path.isdir(mod_path), f"parent {mod_path}"
|
||||||
|
assert os.path.isfile(os.path.join(mod_path, '__init__.py')),f"index {mod_path}"
|
||||||
|
assert os.path.isdir(os.path.join(mod_path, 'gentooimgr')), f"sub {mod_path}"
|
||||||
|
sys.path.append(mod_path)
|
||||||
|
try:
|
||||||
|
import gentooimgr
|
||||||
|
except Exception as e:
|
||||||
|
sys.stderr.write(f"{mod_path} {sys.path} {traceback.print_exc()}")
|
||||||
|
raise
|
||||||
|
import ansible
|
||||||
|
|
||||||
|
DOCUMENTATION = rf'''
|
||||||
|
---
|
||||||
|
module: gentooimgr
|
||||||
|
|
||||||
|
short_description: Gentoo Image Builder for Cloud and Turnkey ISO installers
|
||||||
|
|
||||||
|
|
||||||
|
version_added: "1.0.0"
|
||||||
|
|
||||||
|
description:
|
||||||
|
* This project enables easy access to building ``systemd`` or ``openrc`` -based images.
|
||||||
|
* Performs automatic download AND verification of the linux iso, stage3 tarball and portage.
|
||||||
|
* Caches the iso and stage3 .txt files for at most a day before redownloading and rechecking for new files
|
||||||
|
* Sane and readable cli commands to build, run and test.
|
||||||
|
* Step system to enable user to continue off at the same place if a step fails
|
||||||
|
* No heavy packages like rust included ** TODO
|
||||||
|
|
||||||
|
options:
|
||||||
|
action:
|
||||||
|
description: The action to be run by the image builder
|
||||||
|
choices:
|
||||||
|
- build
|
||||||
|
- run
|
||||||
|
- status
|
||||||
|
- install
|
||||||
|
- chroot
|
||||||
|
- unchroot
|
||||||
|
- command
|
||||||
|
- shrink
|
||||||
|
- kernel
|
||||||
|
required: true
|
||||||
|
# clean test
|
||||||
|
config:
|
||||||
|
default: cloud.json
|
||||||
|
description: init configuration file or or base.json or cloud.json
|
||||||
|
required: false
|
||||||
|
loglevel:
|
||||||
|
default: {logging.INFO}
|
||||||
|
description: python logging level <= 50, INFO=20
|
||||||
|
required: false
|
||||||
|
threads:
|
||||||
|
default: 1
|
||||||
|
description: Number of threads to use
|
||||||
|
required: false
|
||||||
|
profile:
|
||||||
|
default: openrc
|
||||||
|
description: The init system
|
||||||
|
choices:
|
||||||
|
- openrc
|
||||||
|
- systemd
|
||||||
|
required: false
|
||||||
|
kernel_dir:
|
||||||
|
default: /usr/src/linux
|
||||||
|
description: Where kernel is specified. By default uses the active linux kernel
|
||||||
|
required: false
|
||||||
|
portage:
|
||||||
|
description: Extract the specified portage tarball onto the filesystem
|
||||||
|
required: false
|
||||||
|
stage3:
|
||||||
|
description: Extract the specified stage3 package onto the filesystema
|
||||||
|
required: false
|
||||||
|
action_args:
|
||||||
|
default: []
|
||||||
|
description: Arguments for some of the actions - UNUSED!
|
||||||
|
required: false
|
||||||
|
temporary_dir:
|
||||||
|
description: Path to temporary directory for downloading files (20G)
|
||||||
|
required: false
|
||||||
|
qcow:
|
||||||
|
description: Path to file to serve as the base image
|
||||||
|
required: false
|
||||||
|
|
||||||
|
# Specify this value according to your collection
|
||||||
|
# in format of namespace.collection.doc_fragment_name
|
||||||
|
# extends_documentation_fragment:
|
||||||
|
# - my_namespace.my_collection.my_doc_fragment_name
|
||||||
|
|
||||||
|
author:
|
||||||
|
- Your Name (@yourGitHubHandle)
|
||||||
|
'''
|
||||||
|
|
||||||
|
#[-y DAYS]
|
||||||
|
# [-d DOWNLOAD_DIR]
|
||||||
|
# [-f]
|
||||||
|
# [--format FORMAT]
|
||||||
|
|
||||||
|
EXAMPLES = r'''
|
||||||
|
# Pass in a message
|
||||||
|
- name: Test with a message
|
||||||
|
my_namespace.my_collection.my_test:
|
||||||
|
name: hello world
|
||||||
|
|
||||||
|
# pass in a message and have changed true
|
||||||
|
- name: Test with a message and changed output
|
||||||
|
my_namespace.my_collection.my_test:
|
||||||
|
name: hello world
|
||||||
|
new: true
|
||||||
|
|
||||||
|
# fail the module
|
||||||
|
- name: Test failure of the module
|
||||||
|
my_namespace.my_collection.my_test:
|
||||||
|
name: fail me
|
||||||
|
'''
|
||||||
|
|
||||||
|
RETURN = r'''
|
||||||
|
# These are examples of possible return values, and in general should use other names for return values.
|
||||||
|
message:
|
||||||
|
description: The output message that the test module generates.
|
||||||
|
type: str
|
||||||
|
returned: always
|
||||||
|
sample: 'goodbye'
|
||||||
|
'''
|
||||||
|
|
||||||
|
from ansible.module_utils.basic import AnsibleModule
|
||||||
|
|
||||||
|
|
||||||
|
def run_module():
|
||||||
|
# define available arguments/parameters a user can pass to the module
|
||||||
|
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),
|
||||||
|
profile=dict(type='str', required=False),
|
||||||
|
kernel_dir=dict(type='path', required=False),
|
||||||
|
portage=dict(type='path', required=False),
|
||||||
|
stage3=dict(type='path', required=False),
|
||||||
|
temporary_dir=dict(type='path', required=False, default=pathlib.Path(os.getcwd())),
|
||||||
|
download_dir=dict(type='path', required=False, default=pathlib.Path(os.getcwd())),
|
||||||
|
qcow=dict(type='path', required=False),
|
||||||
|
)
|
||||||
|
|
||||||
|
# seed the result dict in the object
|
||||||
|
# we primarily care about changed and state
|
||||||
|
# changed is if this module effectively modified the target
|
||||||
|
# state will include any data that you want your module to pass back
|
||||||
|
# for consumption, for example, in a subsequent task
|
||||||
|
result = dict(
|
||||||
|
changed=False,
|
||||||
|
original_message='',
|
||||||
|
message=''
|
||||||
|
)
|
||||||
|
|
||||||
|
# the AnsibleModule object will be our abstraction working with Ansible
|
||||||
|
# this includes instantiation, a couple of common attr would be the
|
||||||
|
# args/params passed to the execution, as well as if the module
|
||||||
|
# supports check mode
|
||||||
|
module = AnsibleModule(
|
||||||
|
argument_spec=module_args,
|
||||||
|
supports_check_mode=True
|
||||||
|
)
|
||||||
|
|
||||||
|
# if the user is working with this module in only check mode we do not
|
||||||
|
# want to make any changes to the environment, just return the current
|
||||||
|
# state with no modifications
|
||||||
|
if module.check_mode:
|
||||||
|
module.exit_json(**result)
|
||||||
|
|
||||||
|
# manipulate or modify the state as needed (this is going to be the
|
||||||
|
# part where your module will do what it needs to do)
|
||||||
|
# if module.params.get('thirsty'):
|
||||||
|
|
||||||
|
oargs = Namespace(**module.params)
|
||||||
|
# during the execution of the module, if there is an exception or a
|
||||||
|
# conditional state that effectively causes a failure, run
|
||||||
|
# AnsibleModule.fail_json() to pass in the message and the result
|
||||||
|
result['original_message'] = ""
|
||||||
|
try:
|
||||||
|
from gentooimgr.__main__ import main
|
||||||
|
retval = main(oargs)
|
||||||
|
except Exception as e:
|
||||||
|
result['message'] = str(e)
|
||||||
|
e = traceback.print_exc()
|
||||||
|
if e: result['original_message'] += f"{e}"
|
||||||
|
module.fail_json(msg='Exception', **result)
|
||||||
|
else:
|
||||||
|
result['message'] = str(retval)
|
||||||
|
|
||||||
|
# use whatever logic you need to determine whether or not this module
|
||||||
|
# made any modifications to your target
|
||||||
|
if dArgs['action'] in ['status']:
|
||||||
|
result['changed'] = False
|
||||||
|
else:
|
||||||
|
result['changed'] = True
|
||||||
|
|
||||||
|
# in the event of a successful module execution, you will want to
|
||||||
|
# simple AnsibleModule.exit_json(), passing the key/value results
|
||||||
|
module.exit_json(**result)
|
||||||
|
|
||||||
|
|
||||||
|
def main():
|
||||||
|
run_module()
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
main()
|
||||||
|
|
Loading…
Reference in New Issue
Block a user