Skip to content

Commit 8613035

Browse files
author
Ritu Agarwal
committed
Merge remote-tracking branch 'nl_pypowervm1/develop'
publishing latest pypowervm code
2 parents 9cd50bc + 0bcee2f commit 8613035

29 files changed

+504
-124
lines changed

.gitreview

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,3 @@
11
[gerrit]
2-
host=rchgit01.rchland.ibm.com
3-
port=29422
42
project=powervm/pypowervm.git
5-
defaultbranch=hotfix/1.1.33.1
3+
defaultbranch=develop

debian/compat

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
9
1+
10

debian/control

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,13 @@ Source: pypowervm
22
Section: python
33
Priority: optional
44
Maintainer: Eric P. Fried <efried@us.ibm.com>
5-
Build-Depends: debhelper(>= 9)
6-
Standards-Version: 3.9.7
5+
Build-Depends: debhelper(>= 10)
6+
Standards-Version: 3.11
77
Homepage: http://github.com/powervm/pypowervm
88

99
Package: pypowervm
1010
Section: python
1111
Priority: optional
1212
Architecture: all
13-
Depends: ${shlibs:Depends}, ${misc:Depends}, python3.9, linuxvnc(>=0.9.9), python39-lxml, python3-oslo.i18n, python3-oslo.log , python3-oslo.utils , python3-pbr , python39-pyasn1-modules , python3-pyasn1 , python3-requests , python3-six , python3-oslo.concurrency , python3-tz, python3-future, python3-taskflow , python3-oslo.context , python3-pyrsistent , python3-zipp, python39-decorator, python39-fasteners, python39-netifaces, python3-dateutil, python3-jsonschema, python3-monotonic
13+
Depends: ${shlibs:Depends}, ${misc:Depends}, python3.11, linuxvnc(>=0.9.9), python311-lxml, python3-oslo.i18n, python3-oslo.log, python3-oslo.utils, python3-pbr, python311-pyasn1-modules, python3-pyasn1, python3-requests, python3-six, python3-oslo.concurrency, python3-tz, python3-future, python3-taskflow, python3-oslo.context, python3-pyrsistent, python3-zipp, python3-decorator, python3-fasteners, python311-netifaces, python3-dateutil, python3-jsonschema, python3-monotonic, python311-certifi, python3-oslo.config, python3-wrapt, python3-argcomplete, python3-distutils, python3-prettytable, libxslt-dev, python3-networkx
1414
Description: Python API wrapper for PowerVM

debian/rules

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,13 +3,13 @@
33
PACKAGE=pypowervm
44

55
%:
6-
dh $@ --with python3.9
6+
dh $@ --with python3.11
77

88
override_dh_auto_install:
9-
python3.9 setup.py install --root=debian/pypowervm --install-layout=deb --install-lib=/usr/lib/`py3versions -d`/dist-packages/ --install-scripts=/usr/lib/`py3versions -d`/dist-packages/ ; \
9+
python3.11 setup.py install --root=debian/pypowervm --install-layout=deb --install-lib=/usr/lib/python3.11/dist-packages/ --install-scripts=/usr/lib/python3.11/dist-packages/ ; \
1010
for lc in $$(ls -d pypowervm/locale/*/ | cut -f3 -d'/'); do \
1111
mkdir -p debian/pypowervm/usr/share/locale/$$lc/LC_MESSAGES ; \
12-
python3 setup.py compile_catalog -f --input-file pypowervm/locale/$$lc/pypowervm.po --output-file debian/pypowervm/usr/share/locale/$$lc/LC_MESSAGES/pypowervm.mo; \
12+
python3.11 setup.py compile_catalog -f --input-file pypowervm/locale/$$lc/pypowervm.po --output-file debian/pypowervm/usr/share/locale/$$lc/LC_MESSAGES/pypowervm.mo; \
1313
done
1414

1515
override_dh_clean:

pypowervm/adapter.py

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -186,7 +186,7 @@ def __init__(self, host='localhost', username=None, password=None,
186186

187187
def __del__(self):
188188
# Refuse to clean up clones.
189-
if self._init_by != id(self):
189+
if not hasattr(self, '_init_by') or self._init_by != id(self):
190190
return
191191

192192
try:
@@ -568,7 +568,6 @@ def _logoff(self):
568568
self.request('DELETE', c.LOGON_PATH, relogin=False)
569569
except Exception:
570570
LOG.exception(_('Problem logging off. Ignoring.'))
571-
572571
self._logged_in = False
573572
# this should only ever be called when Session has gone out of
574573
# scope, but just in case someone calls it directly while requests
@@ -753,6 +752,10 @@ def read(self, root_type, root_id=None, child_type=None, child_id=None,
753752
"""
754753
self._validate('read', root_type, root_id, child_type, child_id,
755754
suffix_type, suffix_parm, detail)
755+
if child_type == 'GetDPOStatus':
756+
import pypowervm.tasks.dpo as dpot
757+
vals = dpot.dpo_objects()
758+
return vals
756759
path = self.build_path(service, root_type, root_id, child_type,
757760
child_id, suffix_type, suffix_parm, detail,
758761
xag=xag, add_qp=add_qp, topology=topology)

pypowervm/exceptions.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -451,3 +451,7 @@ class AttributeInvalidForAixLinux(AbstractMsgFmtError):
451451
class InvalidKVMMemoryOverHeadValue(AbstractMsgFmtError):
452452
msg_fmt = _("The attribute kvm memory overhead value is not valid."
453453
"It should be in range 0.0-100.0.")
454+
455+
456+
class InvalidAffinityScore(AbstractMsgFmtError):
457+
msg_fmt = _("The value for minimum affinity score should be between 0 to 100.")

pypowervm/tasks/dpo.py

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
# Copyright 2015, 2018 IBM Corp.
2+
#
3+
# All Rights Reserved.
4+
#
5+
# Licensed under the Apache License, Version 2.0 (the "License"); you may
6+
# not use this file except in compliance with the License. You may obtain
7+
# a copy of the License at
8+
#
9+
# http://www.apache.org/licenses/LICENSE-2.0
10+
#
11+
# Unless required by applicable law or agreed to in writing, software
12+
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
13+
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
14+
# License for the specific language governing permissions and limitations
15+
# under the License.
16+
17+
"""Tasks specific to DPO (LPARs and VIOSes)."""
18+
import json
19+
from oslo_log import log as logging
20+
import pypowervm.adapter as adp
21+
import pypowervm.const as c
22+
from pypowervm.wrappers import dpo as dpo_w
23+
from pypowervm.wrappers import entry_wrapper as ew
24+
from pypowervm.wrappers import job
25+
from pypowervm.wrappers import managed_system as pvm_ms
26+
27+
28+
LOG = logging.getLogger(__name__)
29+
30+
31+
def dpo_job():
32+
adap = adp.Adapter()
33+
# Build up the job & invoke
34+
ms_uuid = pvm_ms.System.get(adap)[0].uuid
35+
36+
resp = adap.read(
37+
pvm_ms.System.schema_type, root_id=ms_uuid,
38+
suffix_type=c.SUFFIX_TYPE_DO, suffix_parm='GetDPOStatus')
39+
job_w = job.Job.wrap(resp.entry)
40+
41+
try:
42+
job_w.run_job(ms_uuid, job_parms=None)
43+
job_result = job_w.get_job_results_message()
44+
lpars = json.loads(job_result)
45+
return lpars
46+
except Exception:
47+
LOG.exception('DPO Job failed')
48+
raise
49+
50+
51+
def dpo_objects():
52+
vals = dpo_job()
53+
dposob = []
54+
for dpo in vals:
55+
id = dpo.get("LPAR_ID")
56+
vm = dpo.get("LPAR_NAME")
57+
affinity = dpo.get("CURRENT_AFFINITY_SCORE")
58+
dpoob = dpo_w.DPO.bld(ew.EntryWrapper.adapter,
59+
id, vm, affinity)
60+
dposob.append(dpoob)
61+
return dposob

pypowervm/tasks/vterm.py

Lines changed: 31 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,7 @@ def _close_vterm_local(adapter, lpar_uuid):
9898
:param lpar_uuid: partition uuid
9999
"""
100100
lpar_id = _get_lpar_id(adapter, lpar_uuid)
101+
LOG.info("Invokling rmvterm for lpar id %s" % lpar_id)
101102
_run_proc(['rmvterm', '--id', lpar_id])
102103

103104
# Stop the port.
@@ -182,7 +183,7 @@ def _run_mkvterm_cmd(lpar_uuid, force, codepage=codepage):
182183
def open_remotable_vnc_vterm(
183184
adapter, lpar_uuid, local_ip, remote_ips=None, vnc_path=None,
184185
use_x509_auth=False, ca_certs=None, server_cert=None, server_key=None,
185-
force=False, codepage="037"):
186+
force=False, codepage="037", vterm_timeout=300):
186187
"""Opens a VNC vTerm to a given LPAR. Wraps in some validation.
187188
188189
Must run on the management partition.
@@ -266,8 +267,8 @@ def open_remotable_vnc_vterm(
266267
if remote_port not in _VNC_REMOTE_PORT_TO_LISTENER or listen != 0:
267268
LOG.info("Trying VNCSocket Listener")
268269
listener = _VNCSocketListener(
269-
adapter, remote_port, local_ip, verify_vnc_path,
270-
remote_ips=remote_ips)
270+
adapter, lpar_uuid, remote_port, local_ip, verify_vnc_path,
271+
vterm_timeout, remote_ips=remote_ips)
271272
# If we are doing x509 Authentication, then setup the certificates
272273
if use_x509_auth:
273274
listener.set_x509_certificates(
@@ -336,8 +337,8 @@ class _VNCSocketListener(threading.Thread):
336337
and setup a repeater to forward the data between the two sides.
337338
"""
338339

339-
def __init__(self, adapter, remote_port, local_ip, verify_vnc_path,
340-
remote_ips=None):
340+
def __init__(self, adapter, lpar_uuid, remote_port, local_ip, verify_vnc_path,
341+
vterm_timeout, remote_ips=None):
341342
"""Creates the listener bound to a remote-accessible port.
342343
343344
:param adapter: The pypowervm adapter
@@ -354,11 +355,13 @@ def __init__(self, adapter, remote_port, local_ip, verify_vnc_path,
354355
super(_VNCSocketListener, self).__init__()
355356

356357
self.adapter = adapter
358+
self.lpar_uuid = lpar_uuid
357359
self.remote_port = remote_port
358360
self.local_ip = local_ip
359361
self.verify_vnc_path = verify_vnc_path
360362
self.remote_ips = remote_ips
361363
self.x509_certs = None
364+
self.vterm_timeout = vterm_timeout
362365

363366
self.alive = True
364367
self.vnc_killer = None
@@ -480,7 +483,10 @@ def _setup_forwarding_socket(self, lpar_uuid, client_socket):
480483
# socket.
481484

482485
fwd = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
483-
fwd.connect(('127.0.0.1', local_port))
486+
if fwd.connect_ex(('127.0.0.1', local_port)) != 0:
487+
LOG.exception(_("Port %s is not listening "
488+
"maybe VNC is down "), local_port)
489+
return
484490

485491
# If we were told to enable VeNCrypt using X509 Authentication, do so
486492
if self.x509_certs is not None:
@@ -495,7 +501,8 @@ def _setup_forwarding_socket(self, lpar_uuid, client_socket):
495501
# See if we need to start up a new repeater for the given local port
496502
if local_port not in _VNC_LOCAL_PORT_TO_REPEATER:
497503
_VNC_LOCAL_PORT_TO_REPEATER[local_port] = _VNCRepeaterServer(
498-
self.adapter, lpar_uuid, local_port, client_socket, fwd)
504+
self.adapter, lpar_uuid, local_port, client_socket, fwd,
505+
vterm_timeout=self.vterm_timeout)
499506
_VNC_LOCAL_PORT_TO_REPEATER[local_port].start()
500507
else:
501508
repeater = _VNC_LOCAL_PORT_TO_REPEATER[local_port]
@@ -510,6 +517,7 @@ def _enable_x509_authentication(self, client_socket, server_socket):
510517
if there is an error.
511518
"""
512519
try:
520+
LOG.info("--> _enable_x509_authentication %s" % self.lpar_uuid)
513521
# First perform the RFB Version negotiation between client/server
514522
self._version_negotiation(client_socket, server_socket)
515523
# Next perform the Security Authentication Type Negotiation
@@ -522,6 +530,7 @@ def _enable_x509_authentication(self, client_socket, server_socket):
522530
ca_certs = self.x509_certs.get('ca_certs')
523531
server_key = self.x509_certs.get('server_key')
524532
server_cert = self.x509_certs.get('server_cert')
533+
LOG.info("<-- _enable_x509_authentication %s" % self.lpar_uuid)
525534
return ssl.wrap_socket(
526535
client_socket, server_side=True, ca_certs=ca_certs,
527536
certfile=server_cert, keyfile=server_key,
@@ -540,13 +549,15 @@ def _version_negotiation(self, client_socket, server_socket):
540549
"""
541550
# Do a pass-thru of the RFB Version negotiation up-front
542551
# The length of the version is 12, such as 'RFB 003.007\n'
552+
LOG.info("--> _version_negotiation %s" % self.lpar_uuid)
543553
client_socket.sendall(self._socket_receive(server_socket, 12))
544554
server_socket.sendall(self._socket_receive(client_socket, 12))
545555
# Since we are doing our own additional authentication
546556
# just tell the server we are doing No Authentication (1) to it
547557
auth_size = self._socket_receive(server_socket, 1)
548558
self._socket_receive(server_socket, six.byte2int(auth_size))
549559
server_socket.sendall(six.int2byte(1))
560+
LOG.info("<-- _version_negotiation %s" % self.lpar_uuid)
550561

551562
def _auth_type_negotiation(self, client_socket):
552563
"""Performs the VeNCrypt Authentication Type Negotiation.
@@ -556,6 +567,7 @@ def _auth_type_negotiation(self, client_socket):
556567
"""
557568
# Do the VeNCrypt handshake next before establishing SSL
558569
# Say we only support VeNCrypt (19) authentication version 0.2
570+
LOG.info("--> into _auth_type_negotiation %s" % self.lpar_uuid)
559571
client_socket.sendall(six.int2byte(1))
560572
client_socket.sendall(six.int2byte(19))
561573
client_socket.sendall(encodeutils.safe_encode("\x00\x02"))
@@ -575,6 +587,7 @@ def _auth_type_negotiation(self, client_socket):
575587
# Tell the Client we have accepted the authentication type
576588
# In this particular case 0 means the type was accepted
577589
client_socket.sendall(six.int2byte(0))
590+
LOG.info("<-- _auth_type_negotiation %s" % self.lpar_uuid)
578591
return True
579592

580593
def _auth_subtype_negotiation(self, client_socket):
@@ -584,6 +597,7 @@ def _auth_subtype_negotiation(self, client_socket):
584597
:return success: Boolean whether the handshake was successful.
585598
"""
586599
# Tell the client the authentication sub-type is x509None (260)
600+
LOG.info("--> into _auth_subtype_negotiation %s" % self.lpar_uuid)
587601
client_socket.sendall(six.int2byte(1))
588602
client_socket.sendall(struct.pack('!I', 260))
589603
subtyp_raw = self._socket_receive(client_socket, 4)
@@ -595,6 +609,7 @@ def _auth_subtype_negotiation(self, client_socket):
595609
# Tell the Client we have accepted the authentication handshake
596610
# In this particular case 1 means the sub-type was accepted
597611
client_socket.sendall(six.int2byte(1))
612+
LOG.info("<-- _auth_subtype_negotiation %s" % self.lpar_uuid)
598613
return True
599614

600615
def _socket_receive(self, asocket, bufsize):
@@ -657,7 +672,7 @@ class _VNCRepeaterServer(threading.Thread):
657672
"""
658673

659674
def __init__(self, adapter, lpar_uuid, local_port, client_socket=None,
660-
local_socket=None):
675+
local_socket=None, vterm_timeout=300):
661676
"""Creates the repeater.
662677
663678
:param adapter: The pypowervm adapter
@@ -676,6 +691,7 @@ def __init__(self, adapter, lpar_uuid, local_port, client_socket=None,
676691
self.local_port = local_port
677692
self.alive = True
678693
self.vnc_killer = None
694+
self.vterm_timeout = vterm_timeout
679695

680696
# Add the connection passed into us to the forwarding list
681697
if client_socket is not None and local_socket is not None:
@@ -703,6 +719,8 @@ def run(self):
703719
# 0, then we know that we're ready to close this.
704720
data = s_input.recv(4096)
705721
if len(data) == 0:
722+
LOG.info("The client connection will be closed "
723+
"since no data is received for %s" % self.lpar_uuid)
706724
self._close_client(s_input)
707725

708726
# Note that we have to break here. We do that because the
@@ -749,7 +767,7 @@ def _close_client(self, s_input):
749767

750768
# If this was the last port, close the local connection
751769
if len(self.peers) == 0:
752-
self.vnc_killer = _VNCKiller(self.adapter, self.lpar_uuid)
770+
self.vnc_killer = _VNCKiller(self.adapter, self.lpar_uuid, vterm_timeout=self.vterm_timeout)
753771
self.vnc_killer.start()
754772

755773

@@ -766,11 +784,12 @@ class _VNCKiller(threading.Thread):
766784
session will be closed out and the memory will be reclaimed.
767785
"""
768786

769-
def __init__(self, adapter, lpar_uuid):
787+
def __init__(self, adapter, lpar_uuid, vterm_timeout=300):
770788
super(_VNCKiller, self).__init__()
771789
self.adapter = adapter
772790
self.lpar_uuid = lpar_uuid
773791
self._abort = False
792+
self.vterm_timeout = vterm_timeout
774793

775794
def abort(self):
776795
"""Call to stop the killer from completing its job."""
@@ -780,11 +799,12 @@ def run(self):
780799
count = 0
781800

782801
# Wait up to 5 minutes to see if any new negotiations came in
783-
while count < 300 and not self._abort:
802+
while count < self.vterm_timeout and not self._abort:
784803
time.sleep(1)
785804
if self._abort:
786805
break
787806
count += 1
788807

789808
if not self._abort:
809+
LOG.info("closing console - rmvterm for lpar id %s" % self.lpar_uuid)
790810
_close_vterm_local(self.adapter, self.lpar_uuid)

0 commit comments

Comments
 (0)