lago package

class lago.Prefix(prefix)[source]

Bases: object

A prefix is a directory that will contain all the data needed to setup the environment.

_prefix

str

Path to the directory of this prefix

_paths

lago.path.Paths

Path handler class

_virt_env

lago.virt.VirtEnv

Lazily loaded virtual env handler

_metadata

dict

Lazily loaded metadata

_add_nic_to_mapping(net, dom, nic)[source]

Populates the given net spec mapping entry with the nicks of the given domain

Parameters:
  • net (dict) – Network spec to populate
  • dom (dict) – libvirt domain specification
  • nic (str) – Name of the interface to add to the net mapping from the domain
Returns:

None

_allocate_ips_to_nics(conf)[source]

For all the nics of all the domains in the conf that have dynamic ip, allocate one and addit to the network mapping

Parameters:conf (dict) – Configuration spec to extract the domains from
Returns:None
_allocate_subnets(conf)[source]

Allocate all the subnets needed by the given configuration spec

Parameters:conf (dict) – Configuration spec where to get the nets definitions from
Returns:allocated subnets
Return type:list
_check_predefined_subnets(conf)[source]

Checks if all of the nets defined in the config are inside the allowed range, throws exception if not

Parameters:conf (dict) – Configuration spec where to get the nets definitions from
Returns:None
Raises:RuntimeError – If there are any subnets out of the allowed range
_config_net_topology(conf)[source]

Initialize and populate all the network related elements, like reserving ips and populating network specs of the given confiiguration spec

Parameters:conf (dict) – Configuration spec to initalize
Returns:None
_create_disk(name, spec, template_repo=None, template_store=None)[source]

Creates a disc with the given name from the given repo or store.

Parameters:
  • name (str) – Name of the domain to create the disk for
  • spec (dict) – Specification of the disk to create
  • template_repo (TemplateRepository or None) – template repo instance to use
  • template_store (TemplateStore or None) – template store instance to use
Returns:

Tuple – Path with the disk and metadata

Return type:

str, dict

Raises:

RuntimeError – If the type of the disk is not supported or failed to create the disk

_create_paths()[source]

Get the path handler for this instance

Returns:Path handler
Return type:lago.paths.Paths
_create_ssh_keys()[source]

Generate a pair of ssh keys for this prefix

Returns:None
Raises:RuntimeError – if it fails to create the keys
_create_virt_env()[source]

Create a new virt env from this prefix

Returns:virt env created from this prefix
Return type:lago.virt.VirtEnv
_get_metadata()[source]

Retrieve the metadata info for this prefix

Returns:metadata info
Return type:dict
_init_net_specs(conf)[source]

Given a configuration specification, initializes all the net definitions in it so they can be used comfortably

Parameters:conf (dict) – Configuration specification
Returns:None
_register_preallocated_ips(conf)[source]

Parse all the domains in the given conf and preallocate all their ips into the networks mappings, raising exception on duplicated ips or ips out of the allowed ranges

Parameters:conf (dict) – Configuration spec to parse
Returns:None
Raises:RuntimeError – if there are any duplicated ips or any ip out of the allowed range
_save_metadata()[source]

Write this prefix metadata to disk

Returns:None
_use_prototype(spec, conf)[source]

Populates the given spec with the values of it’s declared prototype

Parameters:
  • spec (dict) – spec to update
  • conf (dict) – Configuration spec containing the prototypes
Returns:

updated spec

Return type:

dict

cleanup()[source]

Stops any running entities in the prefix and uninitializes it, usually you want to do this if you are going to remove the prefix afterwards

Returns:None
create_snapshots(name)[source]

Creates one snapshot on all the domains with the given name

Parameters:name (str) – Name of the snapshots to create
Returns:None
initialize()[source]

Initialize this prefix, this includes creating the destination path, and creating the uuid for the prefix, for any other actions see Prefix.virt_conf()

Will safely roll back if any of those steps fail

Returns:None
Raises:RuntimeError – If it fails to create the prefix dir
paths

Access the path handler for this prefix

Returns:Path handler
Return type:lago.paths.Paths
revert_snapshots(name)[source]

Revert all the snapshots with the given name from all the domains

Parameters:name (str) – Name of the snapshots to revert
Returns:None
save()[source]

Save this prefix to persistent storage

Returns:None
start()[source]

Start this prefix

Returns:None
stop()[source]

Stop this prefix

Returns:None
virt_conf(conf, template_repo=None, template_store=None)[source]

Initializes all the virt infrastructure of the prefix, creating the domains disks, doing any network leases and creating all the virt related files and dirs inside this prefix.

Parameters:
  • conf (dict) – Configuration spec
  • template_repo (TemplateRepository) – template repository intance
  • template_store (TemplateStore) – template store instance
Returns:

None

virt_env

Getter for this instance’s virt env, creates it if needed

Returns:virt env instance used by this prefix
Return type:lago.virt.VirtEnv
lago._create_ip(subnet, index)[source]

Given a subnet or an ip and an index returns the ip with that lower index from the subnet (255.255.255.0 mask only subnets)

Parameters:
  • subnet (str) – Strign containing the three first elements of the decimal representation of a subnet (X.Y.Z) or a full ip (X.Y.Z.A)
  • index (int or str) – Last element of a decimal ip representation, for example, 123 for the ip 1.2.3.123
Returns:

The dotted decimal representation of the ip

Return type:

str

lago._ip_in_subnet(subnet, ip)[source]

Checks if an ip is included in a subnet.

Note

only 255.255.255.0 masks allowed

Parameters:
  • subnet (str) – Strign containing the three first elements of the decimal representation of a subnet (X.Y.Z) or a full ip (X.Y.Z.A)
  • ip (str or int) – Decimal ip representation
Returns:

True if ip is in subnet, False otherwise

Return type:

bool

Submodules

lago.brctl module

lago.brctl._brctl(command, *args)[source]
lago.brctl.create(name, stp=True)[source]
lago.brctl.destroy(name)[source]
lago.brctl.exists(name)[source]

lago.config module

lago.config._get_environ()[source]
lago.config._get_from_dir(path, key)[source]
lago.config._get_from_env(key)[source]
lago.config._get_from_files(paths, key)[source]
lago.config._get_providers()[source]
lago.config.get(key, default=<object object>)[source]

lago.constants module

lago.dirlock module

lago.dirlock._lock_path(path)[source]
lago.dirlock.lock(path, excl, key_path)[source]
lago.dirlock.trylock(path, excl, key_path)[source]
lago.dirlock.unlock(path, key_path)[source]

lago.paths module

class lago.paths.Paths(prefix)[source]

Bases: object

_prefixed(*args)[source]
images(*path)[source]
logs()[source]
metadata()[source]
prefix()[source]
prefix_lagofile()[source]

This file represents a prefix that’s initialized

ssh_id_rsa()[source]
ssh_id_rsa_pub()[source]
uuid()[source]
virt(*path)[source]

lago.subnet_lease module

Module that handles the leases for the subnets of the virtual network interfaces.

Note

Currently only /24 ranges are handled, and all of them under the 192.168.MIN_SUBNET to 192.168.MAX_SUBNET ranges

The leases are stored under LEASE_DIR as json files with the form:

[
    "/path/to/prefix/uuid/file",
    "uuid_hash",
]

Where the uuid_hash is the 32 char uuid of the prefix (the contents of the uuid file at the time of doing the lease)

lago.subnet_lease.LEASE_DIR = '/var/lib/lago/subnets/'

Path to the directory where the net leases are stored

lago.subnet_lease.LOCK_FILE = '/var/lib/lago/subnets/leases.lock'

Path to the net leases lock

lago.subnet_lease.MAX_SUBNET = 209

Upper range for the allowed subnets

lago.subnet_lease.MIN_SUBNET = 200

Lower range for the allowed subnets

lago.subnet_lease._acquire(*args, **kwargs)[source]

Lease a free network for the given uuid path

Parameters:uuid_path (str) – Path to the uuid file of a lago.Prefix
Returns:the third element of the dotted ip of the leased network or None if no lease was available
Return type:int or None

Todo

Raise exception or something instead of returning None so the caller can handle the failure case

lago.subnet_lease._lease_owned(path, current_uuid_path)[source]

Checks if the given lease is owned by the prefix whose uuid is in the given path

Note

The prefix must be also in the same path it was when it took the lease

Parameters:
  • path (str) – Path to the lease
  • current_uuid_path (str) – Path to the uuid to check ownersip of
Returns:

True if the given lease in owned by the prefix, False otherwise

Return type:

bool

lago.subnet_lease._lease_valid(path)[source]

Checs if the given lease still has a prefix that owns it

Parameters:path (str) – Path to the lease
Returns:True if the uuid path in the lease still exists and is the same as the one in the lease
Return type:bool
lago.subnet_lease._locked(func)[source]

Decorator that will make sure that you have the exclusive lock for the leases

lago.subnet_lease._release(*args, **kwargs)[source]

Free the lease of the given subnet index

Parameters:index (int) – Third element of a dotted ip representation of the subnet, for example, for 1.2.3.4 it would be 3
Returns:None
lago.subnet_lease._take_lease(path, uuid_path)[source]

Persist to the given leases path the prefix uuid that’s in the uuid path passed

Parameters:
  • path (str) – Path to the leases file
  • uuid_path (str) – Path to the prefix uuid
Returns:

None

lago.subnet_lease._validate_lease_dir_present(func)[source]

Decorator that will ensure that the lease dir exists, creating it if necessary

lago.subnet_lease.acquire(uuid_path)[source]

Lease a free network for the given uuid path

Parameters:uuid_path (str) – Path to the uuid file of a lago.Prefix
Returns:the dotted ip of the gateway for the leased net
Return type:str

Todo

_aquire might return None, this will throw a TypeError

lago.subnet_lease.is_leasable_subnet(subnet)[source]

Checks if a given subnet is inside the defined provisionable range

Parameters:subnet (str) – Subnet or ip in dotted decimal format
Returns:True if subnet is inside the range, False otherwise
Return type:bool
lago.subnet_lease.release(subnet)[source]

Free the lease of the given subnet

Parameters:subnet (str) – dotted ip or network to free the lease of
Returns:None

lago.sysprep module

lago.sysprep._config_net_interface(iface, **kwargs)[source]
lago.sysprep._upload_file(local_path, remote_path)[source]
lago.sysprep._write_file(path, content)[source]
lago.sysprep.add_ssh_key(key, with_restorecon_fix=False)[source]
lago.sysprep.config_net_interface_dhcp(iface, hwaddr)[source]
lago.sysprep.set_hostname(hostname)[source]
lago.sysprep.set_iscsi_initiator_name(name)[source]
lago.sysprep.set_root_password(password)[source]
lago.sysprep.set_selinux_mode(mode)[source]
lago.sysprep.sysprep(disk, mods)[source]

lago.templates module

lago.utils module

class lago.utils.CommandStatus[source]

Bases: lago.utils.CommandStatus

class lago.utils.EggTimer(timeout)[source]
elapsed()[source]
class lago.utils.RollbackContext(*args)[source]

Bases: object

A context manager for recording and playing rollback. The first exception will be remembered and re-raised after rollback

Sample usage: > with RollbackContext() as rollback: > step1() > rollback.prependDefer(lambda: undo step1) > def undoStep2(arg): pass > step2() > rollback.prependDefer(undoStep2, arg)

More examples see tests/utilsTests.py @ vdsm code

__exit__(exc_type, exc_value, traceback)[source]

If this function doesn’t return True (or raises a different exception), python re-raises the original exception once this function is finished.

clear()[source]
defer(func, *args, **kwargs)[source]
prependDefer(func, *args, **kwargs)[source]
class lago.utils.VectorThread(targets)[source]
join_all(raise_exceptions=True)[source]
start_all()[source]
lago.utils._CommandStatus

alias of CommandStatus

lago.utils._read_nonblocking(f)[source]
lago.utils._ret_via_queue(func, queue)[source]
lago.utils.drain_ssh_channel(chan, stdin=None, stdout=<open file '<stdout>', mode 'w'>, stderr=<open file '<stderr>', mode 'w'>)[source]
lago.utils.func_vector(target, args_sequence)[source]
lago.utils.interactive_ssh_channel(chan, command=None, stdin=<open file '<stdin>', mode 'r'>)[source]
lago.utils.invoke_in_parallel(func, *args_sequences)[source]
lago.utils.json_dump(obj, f)[source]
lago.utils.run_command(command, input_data=None, out_pipe=-1, err_pipe=-1, env=None, **kwargs)[source]
lago.utils.service_is_enabled(name)[source]
lago.utils.setup_logging(logdir)[source]

lago.virt module

class lago.virt.BridgeNetwork(env, spec)[source]

Bases: lago.virt.Network

_libvirt_xml()[source]
start()[source]
stop()[source]
class lago.virt.NATNetwork(env, spec)[source]

Bases: lago.virt.Network

_libvirt_xml()[source]
class lago.virt.Network(env, spec)[source]

Bases: object

_libvirt_name()[source]
add_mapping(name, ip, save=True)[source]
add_mappings(mappings)[source]
alive()[source]
gw()[source]
is_management()[source]
name()[source]
resolve(name)[source]
save()[source]
start()[source]
stop()[source]
class lago.virt.ServiceState[source]
ACTIVE = 2
INACTIVE = 1
MISSING = 0
class lago.virt.VM(env, spec)[source]

Bases: object

VM properties: * name * cpus * memory * disks * metadata * network/mac addr

_check_alive(func)[source]
_create_dead_snapshot(name)[source]
_create_live_snapshot(name)[source]
_detect_service_manager()[source]
_get_ssh_client(*args, **kwargs)[source]
_libvirt_name()[source]
_libvirt_xml()[source]
classmethod _normalize_spec(spec)[source]
_open_ssh_client()[source]
_reclaim_disk(path)[source]
_reclaim_disks()[source]
_sftp(*args, **kwds)[source]
_template_metadata()[source]
alive()[source]
bootstrap()[source]
copy_from(remote_path, local_path)[source]
copy_to(local_path, remote_path)[source]
create_snapshot(name)[source]
distro()[source]
extract_paths(paths)[source]
guest_agent()[source]
interactive_ssh(*args, **kwargs)[source]
ip()[source]
iscsi_name()[source]
metadata
name()[source]
nics()[source]
revert_snapshot(name)[source]
root_password()[source]
save(path=None)[source]
service(*args, **kwargs)[source]
ssh(command, data=None, show_output=True)[source]
ssh_script(path, show_output=True)[source]
start()[source]
stop()[source]
virt_env()[source]
vnc_port(*args, **kwargs)[source]
wait_for_ssh(connect_retries=50)[source]
class lago.virt.VirtEnv(prefix, vm_specs, net_specs)[source]

Bases: object

Env properties: * prefix * vms * net

  • libvirt_con
_create_net(net_spec)[source]
_create_vm(vm_spec)[source]
bootstrap()[source]
create_snapshots(name)[source]
classmethod from_prefix(prefix)[source]
get_net(name=None)[source]
get_nets()[source]
get_vm(name)[source]
get_vms()[source]
libvirt_con
prefixed_name(unprefixed_name)[source]
revert_snapshots(name)[source]
save()[source]
start()[source]
stop()[source]
virt_path(*args)[source]
class lago.virt._Service(vm, name)[source]
alive()[source]
exists()[source]
classmethod is_supported(vm)[source]
start()[source]
stop()[source]
class lago.virt._SysVInitService(vm, name)[source]

Bases: lago.virt._Service

BIN_PATH = '/sbin/service'
_request_start()[source]
_request_stop()[source]
state()[source]
class lago.virt._SystemdContainerService(vm, name)[source]

Bases: lago.virt._Service

BIN_PATH = '/usr/bin/docker'
HOST_BIN_PATH = '/usr/bin/systemctl'
_request_start()[source]
_request_stop()[source]
state()[source]
class lago.virt._SystemdService(vm, name)[source]

Bases: lago.virt._Service

BIN_PATH = '/usr/bin/systemctl'
_request_start()[source]
_request_stop()[source]
state()[source]
lago.virt._gen_ssh_command_id()[source]
lago.virt._guestfs_copy_path(g, guest_path, host_path)[source]
lago.virt._ip_to_mac(ip)[source]
lago.virt._path_to_xml(basename)[source]