Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
33 changes: 29 additions & 4 deletions HACKING/docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,13 @@ services:
networks:
- proxstar
restart: always
develop:
watch:
- action: sync+restart
path: ../proxstar
target: /opt/proxstar/proxstar
ignore:
- __pycache__

proxstar-postgres:
build:
Expand All @@ -13,7 +20,7 @@ services:
ports:
- "5432:5432"
volumes:
- ./proxstar-postgres/volume:/var/lib/postgresql/data:Z
- proxstar-postgres:/var/lib/postgresql/data:Z
networks:
- proxstar
restart: always
Expand All @@ -26,6 +33,13 @@ services:
networks:
- proxstar
restart: always
develop:
watch:
- action: sync+restart
path: ../proxstar
target: /opt/proxstar/proxstar
ignore:
- __pycache__

proxstar-rq:
build:
Expand All @@ -35,16 +49,27 @@ services:
networks:
- proxstar
restart: always
develop:
watch:
- action: sync+restart
path: ../proxstar
target: /opt/proxstar/proxstar
ignore:
- __pycache__


proxstar:
build:
context: ..
ports:
- "8000:8000"
- "8001:8001"
- "8080:8080"
- "8081:8081"
env_file: .env
entrypoint: ["gunicorn", "proxstar:app", "--bind=0.0.0.0:8000"]
entrypoint: ["gunicorn", "proxstar:app", "--bind=0.0.0.0:8080"]
networks:
- proxstar
networks:
proxstar:

volumes:
proxstar-postgres:
4 changes: 4 additions & 0 deletions proxstar/proxmox.py
Original file line number Diff line number Diff line change
Expand Up @@ -71,3 +71,7 @@ def get_pools(proxmox, db):
pools.append(poolid)
pools = sorted(pools)
return pools

def get_task_status(proxmox, task_id):
node_name = task_id.split(':')[1]
return proxmox.nodes(node_name).tasks(task_id).status().get()
1 change: 1 addition & 0 deletions proxstar/starrs.py
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,7 @@ def register_starrs(starrs, name, owner, mac, addr):
c.execute('BEGIN')
c.callproc('api.initialize', ('root',))
c.callproc('api.modify_system', (name, 'comment', f'Owned by {owner}'))
c.callproc('api.modify_system', (name, 'type', 'Virtual Machine'))
c.execute('COMMIT')
except Exception as e:
logging.exception(e)
Expand Down
24 changes: 21 additions & 3 deletions proxstar/tasks.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
get_template,
)
from proxstar.mail import send_vm_expire_email, send_rtp_vm_delete_email
from proxstar.proxmox import connect_proxmox, get_pools
from proxstar.proxmox import connect_proxmox, get_pools, get_task_status
from proxstar.starrs import get_next_ip, register_starrs, delete_starrs
from proxstar.user import User, get_vms_for_rtp
from proxstar.vm import VM, clone_vm, create_vm
Expand Down Expand Up @@ -69,17 +69,26 @@ def create_vm_task(user, name, cores, memory, disk, iso): # pylint: disable=too
starrs = connect_starrs()
logging.info('[{}] Creating VM.'.format(name))
set_job_status(job, 'creating VM')
vmid = create_vm(proxmox, user, name, cores, memory, disk, iso)
vmid, task_id = create_vm(proxmox, user, name, cores, memory, disk, iso)
logging.info('[{}] Waiting until Proxmox is done provisioning.'.format(name))
set_job_status(job, 'waiting for Proxmox')
timeout = 20
retry = 0
while retry < timeout:
status = get_task_status(proxmox, task_id)

if status['status'] == 'stopped' and status['exitstatus'] != 'OK':
logging.warning('Failed to provision, error code is {}'.format(status['exitstatus']))

@datadog-computersciencehouse datadog-computersciencehouse Bot Nov 7, 2026 •

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Low: Code Quality Violation

do not use format with logging (...read more)

Avoid using format string with the format method when logging information.

Helpful? 👍/👎 View in Datadog  Leave us feedback  Documentation
🚩 Report as false positive. Flags the rule for review to improve detection accuracy.

set_job_status(job, 'Failed to provision, error code is {}'.format(status['exitstatus']))
delete_vm_task(vmid)
return

if not VM(vmid).is_provisioned():
retry += 1
time.sleep(3)
continue
break

if retry == timeout:
logging.info('[{}] Failed to provision, deleting.'.format(name))
set_job_status(job, 'failed to provision')
Expand Down Expand Up @@ -190,17 +199,26 @@ def setup_template_task(
get_template(db, template_id)
logging.info('[{}] Cloning template {}.'.format(name, template_id))
set_job_status(job, 'cloning template')
vmid = clone_vm(proxmox, template_id, name, user)
vmid, task_id = clone_vm(proxmox, template_id, name, user)
logging.info('[{}] Waiting until Proxmox is done provisioning.'.format(name))
set_job_status(job, 'waiting for Proxmox')
timeout = 25
retry = 0
while retry < timeout:
status = get_task_status(proxmox, task_id)

if status['status'] == 'stopped' and status['exitstatus'] != 'OK':
logging.warning('Failed to provision, error code is {}'.format(status['exitstatus']))

@datadog-computersciencehouse datadog-computersciencehouse Bot Nov 7, 2026 •

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Low: Code Quality Violation

do not use format with logging (...read more)

Avoid using format string with the format method when logging information.

Helpful? 👍/👎 View in Datadog  Leave us feedback  Documentation
🚩 Report as false positive. Flags the rule for review to improve detection accuracy.

set_job_status(job, 'Failed to provision, error code is {}'.format(status['exitstatus']))
delete_vm_task(vmid)
return

if not VM(vmid).is_provisioned():
retry += 1
time.sleep(12)
continue
break

if retry == timeout:
logging.info('[{}] Failed to provision, deleting.'.format(name))
set_job_status(job, 'failed to provision')
Expand Down
9 changes: 5 additions & 4 deletions proxstar/vm.py
Original file line number Diff line number Diff line change
Expand Up @@ -377,7 +377,7 @@ def create_vm(proxmox, user, name, cores, memory, disk, iso): # pylint: disable
vmid = get_free_vmid(proxmox)
# Make sure lingering expirations are deleted
delete_vm_expire(db, vmid)
node.qemu.create(
task_id = node.qemu.create(
vmid=vmid,
name=name,
cores=cores,
Expand All @@ -389,7 +389,7 @@ def create_vm(proxmox, user, name, cores, memory, disk, iso): # pylint: disable
pool=user,
description='Managed by Proxstar',
)
return vmid
return vmid, task_id


# Will clone a new VM from a template, does not guarantee the
Expand All @@ -400,7 +400,8 @@ def clone_vm(proxmox, template_id, name, pool):
# Make sure lingering expirations are deleted
delete_vm_expire(db, vmid)
target = get_node_least_mem(proxmox)
node.qemu(template_id).clone.post(
task_id = node.qemu(template_id).clone.post(
newid=vmid, name=name, pool=pool, full=1, description='Managed by Proxstar', target=target
)
return vmid

return vmid, task_id
2 changes: 1 addition & 1 deletion requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ flask-pyoidc==3.14.3
gunicorn==23.0.0
markupsafe==3.0.2
paramiko==2.11.0
proxmoxer==2.2.0
proxmoxer==2.3.0
psutil==7.0.0
psycopg2-binary==2.9.10
python-dateutil==2.9.0
Expand Down
Loading