Skip to content

Commit

Permalink
improved readability greatly. Fixed overwriting host vars bug
Browse files Browse the repository at this point in the history
  • Loading branch information
XaverStiensmeier committed Oct 18, 2024
1 parent 4a0ff18 commit d989d73
Show file tree
Hide file tree
Showing 6 changed files with 108 additions and 116 deletions.
71 changes: 34 additions & 37 deletions bibigrid/core/actions/create.py
Original file line number Diff line number Diff line change
Expand Up @@ -196,20 +196,17 @@ def start_vpn_or_master(self, configuration, provider): # pylint: disable=too-m
image = image_selection.select_image(provider, instance["image"], self.log,
configuration.get("fallbackOnOtherImage"))

volumes = self.attach_volumes(provider=provider, instance=instance, name=name)
volumes = self.create_server_volumes(provider=provider, instance=instance, name=name)

# create a server and block until it is up and running
boot_volume = instance.get("bootVolume", configuration.get("bootVolume", {}))
server = provider.create_server(name=name, flavor=flavor, key_name=self.key_name, image=image, network=network,
volumes=volumes, security_groups=configuration["security_groups"], wait=True,
boot_from_volume=instance.get("bootFromVolume",
configuration.get("bootFromVolume", False)),
boot_volume=instance.get("bootVolume", configuration.get("bootVolume")),
terminate_boot_volume=instance.get("terminateBootVolume",
configuration.get("terminateBootVolume",
True)),
volume_size=instance.get("bootVolumeSize",
configuration.get("bootVolumeSize", 50)))
self.attached_volumes_ansible_preparation(provider, server, instance, name)
boot_from_volume=boot_volume.get("bootFromVolume", False),
boot_volume=bool(boot_volume),
terminate_boot_volume=boot_volume.get("terminate", True),
volume_size=boot_volume.get("size", 50))
self.add_volume_device_info_to_instance(provider, server, instance, name)

configuration["private_v4"] = server["private_v4"]
self.log.debug(f"Created Server {name}: {server['private_v4']}.")
Expand Down Expand Up @@ -239,18 +236,17 @@ def start_workers(self, worker, worker_count, configuration, provider): # pylin
image = image_selection.select_image(provider, worker["image"], self.log,
configuration.get("fallbackOnOtherImage"))

volumes = self.attach_volumes(provider=provider, instance=worker, name=name)
volumes = self.create_server_volumes(provider=provider, instance=worker, name=name)

# create a server and block until it is up and running
boot_volume = worker.get("bootVolume", configuration.get("bootVolume", {}))
server = provider.create_server(name=name, flavor=flavor, key_name=self.key_name, image=image, network=network,
volumes=volumes, security_groups=configuration["security_groups"], wait=True,
boot_from_volume=worker.get("bootFromVolume",
configuration.get("bootFromVolume", False)),
boot_volume=worker.get("bootVolume", configuration.get("bootVolume")),
terminate_boot_volume=worker.get("terminateBootVolume",
configuration.get("terminateBootVolume",
True)))
self.attached_volumes_ansible_preparation(provider, server, worker, name)
boot_from_volume=boot_volume.get("bootFromVolume", False),
boot_volume=bool(boot_volume),
terminate_boot_volume=boot_volume.get("terminateBoot", True),
volume_size=boot_volume.get("size", 50))
self.add_volume_device_info_to_instance(provider, server, worker, name)

self.log.info(f"Worker {name} started on {provider.cloud_specification['identifier']}.")
with self.worker_thread_lock:
Expand All @@ -264,30 +260,31 @@ def start_workers(self, worker, worker_count, configuration, provider): # pylin
ansible_configurator.write_yaml(a_rp.HOSTS_FILE, hosts, self.log)
self.log.debug(f"Added worker {name} to hosts file {a_rp.HOSTS_FILE}.")

def attach_volumes(self, provider, instance, name):
def create_server_volumes(self, provider, instance, name):
self.log.info("Creating volumes ...")
volumes = []
for i, attach_volume in enumerate(instance.get("attachVolumes", [])):
return_volumes = []
for i, volume in enumerate(instance.get("volumes", [])):
volume_name = f"{name}-{i}"
self.log.debug(f"Created volume {volume_name}")
volume = provider.create_volume(size=attach_volume.get("size", 50), name=volume_name)
attach_volume["name"] = volume_name
volumes.append(volume)
return volumes

def attached_volumes_ansible_preparation(self, provider, server, instance, name):
server_volumes = provider.get_mount_info_from_server(server) # list of attached volumes
attach_volumes = instance.get("attachVolumes", [])
if attach_volumes:
for attach_volume in attach_volumes:
volume["name"] = volume_name
return_volume = provider.create_volume(size=volume.get("size", 50), name=volume_name)
return_volumes.append(return_volume)
return return_volumes

def add_volume_device_info_to_instance(self, provider, server, instance, name):
server_volumes = provider.get_mount_info_from_server(server) # list of volumes attachments
volumes = instance.get("volumes")
if volumes:
for volume in volumes:
server_volume = next((server_volume for server_volume in server_volumes if
server_volume["name"] == attach_volume["name"]), None)
attach_volume["device"] = server_volume.get("device")
self.log.debug(f"Added Configuration: Instance {name} has volume {attach_volume['name']} "
f"as device {attach_volume['device']} that is going to be mounted to "
f"{attach_volume['mountPoint']}")
server_volume["name"] == volume["name"]), None)
volume["device"] = server_volume.get("device")

self.log.debug(f"Added Configuration: Instance {name} has volume {volume['name']} "
f"as device {volume['device']} that is going to be mounted to "
f"{volume['mountPoint']}")
else:
instance["attachVolumes"] = []
instance["volumes"] = []

def prepare_vpn_or_master_args(self, configuration, provider):
"""
Expand Down
11 changes: 7 additions & 4 deletions bibigrid/core/utility/ansible_configurator.py
Original file line number Diff line number Diff line change
Expand Up @@ -91,14 +91,14 @@ def write_host_and_group_vars(configurations, providers, cluster_id, log): # py
name = create.WORKER_IDENTIFIER(cluster_id=cluster_id,
additional=f"[{worker_count}-{worker_count + worker.get('count', 1) - 1}]")
group_name = name.replace("[", "").replace("]", "").replace(":", "_").replace("-", "_")
worker_count += worker.get('count', 1)
regexp = create.WORKER_IDENTIFIER(cluster_id=cluster_id, additional=r"\d+")
worker_dict = {"name": name, "regexp": regexp, "image": worker["image"],
"network": configuration["network"], "flavor": flavor_dict,
"gateway_ip": configuration["private_v4"],
"cloud_identifier": configuration["cloud_identifier"],
"on_demand": worker.get("onDemand", True), "state": "CLOUD",
"partitions": worker.get("partitions", []) + ["all", configuration["cloud_identifier"]],
"boot_volume": worker.get("bootVolume", configuration.get("bootVolume", {}))
}

worker_features = worker.get("features", [])
Expand All @@ -111,8 +111,11 @@ def write_host_and_group_vars(configurations, providers, cluster_id, log): # py
pass_through(configuration, worker_dict, "waitForServices", "wait_for_services")
write_yaml(os.path.join(aRP.GROUP_VARS_FOLDER, f"{group_name}.yaml"), worker_dict, log)
for worker_number in range(worker.get('count', 1)):
name = create.WORKER_IDENTIFIER(cluster_id=cluster_id, additional=worker_number)
write_yaml(os.path.join(aRP.HOST_VARS_FOLDER, f"{name}.yaml"), {"volumes": worker.get("attachVolumes", [])}, log)
name = create.WORKER_IDENTIFIER(cluster_id=cluster_id, additional=worker_count+worker_number)
write_yaml(os.path.join(aRP.HOST_VARS_FOLDER, f"{name}.yaml"), {"volumes": worker.get("volumes", [])},
log)
worker_count += worker.get('count', 1)

vpngtw = configuration.get("vpnInstance")
if vpngtw:
name = create.VPN_WORKER_IDENTIFIER(cluster_id=cluster_id, additional=f"{vpn_count}")
Expand Down Expand Up @@ -141,7 +144,7 @@ def write_host_and_group_vars(configurations, providers, cluster_id, log): # py
"network_cidrs": configuration["subnet_cidrs"], "floating_ip": configuration["floating_ip"],
"flavor": flavor_dict, "private_v4": configuration["private_v4"],
"cloud_identifier": configuration["cloud_identifier"],
"volumes": configuration["masterInstance"]["attachVolumes"],
"volumes": configuration["masterInstance"]["volumes"],
"fallback_on_other_image": configuration.get("fallbackOnOtherImage", False),
"state": "UNKNOWN" if configuration.get("useMasterAsCompute", True) else "DRAINED",
"on_demand": False,
Expand Down
40 changes: 27 additions & 13 deletions bibigrid/core/utility/validate_schema.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,15 +5,21 @@
from schema import Schema, Optional, Or, SchemaError

WORKER = {'type': str, 'image': str, Optional('count'): int, Optional('onDemand'): bool, Optional('partitions'): [str],
Optional('features'): [str],
Optional('bootVolume'): str,
Optional('bootFromVolume'): bool, Optional('terminateBootVolume'): bool, Optional('bootVolumeSize'): int,
}
Optional('features'): [str],
Optional('bootVolume'): {
Optional('name'): str,
Optional('terminate'): bool,
Optional('size'): int
},
}
MASTER = VPN = {'type': str, 'image': str, Optional('onDemand'): bool, Optional('partitions'): [str],
Optional('features'): [str],
Optional('bootVolume'): str,
Optional('bootFromVolume'): bool, Optional('terminateBootVolume'): bool, Optional('bootVolumeSize'): int,
}
Optional('features'): [str],
Optional('bootVolume'): {
Optional('name'): str,
Optional('terminate'): bool,
Optional('size'): int
},
}

# Define the schema for the configuration file
master_schema = Schema(
Expand All @@ -31,22 +37,30 @@
'ResumeTimeout'): int,
Optional('TreeWidth'): int}},
Optional('zabbix'): bool, Optional('nfs'): bool, Optional('ide'): bool, Optional('useMasterAsCompute'): bool,
Optional('useMasterWithPublicIp'): bool, Optional('waitForServices'): [str], Optional('bootVolume'): str,
Optional('bootFromVolume'): bool, Optional('terminateBootVolume'): bool, Optional('bootVolumeSize'): int,
Optional('useMasterWithPublicIp'): bool, Optional('waitForServices'): [str],
Optional('gateway'): {'ip': str, 'portFunction': str}, Optional('dontUploadCredentials'): bool,
Optional('fallbackOnOtherImage'): bool,
Optional('localDNSLookup'): bool, Optional('features'): [str], 'workerInstances': [
WORKER],
'masterInstance': MASTER,
Optional('vpngtw'): {'type': str, 'image': str},
Optional('bootVolume'): str,
Optional('bootFromVolume'): bool, Optional('terminateBootVolume'): bool, Optional('bootVolumeSize'): int
Optional('bootVolume'): {
Optional('name'): str,
Optional('terminate'): bool,
Optional('size'): int
},
})

other_schema = Schema(
{'infrastructure': str, 'cloud': str, 'sshUser': str, Or('subnet', 'network'): str, 'cloud_identifier': str,
Optional('waitForServices'): [str], Optional('features'): [str], 'workerInstances': [
WORKER], 'vpnInstance': VPN})
WORKER], 'vpnInstance': VPN,
Optional('bootVolume'): {
Optional('name'): str,
Optional('terminate'): bool,
Optional('size'): int
},
})


def validate_configurations(configurations, log):
Expand Down
45 changes: 8 additions & 37 deletions documentation/markdown/features/configuration.md
Original file line number Diff line number Diff line change
Expand Up @@ -70,38 +70,6 @@ cloudScheduling:
sshTimeout: 5
```

#### masterMounts (optional:False)

`masterMounts` expects a list of volumes and snapshots. Those will be attached to the master. If any snapshots are
given, volumes are first created from them. Volumes are not deleted after Cluster termination.

```yaml
masterMounts:
- name: test # name of the volume to be attached
mountPoint: /vol/spool2 # where attached volume is to be mount to (optional)
```

`masterMounts` can be combined with [nfsshares](#nfsshares-optional).
The following example attaches volume test to our master instance and mounts it to `/vol/spool2`.
Then it creates an nfsshare on `/vol/spool2` allowing workers to access the volume test.

```yaml
masterMounts:
- name: test # name of the volume to be attached
mountPoint: /vol/spool2 # where attached volume is to be mount to (optional)
nfsshares:
- /vol/spool2
```

<details>
<summary>
What is mounting?
</summary>

[Mounting](https://man7.org/linux/man-pages/man8/mount.8.html) adds a new filesystem to the file tree allowing access.
</details>

#### nfsShares (optional)

`nfsShares` expects a list of folder paths to share over the network using nfs.
Expand Down Expand Up @@ -263,10 +231,14 @@ workerInstance:
features: # optional
- hasdatabase
- holdsinformation
bootVolume: False
bootFromVolume: True
terminateBootVolume: True
bootVolumeSize: 50
volumes:
- mountPoint: /vol/test
size: 50
fstype: ext4
bootVolume:
name: False
terminate: True
size: 50
```

- `type` sets the instance's hardware configuration.
Expand All @@ -279,7 +251,6 @@ workerInstance:
- `bootFromVolume` (optional:False) if True, the instance will boot from a volume created for this purpose.
- `terminateBootVolume` (optional:True) if True, the boot volume will be terminated when the server is terminated.
- `bootVolumeSize` (optional:50) if a boot volume is created, this sets its size.

##### Find your active `images`

```commandline
Expand Down
Loading

0 comments on commit d989d73

Please sign in to comment.