From b79dbe47080aa2ad7176c23a38e1a66d068bfb66 Mon Sep 17 00:00:00 2001 From: Mario Date: Sun, 4 Aug 2024 23:24:04 +0200 Subject: [PATCH] Add stop/start and state for vps --- .../__pycache__/vps_server.cpython-39.pyc | Bin 4835 -> 6902 bytes ow_vm_management/models/vps_server.py | 62 ++++++++++++++++++ ow_vm_management/views/vps_server_views.xml | 5 ++ 3 files changed, 67 insertions(+) diff --git a/ow_vm_management/models/__pycache__/vps_server.cpython-39.pyc b/ow_vm_management/models/__pycache__/vps_server.cpython-39.pyc index 3e16b155552e2b071747be280391e465beae00d3..2f951722374a8a065618fc37be84f591f8ee5b14 100644 GIT binary patch delta 3223 zcmcImO>7&-72er@QY7_b#rm~GS%0Qui?ZV)PHQ`M6U%W^D}t#w2$Pmrb4C&=YL}W_ z+LB6!MkF*qfuJ!4Ii)G2qL%;$nj%FHEeiD9L(yJ(7!*i=Tyw}N2O&uN-je#GU9^XW z#D4SU&6~IL{^srH<6nIz;l$%n1%6{+{$}Ch(T9mYk~bgz>z!H4%6fo$)2Di^yHS39ipRj z48~zPPA6bY(n)#>#u1vLr(rxvpQdME9A*8*u~7S2I<;kQj+5+oI8D=Oc-cfqpQGo2 zo_t5qmF%gElDhE8=i~y(rL>ePEnacmg1eZtZZ`H2^dd+4^kSpVUQMO3r?jJaP*Am(LOVd0dYcntv$Lp2oyhoU?La*DZ-B<-MX)Q5_GVV(qS<<}6cwu3EV`z?hYb)Mb5_Ts!TdgoZNG>>q5~JTuj{B)D z@#nVTL8(=ENt)abc%dv~pg9-dtH9S%w8!44Tg|PqgF6MEg#KHR>l(_1XOCEH5Cn`D$NxJW>IM~mzKSP8%Uixfg`PQwtPV4Ic%){1hs; zd7b%X&-IxktTiz@a?P!|<`E}hi;vl(5Sy4Jrgr~J*Ai+%RY^B+qNIy#^xv7wWEck@ zO|@>%6WrSTVS+{AsfSth1E8wPi^`8K)<~5U72ZXOt5UV5;;ftmBsC544)O~!3-SoE zNdq)LG@M9%JdUU1aNdNZtHD~LC(YzWRi!Oot?>}<#$u@svP)^-@o zH-QLC`}Pw{yZ&El8~Y2j`V?xz6IoXI9F4%u5UrA&wyKBK-Zpz+yVP!6pFc?F-S$1( z^A*mS8}Mi0IMQrhurauQ6dngw>aprKP==+9gSzK0f?%WOUq`Y4Ki0cocos;O!{=MO2Wyc+mFz8zX!Ibz+-1Xi|r6Rctvt zg>V|-X@oNfXA!0l(g@Q4Qd?vJKaW#vgW{*Lv*eEWUF_VM(9!%ET*1?(`Wg|shzz`M z8-_JvB_`rm$t|%MKTERW{rDJpUHlb9|P0>h3HQFOjT|1%fv&{ zC8pcYO?3kwKDqGzm-;=Y1Wd5=@xyRQbzhyMiNZ{p|e) zz$aW4`3-&iE#zyQ`K`Jhz`{SoOh=KdiQje%TnaVfNe<~VD{iUaE<-@W-h@|atC~&V z{ZrVTBRZK)rNrsZSC$rmCG~l>7H|)DlyPp|bOW}?IA6kLr7vb<<}8r5N;s6gn%W(?*m9<1-f%7 z^dNtLTs*jp=W_Xy(IX90lFm8pfMFoenhlzpOrF{v`RVlG6_~{ZBb}uw>8~^IR0cgqOc>n+a delta 1148 zcmZ8gUuYaf7~i?wy<5XwdR}gGdzU|VDXH~r)3sG;i#8geiFv3ET7_<{=jLYavdP`- z=G(dSaww%V7!V&!2SG}e7GDLCK8k%;@Kt1<#J&~^KKM{5IJ3btWQYCn{h9f``F-Cv z|GxI{$grQw4QcZG_0f+lx3V+*Gb--<_RB}xS_|PKwzn*=M4Y>2Jc>*AQrN-eE$t@q zD!78jwlr^yIIH8y-f=v!Wl7IOqD|teJUN-jH9RHd>b7QRUhRFYe)#^e)T@X;(El=X zGO@$IH-0!XDkUf>NGmWU)Dh&BT-*a&N+R0`X>-M=ZPEzv1m8BN`FgH`X8D)7WpwBM z7_Gk)XwZ&8_73ujHC#|-$@!gTonO)K&t zmK3AQ{B~g(9pO(4r=Js<59k^VuTg$>grn2^_mMYIjXzFTUw&3L*ej*bd(aVSkQsu= z%SsLnrs&DKdHki!m2tgIn8<@4$V9CW8oP9ap@{N!aR$A}zb>Af6Z!YZdXL2He7{K| zRV}Ei{*;scc$o;oemCq3YuT59WKNinZZEUZZLrOVK#BiTd<#|iEA|YU;l4eMj`Pp$ zqlW|{`F5s1-YT6uF|3m5Nitz<_?=jCBFzvm6r^W2gc=RF zD&ZDyl%j=(Qm;s;8<16UMuIS}LBI%ntn9n-;1gxnfy4)6ElbBYeAHP*9>3v?y^%yz zH`y02-J_j=uGLe!gX$~qfh!Sd`;PzVOra_M)VX+lUh2ZQMEVTgRogErJ+nv|X%m12 zrJ3`c&}ZUk5nKc3IiXt{mEqDvzas zA_jz`%E-dAkxOo!)KC>l{qb=L7Bb|rQh7AIZxv9Yr?Tb{8ZxYicPq2U-d15}6}%up Tm=}_iD$>3lCkbu-N2T^3`wSvX diff --git a/ow_vm_management/models/vps_server.py b/ow_vm_management/models/vps_server.py index 7089ba7..ade2aa4 100644 --- a/ow_vm_management/models/vps_server.py +++ b/ow_vm_management/models/vps_server.py @@ -20,6 +20,11 @@ class VPSServer(models.Model): proxmox_server_id = fields.Many2one('proxmox.server', string='Proxmox Server', tracking=True) ct_id = fields.Integer(string='CT ID (LXC)', tracking=True) vm_id = fields.Integer(string='VM ID (QEMU)', tracking=True) + state = fields.Selection([ + ('running', 'Running'), + ('stopped', 'Stopped'), + ('unknown', 'Unknown') + ], string='State', default='unknown', tracking=True) def _compute_access_url(self): super()._compute_access_url() @@ -31,6 +36,61 @@ class VPSServer(models.Model): if self.ct_id and self.vm_id: raise UserError(_("Please provide either CT ID or VM ID, not both.")) + def _proxmox_request(self, method, endpoint, data=None): + self.ensure_one() + proxmox = self.proxmox_server_id + base_url = proxmox.url.rstrip('/') + headers = { + "Authorization": f"PVEAPIToken={proxmox.api_token_id}={proxmox.api_token_secret}" + } + url = f"{base_url}/api2/json/{endpoint}" + + urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning) + + try: + response = requests.request(method, url, headers=headers, json=data, verify=False) + response.raise_for_status() + return response.json() + except requests.exceptions.RequestException as e: + raise UserError(_("Proxmox API request failed: %s") % str(e)) + + def action_start(self): + for server in self: + vm_type = 'lxc' if server.ct_id else 'qemu' + vm_id = server.ct_id or server.vm_id + self._proxmox_request('POST', f'nodes/pve/{vm_type}/{vm_id}/status/start') + self.fetch_state() + + def action_shutdown(self): + for server in self: + vm_type = 'lxc' if server.ct_id else 'qemu' + vm_id = server.ct_id or server.vm_id + self._proxmox_request('POST', f'nodes/pve/{vm_type}/{vm_id}/status/shutdown') + self.fetch_state() + + def action_stop(self): + for server in self: + vm_type = 'lxc' if server.ct_id else 'qemu' + vm_id = server.ct_id or server.vm_id + self._proxmox_request('POST', f'nodes/pve/{vm_type}/{vm_id}/status/stop') + self.fetch_state() + + def action_reboot(self): + for server in self: + vm_type = 'lxc' if server.ct_id else 'qemu' + vm_id = server.ct_id or server.vm_id + self._proxmox_request('POST', f'nodes/pve/{vm_type}/{vm_id}/status/reboot') + self.fetch_state() + + def fetch_state(self): + for server in self: + vm_type = 'lxc' if server.ct_id else 'qemu' + vm_id = server.ct_id or server.vm_id + status = self._proxmox_request('GET', f'nodes/pve/{vm_type}/{vm_id}/status/current') + server.state = 'running' if status['data']['status'] == 'running' else 'stopped' + + + def action_fetch_proxmox_data(self): self.ensure_one() if not self.proxmox_server_id: @@ -129,6 +189,8 @@ class VPSServer(models.Model): else: # QEMU self.os = config_data.get('ostype', 'Unknown') + self.fetch_state() + return { 'type': 'ir.actions.client', 'tag': 'display_notification', diff --git a/ow_vm_management/views/vps_server_views.xml b/ow_vm_management/views/vps_server_views.xml index c062d36..fcd44a5 100644 --- a/ow_vm_management/views/vps_server_views.xml +++ b/ow_vm_management/views/vps_server_views.xml @@ -6,7 +6,12 @@
+