def create(self) -> list[MachineModel] | None:
image = self.image(self.layout.runs_on)
if not image and not self.layout.username:
raise ProvisionException(
f"Could not locate AMI and/or username for: {self.layout.runs_on}"
)
size = self.sizes(self.layout.instance_size)[0]
ex_metadata = {
"items": [
{
"key": "ssh-keys",
"value": "%s: %s"
% (
self.layout.username,
Path(self.layout.ssh_public_key)
.expanduser()
.read_text()
.strip(),
),
},
{
"key": "startup-script",
"value": self._userdata()
if "windows" not in self.layout.runs_on
else "",
},
]
}
if self.layout.ports:
self.create_firewall(self.layout.name, self.layout.ports, self.layout.tags)
now = datetime.datetime.utcnow().strftime("created-%Y-%m-%d")
if self.layout.tags:
self.layout.tags.append(now)
self.layout.tags.append(f"user-{os.environ.get('USER', 'ogc')}")
# Store some extra metadata similar to what other projects use
self.layout.tags.append("environment-ogc")
self.layout.tags.append("repo-ogc")
suffix = str(uuid.uuid4())[:4]
opts = dict(
base_name=f"ogc-{self.layout.name}-{suffix}",
image=image,
size=size,
number=self.layout.scale,
ex_metadata=ex_metadata,
ex_tags=self.layout.tags,
ex_labels=self.layout.labels,
ex_disk_type="pd-ssd",
ex_disk_size=100,
ex_preemptible=os.environ.get("OGC_DISABLE_SPOT", True),
)
_nodes = self.provisioner.ex_create_multiple_nodes(**opts) # type: ignore
_machines = []
for node in _nodes:
state_file_p = db.cache_path() / node.id
state_file_p.write_bytes(db.model_as_pickle(node))
machine = MachineModel(
layout=self.layout,
instance_name=node.name,
instance_id=node.id,
instance_state=node.state,
public_ip=node.public_ips[0],
private_ip=node.private_ips[0],
remote_state_file=(db.cache_path() / node.id).resolve(),
)
machine.save()
_machines.append(machine)
return _machines