Change in vdsm[master]: multipath: Move all calls to multipath exe to a single method
by smizrahi@redhat.com
Saggi Mizrahi has uploaded a new change for review.
Change subject: multipath: Move all calls to multipath exe to a single method
......................................................................
multipath: Move all calls to multipath exe to a single method
This makes the code a bit cleaner
Change-Id: I52afc07a07a925ed7572eb369deb7c203edb04cd
Signed-off-by: Saggi Mizrahi <smizrahi(a)redhat.com>
---
M vdsm/storage/multipath.py
1 file changed, 11 insertions(+), 4 deletions(-)
git pull ssh://gerrit.ovirt.org:29418/vdsm refs/changes/55/19255/1
diff --git a/vdsm/storage/multipath.py b/vdsm/storage/multipath.py
index 924d747..c31b5c3 100644
--- a/vdsm/storage/multipath.py
+++ b/vdsm/storage/multipath.py
@@ -94,6 +94,10 @@
)
+def _runCmd(args):
+ return misc.execCmd([constants.EXT_MULTIPATH] + args, sudo=True)
+
+
def rescan():
"""
Forces multipath daemon to rescan the list of available devices and
@@ -108,8 +112,8 @@
supervdsm.getProxy().forceScsiScan()
# Now let multipath daemon pick up new devices
- cmd = [constants.EXT_MULTIPATH, "-r"]
- misc.execCmd(cmd, sudo=True)
+
+ _runCmd("-r")
def isEnabled():
@@ -154,6 +158,10 @@
return False
+def flushAll():
+ _runCmd("-F")
+
+
def setupMultipath():
"""
Set up the multipath daemon configuration to the known and
@@ -173,8 +181,7 @@
raise se.MultipathSetupError()
misc.persistFile(MPATH_CONF)
- # Flush all unused multipath device maps
- misc.execCmd([constants.EXT_MULTIPATH, "-F"], sudo=True)
+ flushAll()
cmd = [constants.EXT_VDSM_TOOL, "service-reload", "multipathd"]
rc = misc.execCmd(cmd, sudo=True)[0]
--
To view, visit http://gerrit.ovirt.org/19255
To unsubscribe, visit http://gerrit.ovirt.org/settings
Gerrit-MessageType: newchange
Gerrit-Change-Id: I52afc07a07a925ed7572eb369deb7c203edb04cd
Gerrit-PatchSet: 1
Gerrit-Project: vdsm
Gerrit-Branch: master
Gerrit-Owner: Saggi Mizrahi <smizrahi(a)redhat.com>
7 years, 9 months
Change in vdsm[master]: [WIP]Java Bindings: Proton support in Java Bindings
by smizrahi@redhat.com
Saggi Mizrahi has uploaded a new change for review.
Change subject: [WIP]Java Bindings: Proton support in Java Bindings
......................................................................
[WIP]Java Bindings: Proton support in Java Bindings
Change-Id: I94c52e118cb63d7df84b89a9b93da7b9e477be91
Signed-off-by: Saggi Mizrahi <smizrahi(a)redhat.com>
---
A client/java/vdsm-json-rpc/src/main/java/org/ovirt/vdsm/reactors/ProtonAuthenticator.java
A client/java/vdsm-json-rpc/src/main/java/org/ovirt/vdsm/reactors/ProtonClient.java
A client/java/vdsm-json-rpc/src/main/java/org/ovirt/vdsm/reactors/ProtonListener.java
A client/java/vdsm-json-rpc/src/main/java/org/ovirt/vdsm/reactors/ProtonReactor.java
A client/java/vdsm-json-rpc/src/test/java/org/ovirt/vdsm/jsonrpc/AmqpReactorTestHelper.java
A client/java/vdsm-json-rpc/src/test/java/org/ovirt/vdsm/jsonrpc/TestJsonRpcClientAMQP.java
6 files changed, 844 insertions(+), 0 deletions(-)
git pull ssh://gerrit.ovirt.org:29418/vdsm refs/changes/28/15428/1
diff --git a/client/java/vdsm-json-rpc/src/main/java/org/ovirt/vdsm/reactors/ProtonAuthenticator.java b/client/java/vdsm-json-rpc/src/main/java/org/ovirt/vdsm/reactors/ProtonAuthenticator.java
new file mode 100644
index 0000000..35c9099
--- /dev/null
+++ b/client/java/vdsm-json-rpc/src/main/java/org/ovirt/vdsm/reactors/ProtonAuthenticator.java
@@ -0,0 +1,98 @@
+package org.ovirt.vdsm.reactors;
+
+import java.io.IOException;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+import org.apache.qpid.proton.driver.Connector;
+import org.apache.qpid.proton.engine.Sasl;
+import org.apache.qpid.proton.engine.Sasl.SaslOutcome;
+import org.apache.qpid.proton.engine.Sasl.SaslState;
+import org.ovirt.vdsm.reactors.ProtonAuthenticator.AuthenticatorType;
+
+public final class ProtonAuthenticator {
+
+ public enum AuthenticatorType {
+
+ SERVER, CLIENT
+ }
+
+ public enum ConnectionState {
+
+ AUTHENTICATING, CONNECTED, FAILED
+ }
+ private ConnectionState _state;
+ final private AuthenticatorType _authType;
+ final private Connector<?> _connector;
+
+ public ProtonAuthenticator(Connector<?> connector,
+ AuthenticatorType authType) {
+ _authType = authType;
+ setState(ConnectionState.AUTHENTICATING);
+ _connector = connector;
+ final Sasl sasl = _connector.sasl();
+ if (authType == AuthenticatorType.CLIENT) {
+ sasl.setMechanisms(new String[]{"ANONYMOUS"});
+ sasl.client();
+ }
+ }
+
+ private void setState(ConnectionState state) {
+ _state = state;
+ }
+
+ public ConnectionState getState() {
+ return _state;
+ }
+
+ public void authenticate() {
+ final Sasl sasl = _connector.sasl();
+
+ while (true) {
+ try {
+ this._connector.process();
+ } catch (IOException ex) {
+ return;
+ }
+ final SaslState state = sasl.getState();
+ switch (state) {
+ case PN_SASL_CONF:
+ if (_authType == AuthenticatorType.SERVER) {
+ sasl.setMechanisms(new String[]{"ANONYMOUS"});
+ sasl.server();
+ }
+ break;
+ case PN_SASL_STEP:
+ if (_authType == AuthenticatorType.SERVER) {
+ final String[] mechs = sasl.getRemoteMechanisms();
+ if (mechs.length < 1) {
+ sasl.done(SaslOutcome.PN_SASL_AUTH);
+ break;
+ }
+
+ final String mech = mechs[0];
+ if (mech.equals("ANONYMOUS")) {
+ sasl.done(SaslOutcome.PN_SASL_OK);
+ } else {
+ sasl.done(SaslOutcome.PN_SASL_AUTH);
+ }
+ }
+ return;
+ case PN_SASL_PASS:
+ this.setState(ConnectionState.CONNECTED);
+ return;
+ case PN_SASL_FAIL:
+ this.setState(ConnectionState.FAILED);
+ return;
+ case PN_SASL_IDLE:
+
+ break;
+ default:
+ return;
+ }
+ }
+ }
+
+ public AuthenticatorType getAuthType() {
+ return _authType;
+ }
+}
diff --git a/client/java/vdsm-json-rpc/src/main/java/org/ovirt/vdsm/reactors/ProtonClient.java b/client/java/vdsm-json-rpc/src/main/java/org/ovirt/vdsm/reactors/ProtonClient.java
new file mode 100644
index 0000000..4baffbf
--- /dev/null
+++ b/client/java/vdsm-json-rpc/src/main/java/org/ovirt/vdsm/reactors/ProtonClient.java
@@ -0,0 +1,224 @@
+package org.ovirt.vdsm.reactors;
+
+import java.nio.ByteBuffer;
+import java.util.Calendar;
+import java.util.UUID;
+import java.util.concurrent.Callable;
+import java.util.concurrent.ConcurrentLinkedQueue;
+import java.util.concurrent.Future;
+
+import javax.swing.event.EventListenerList;
+
+import org.apache.qpid.proton.amqp.Binary;
+import org.apache.qpid.proton.amqp.messaging.Data;
+import org.apache.qpid.proton.amqp.messaging.Section;
+import org.apache.qpid.proton.engine.Delivery;
+import org.apache.qpid.proton.engine.EndpointState;
+import org.apache.qpid.proton.engine.Link;
+import org.apache.qpid.proton.engine.Receiver;
+import org.apache.qpid.proton.engine.Sender;
+import org.apache.qpid.proton.engine.Session;
+import org.apache.qpid.proton.message.Message;
+import org.apache.qpid.proton.message.MessageFactory;
+import org.apache.qpid.proton.message.impl.MessageFactoryImpl;
+
+public final class ProtonClient implements ReactorClient {
+ private final ProtonReactor _reactor;
+ final private Session _ssn;
+
+ private Sender _sender;
+ private Receiver _receiver;
+
+ private final int _CREDIT = 10;
+ private final ConcurrentLinkedQueue<ByteBuffer> _outbox;
+ private final EventListenerList _eventListeners;
+ private final int _deliveryTimeoutSec;
+ private final MessageFactory _msgFactory;
+
+ public ProtonClient(ProtonReactor reactor, Session session) {
+ _ssn = session;
+ _sender = null;
+ _receiver = null;
+ _outbox = new ConcurrentLinkedQueue<>();
+ _eventListeners = new EventListenerList();
+ _deliveryTimeoutSec = 60 * 3;
+ _reactor = reactor;
+ _msgFactory = new MessageFactoryImpl();
+ }
+
+ @Override
+ public void addEventListener(EventListener el) {
+ synchronized (_eventListeners) {
+ _eventListeners.add(EventListener.class, el);
+ }
+ }
+
+ @Override
+ public void removeEventListener(EventListener el) {
+ synchronized (_eventListeners) {
+ _eventListeners.remove(EventListener.class, el);
+ }
+ }
+
+ private void emitOnMessageReceived(ByteBuffer message) {
+ synchronized (_eventListeners) {
+ final Class<EventListener> cls = EventListener.class;
+ final EventListener[] els = _eventListeners.getListeners(cls);
+ for (EventListener el : els) {
+ el.onMessageReceived(this, message);
+ }
+ }
+ }
+
+ @Override
+ public void sendMessage(ByteBuffer message) {
+ _outbox.add(message);
+ _reactor.wakeup();
+ }
+
+ public void addLink(Link link) {
+ assert (link.getSession().equals(_ssn));
+
+ if (link instanceof Sender) {
+ if (_sender != null) {
+ // already have a sender
+ link.close();
+ return;
+ }
+
+ _sender = (Sender) link;
+ } else {
+ assert (link instanceof Receiver);
+ if (_receiver != null) {
+ // already have a receiver
+ link.close();
+ return;
+ }
+
+ _receiver = (Receiver) link;
+ _receiver.flow(_CREDIT);
+ }
+ link.open();
+ }
+
+ private Message _popOutgoingMessage() {
+ final ByteBuffer data = _outbox.poll();
+ if (data == null) {
+ return null;
+ }
+
+ final Section body = new Data(Binary.create(data));
+ final Message msg = _msgFactory.createMessage();
+ msg.setBody(body);
+ msg.setAddress(_sender.getTarget().toString());
+ return msg;
+ }
+
+ public void queueDeliveries() {
+ if (_sender == null) {
+ final String uuid = UUID.randomUUID().toString();
+ _sender = _ssn.sender("Sender-" + uuid);
+ }
+
+ while (_sender.getCredit() > 0) {
+ final Message m = _popOutgoingMessage();
+ if (m == null) {
+ return;
+ }
+
+ final String uuid = UUID.randomUUID().toString();
+ final Delivery d = _sender
+ .delivery(("outgoing-" + uuid).getBytes());
+ d.setContext(m);
+ }
+ }
+
+ public void processDelivery(Delivery delivery) {
+ assert (_ssn.equals(delivery.getLink().getSession()));
+
+ if (delivery.isReadable()) {
+ _processIncomingDelivery(delivery);
+ } else {
+ assert (delivery.isWritable());
+ _processOutgoingDelivery(delivery);
+ }
+ }
+
+ private void _processOutgoingDelivery(Delivery delivery) {
+ final Sender link = (Sender) delivery.getLink();
+ assert (link.equals(_sender));
+
+ final Message msg = (Message) delivery.getContext();
+ // TBD: Buffer can be reused forever. Change in case of
+ // performance issues.
+ ByteBuffer buff;
+ int i = 1;
+ int written = 0;
+ do {
+ buff = ByteBuffer.allocate(i * 4096);
+ written = msg.encode(buff.array(), 0, buff.capacity());
+ i++;
+ } while (written == buff.capacity());
+
+ link.send(buff.array(), 0, written);
+ if (link.advance()) {
+ // Attach timeout to the delivery
+ final Calendar calendar = Calendar.getInstance();
+ calendar.add(Calendar.SECOND, _deliveryTimeoutSec);
+ delivery.setContext(calendar);
+ }
+ }
+
+ private void _processIncomingDelivery(Delivery delivery) {
+ int total = 0;
+ int read = 0;
+ ByteBuffer buff = ByteBuffer.allocate(4096);
+
+ while (read >= 0) {
+ total += read;
+ if (total >= buff.capacity()) {
+ final ByteBuffer buff2 = ByteBuffer
+ .allocate(buff.capacity() * 2);
+ buff2.put(buff);
+ buff = buff2;
+ }
+ read = _receiver.recv(buff.array(), total, buff.capacity() - total);
+ }
+
+ final Message msg = _msgFactory.createMessage();
+ msg.decode(buff.array(), 0, total);
+
+ assert (msg.getBody() instanceof Data);
+ final Data body = (Data) msg.getBody();
+ final ByteBuffer bb = body.getValue().asByteBuffer();
+ delivery.settle();
+ emitOnMessageReceived(bb);
+ }
+
+ @Override
+ public Future<Void> close() {
+ final Session ssn = _ssn;
+ return _reactor.queueOperation(new Callable<Void>() {
+ @Override
+ public Void call() {
+ ssn.close();
+ return null;
+ }
+ });
+ }
+
+ @Override
+ public boolean closed() {
+ return _ssn.getLocalState().equals(EndpointState.CLOSED);
+ }
+
+ public void removeLink(Link link) {
+ if (link.equals(_sender)) {
+ _sender = null;
+ } else {
+ assert (link.equals(_receiver));
+ _receiver = null;
+ }
+ link.close();
+ }
+}
diff --git a/client/java/vdsm-json-rpc/src/main/java/org/ovirt/vdsm/reactors/ProtonListener.java b/client/java/vdsm-json-rpc/src/main/java/org/ovirt/vdsm/reactors/ProtonListener.java
new file mode 100644
index 0000000..35896f4
--- /dev/null
+++ b/client/java/vdsm-json-rpc/src/main/java/org/ovirt/vdsm/reactors/ProtonListener.java
@@ -0,0 +1,42 @@
+package org.ovirt.vdsm.reactors;
+
+import java.io.IOException;
+import java.util.concurrent.Callable;
+import java.util.concurrent.Future;
+
+import org.apache.qpid.proton.driver.Listener;
+
+public final class ProtonListener implements ReactorListener {
+ private final EventListener _eventListener;
+ private Listener<ProtonListener> _listener;
+ private final ProtonReactor _reactor;
+
+ public ProtonListener(ProtonReactor reactor, EventListener eventListener) {
+ _eventListener = eventListener;
+ _reactor = reactor;
+ }
+
+ public void setListener(Listener<ProtonListener> l) {
+ _listener = l;
+ }
+
+ public void accept(ReactorClient client) {
+ _eventListener.onAcccept(this, client);
+ }
+
+ @Override
+ public Future<Void> close() {
+ final Listener<ProtonListener> l = _listener;
+ return _reactor.queueOperation(new Callable<Void>() {
+ @Override
+ public Void call() {
+ try {
+ l.close();
+ } catch (IOException e) {
+ // already closed
+ }
+ return null;
+ }
+ });
+ }
+}
diff --git a/client/java/vdsm-json-rpc/src/main/java/org/ovirt/vdsm/reactors/ProtonReactor.java b/client/java/vdsm-json-rpc/src/main/java/org/ovirt/vdsm/reactors/ProtonReactor.java
new file mode 100644
index 0000000..b5a38b4
--- /dev/null
+++ b/client/java/vdsm-json-rpc/src/main/java/org/ovirt/vdsm/reactors/ProtonReactor.java
@@ -0,0 +1,452 @@
+package org.ovirt.vdsm.reactors;
+
+import java.io.IOException;
+import java.util.Calendar;
+import java.util.EnumSet;
+import java.util.Iterator;
+import java.util.concurrent.Callable;
+import java.util.concurrent.Future;
+import java.util.concurrent.FutureTask;
+
+import org.apache.qpid.proton.driver.Connector;
+import org.apache.qpid.proton.driver.Driver;
+import org.apache.qpid.proton.driver.Listener;
+import org.apache.qpid.proton.driver.impl.DriverFactoryImpl;
+import org.apache.qpid.proton.engine.Connection;
+import org.apache.qpid.proton.engine.Delivery;
+import org.apache.qpid.proton.engine.EndpointState;
+import org.apache.qpid.proton.engine.EngineFactory;
+import org.apache.qpid.proton.engine.Link;
+import org.apache.qpid.proton.engine.Receiver;
+import org.apache.qpid.proton.engine.Session;
+import org.apache.qpid.proton.engine.impl.EngineFactoryImpl;
+import org.ovirt.vdsm.reactors.ProtonAuthenticator.AuthenticatorType;
+import org.ovirt.vdsm.reactors.ProtonAuthenticator.ConnectionState;
+import org.ovirt.vdsm.util.ChainedOperation;
+import org.ovirt.vdsm.util.ReactorScheduler;
+
+public final class ProtonReactor implements Reactor {
+
+ private final Driver _driver;
+ private final ReactorScheduler _scheduler;
+ private boolean _isRunning;
+ final Object _syncRoot = new Object();
+ final ProtonReactor reactor = this;
+ private EngineFactory _engineFactory;
+
+ public boolean isRunning() {
+ return _isRunning;
+ }
+
+ public ProtonReactor() throws IOException {
+ _engineFactory = new EngineFactoryImpl();
+ _driver = new DriverFactoryImpl().createDriver();
+ _isRunning = false;
+ _scheduler = new ReactorScheduler();
+ }
+
+ @Override
+ public void finalize() throws Throwable {
+ try {
+ _driver.destroy();
+ } finally {
+ super.finalize();
+ }
+ }
+
+ // Creates a listener, returns null if failed to bind or reactor is not
+ // running;
+ @Override
+ public Future<ReactorListener> createListener(final String host,
+ final int port,
+ final ReactorListener.EventListener eventListener) {
+
+ return queueOperation(new Callable<ReactorListener>() {
+ @Override
+ public ProtonListener call() {
+
+ final ProtonListener listener = new ProtonListener(reactor, eventListener);
+ final Listener<ProtonListener> l = _driver.createListener(host,
+ port, listener);
+
+ listener.setListener(l);
+
+ if (l == null) {
+ return null;
+ }
+
+ return listener;
+ }
+ });
+ }
+
+ @Override
+ public Future<ReactorClient> createClient(final String host, final int port) {
+ final Driver driver = _driver;
+ final EngineFactory engineFactory = _engineFactory;
+
+ return queueOperation(new ChainedOperation.Operation<ReactorClient>() {
+ final private int _INIT = 1;
+ final private int _AUTHENTICATE = 2;
+ final private int _DONE = 3;
+ private int _state;
+ final private Driver _driver;
+ final private ProtonReactor _reactor;
+ private Connector<ProtonAuthenticator> _connector;
+ private ProtonAuthenticator _auth;
+ private boolean _done;
+ private boolean _cancelled;
+ private ReactorClient _result;
+ private EngineFactory _engineFactory;
+
+ {
+ _driver = driver;
+ _reactor = reactor;
+ _state = _INIT;
+ _done = false;
+ _cancelled = false;
+ _engineFactory = engineFactory;
+ }
+
+ @Override
+ public void call(final boolean cancelled) {
+ switch (_state) {
+ case _INIT:
+ if (cancelled) {
+ _cancelled = true;
+ _done = true;
+ return;
+ }
+
+ _connector = this._driver.createConnector(host, port, null);
+
+ final Connection connection = engineFactory.createConnection();
+ _connector.setConnection(connection);
+ _auth = new ProtonAuthenticator(_connector,
+ AuthenticatorType.CLIENT);
+ _connector.setContext(_auth);
+ connection.open();
+ _state = _AUTHENTICATE;
+ case _AUTHENTICATE:
+ if (cancelled) {
+ _cancelled = true;
+ _close();
+ return;
+ }
+
+ switch (_auth.getState()) {
+ case AUTHENTICATING:
+ _auth.authenticate();
+ try {
+ _connector.process();
+ } catch (IOException e) {
+ // ignore
+ }
+ return;
+ case FAILED:
+ _close();
+ return;
+ case CONNECTED:
+ // Success !
+ break;
+ }
+
+ Session ssn = _connector.getConnection().session();
+ ssn.open();
+ _result = new ProtonClient(_reactor, ssn);
+ ssn.setContext(_result);
+ _done = true;
+ _state = _DONE;
+ }
+ }
+
+ private void _close() {
+ _connector.getConnection().close();
+ _connector.close();
+ _done = true;
+ _result = null;
+ }
+
+ @Override
+ public boolean isDone() {
+ return _done;
+ }
+
+ @Override
+ public boolean isCancelled() {
+ return _cancelled;
+ }
+
+ @Override
+ public ReactorClient getResult() {
+ return _result;
+ }
+ });
+ }
+
+ // Queues operation to be run in the serving loop.
+ public <T> Future<T> queueOperation(Callable<T> cb) {
+ final FutureTask<T> task = new FutureTask<>(cb);
+ _queueFuture(task);
+ return task;
+ }
+
+ public <T> Future<T> queueOperation(ChainedOperation.Operation<T> op) {
+ final ChainedOperation<T> task = new ChainedOperation<>(op);
+ _queueFuture(task);
+ return task;
+ }
+
+ private void _queueFuture(Future<?> op) {
+ synchronized (_scheduler) {
+ _scheduler.queueFuture(op);
+ wakeup();
+ }
+ }
+
+ private void _waitEvents() {
+ _driver.doWait(0);
+ }
+
+ public void wakeup() {
+ _driver.wakeup();
+ }
+
+ @Override
+ public void serve() {
+ synchronized (_syncRoot) {
+ _isRunning = true;
+ }
+
+ while (_isRunning) {
+ //_waitEvents();
+ synchronized (_scheduler) {
+ _scheduler.performPendingOperations();
+ }
+ _acceptConnectionRequests();
+ _processConnectors();
+ }
+ }
+
+ private void _processConnectors() {
+ for (Connector<?> connector = _driver.connector(); connector != null; connector = _driver
+ .connector()) {
+ if (connector.isClosed()) {
+ connector.destroy();
+ continue;
+ }
+
+ try {
+ connector.process();
+ } catch (IOException e) {
+ continue;
+ }
+
+ final Object ctx = connector.getContext();
+ assert (ctx instanceof ProtonAuthenticator);
+
+ if (ctx instanceof ProtonAuthenticator) {
+ final ProtonAuthenticator auth = (ProtonAuthenticator) ctx;
+ ConnectionState cs = auth.getState();
+ if (cs.equals(ConnectionState.AUTHENTICATING)) {
+ auth.authenticate();
+ cs = auth.getState();
+ }
+
+ if (cs.equals(ConnectionState.CONNECTED)) {
+ if (connector.getConnection() == null) {
+ connector.setConnection(_engineFactory.createConnection());
+ }
+ _processConnector(connector);
+ }
+ }
+
+ try {
+ connector.process();
+ } catch (IOException e) {
+ continue;
+ }
+ }
+ }
+
+ private void _processConnector(Connector<?> connector) {
+ _initConnection(connector);
+ _openPendingSessions(connector);
+ _openLinks(connector);
+ _queueOutgoingDeliveries(connector);
+ _processDeliveries(connector);
+ _cleanDeliveries(connector);
+ _cleanLinks(connector);
+ _cleanSessions(connector);
+ }
+
+ private void _cleanSessions(Connector<?> connector) {
+ final Connection conn = connector.getConnection();
+ final EnumSet<EndpointState> localState = EnumSet
+ .of(EndpointState.ACTIVE);
+ final EnumSet<EndpointState> remoteState = EnumSet
+ .of(EndpointState.CLOSED);
+
+ for (Session ssn = conn.sessionHead(localState, remoteState); ssn != null; ssn
+ .next(localState, remoteState)) {
+
+ ssn.close();
+ }
+ }
+
+ private void _cleanLinks(Connector<?> connector) {
+ final Connection conn = connector.getConnection();
+ final EnumSet<EndpointState> localState = EnumSet
+ .of(EndpointState.ACTIVE);
+ final EnumSet<EndpointState> remoteState = EnumSet
+ .of(EndpointState.CLOSED);
+
+ for (Link link = conn.linkHead(localState, remoteState); link != null; link = link
+ .next(localState, remoteState)) {
+
+ final ProtonClient ssn = _getClient(link.getSession());
+ ssn.removeLink(link);
+ }
+ }
+
+ private void _cleanDeliveries(Connector<?> connector) {
+ final Connection conn = connector.getConnection();
+ final EnumSet<EndpointState> localState = EnumSet
+ .of(EndpointState.ACTIVE);
+ final EnumSet<EndpointState> remoteState = EnumSet
+ .allOf(EndpointState.class);
+ for (Link link = conn.linkHead(localState, remoteState); link != null; link = link
+ .next(localState, remoteState)) {
+
+ if (link instanceof Receiver) {
+ // We settle all incoming deliveries upon receive
+ continue;
+ }
+
+ Delivery d;
+ final Calendar now = Calendar.getInstance();
+ for (Iterator<Delivery> iter = link.unsettled(); iter.hasNext();) {
+ d = iter.next();
+ Object ctx = d.getContext();
+ if (!(ctx instanceof Calendar)) {
+ // Has not been sent yet
+ continue;
+ }
+
+ final Calendar timeout = (Calendar) ctx;
+ boolean remoteClosed = link.getRemoteState().equals(
+ EndpointState.CLOSED);
+ boolean timedOut = now.after(timeout);
+ if (d.remotelySettled() || timedOut || remoteClosed) {
+ d.settle();
+ d.free();
+ }
+ }
+
+ }
+
+ }
+
+ private void _processDeliveries(Connector<?> connector) {
+ final Connection conn = connector.getConnection();
+ for (Delivery delivery = conn.getWorkHead(); delivery != null; delivery = delivery
+ .getWorkNext()) {
+
+ final ProtonClient client = _getClient(delivery.getLink()
+ .getSession());
+ client.processDelivery(delivery);
+ }
+ }
+
+ private void _queueOutgoingDeliveries(Connector<?> connector) {
+ final Connection conn = connector.getConnection();
+
+ final EnumSet<EndpointState> localState = EnumSet
+ .of(EndpointState.ACTIVE);
+ final EnumSet<EndpointState> remoteState = EnumSet
+ .allOf(EndpointState.class);
+
+ for (Session ssn = conn.sessionHead(localState, remoteState); ssn != null; ssn = ssn
+ .next(localState, remoteState)) {
+
+ final ProtonClient client = _getClient(ssn);
+ client.queueDeliveries();
+ }
+ }
+
+ private void _openLinks(Connector<?> connector) {
+ final Connection conn = connector.getConnection();
+ final EnumSet<EndpointState> localState = EnumSet
+ .of(EndpointState.UNINITIALIZED);
+ final EnumSet<EndpointState> remoteState = EnumSet
+ .allOf(EndpointState.class);
+ for (Link link = conn.linkHead(localState, remoteState); link != null; link = link
+ .next(localState, remoteState)) {
+
+ // configure the link
+ link.setSource(link.getRemoteSource());
+ link.setTarget(link.getRemoteTarget());
+
+ final ProtonClient client = _getClient(link.getSession());
+ client.addLink(link);
+ }
+ }
+
+ private ProtonClient _getClient(Session ssn) {
+ return (ProtonClient) ssn.getContext();
+ }
+
+ private void _openPendingSessions(Connector<?> connector) {
+ final Connection conn = connector.getConnection();
+ final EnumSet<EndpointState> localState = EnumSet
+ .of(EndpointState.UNINITIALIZED);
+ final EnumSet<EndpointState> remoteState = EnumSet
+ .allOf(EndpointState.class);
+
+ for (Session ssn = conn.sessionHead(localState, remoteState); ssn != null; ssn = ssn
+ .next(localState, remoteState)) {
+
+ final ProtonClient client = new ProtonClient(this, ssn);
+ ssn.setContext(client);
+ final Object ctx = connector.getContext();
+ assert (ctx instanceof ProtonAuthenticator);
+ ProtonAuthenticator auth = (ProtonAuthenticator) ctx;
+ if (auth.getAuthType() == AuthenticatorType.SERVER) {
+ ssn.open();
+ final ProtonListener l = (ProtonListener) ctx;
+ l.accept(client);
+ } else {
+ ssn.close();
+ }
+ }
+ }
+
+ private void _initConnection(Connector<?> connector) {
+ final Connection conn = connector.getConnection();
+ if (conn.getLocalState().equals(EndpointState.UNINITIALIZED)) {
+ conn.open();
+ }
+ }
+
+ private void _acceptConnectionRequests() {
+ for (final Listener<?> l : _driver.listeners()) {
+
+ @SuppressWarnings("unchecked")
+ final Connector<ProtonAuthenticator> connector = (Connector<ProtonAuthenticator>) l
+ .accept();
+ if (connector == null) {
+ continue;
+ }
+ connector.setContext(new ProtonAuthenticator(connector,
+ AuthenticatorType.SERVER));
+ }
+ }
+
+ public void stop() {
+ synchronized (_syncRoot) {
+ _isRunning = false;
+ }
+
+ wakeup();
+ }
+}
\ No newline at end of file
diff --git a/client/java/vdsm-json-rpc/src/test/java/org/ovirt/vdsm/jsonrpc/AmqpReactorTestHelper.java b/client/java/vdsm-json-rpc/src/test/java/org/ovirt/vdsm/jsonrpc/AmqpReactorTestHelper.java
new file mode 100644
index 0000000..46d9cc3
--- /dev/null
+++ b/client/java/vdsm-json-rpc/src/test/java/org/ovirt/vdsm/jsonrpc/AmqpReactorTestHelper.java
@@ -0,0 +1,18 @@
+package org.ovirt.vdsm.jsonrpc;
+
+import java.io.IOException;
+import org.ovirt.vdsm.reactors.ProtonReactor;
+import org.ovirt.vdsm.reactors.Reactor;
+
+public class AmqpReactorTestHelper implements ReactorTestHelper {
+ @Override
+ public Reactor createReactor() throws IOException {
+ return new ProtonReactor();
+ }
+
+ @Override
+ public String getUriScheme() {
+ return "amqp";
+ }
+
+}
diff --git a/client/java/vdsm-json-rpc/src/test/java/org/ovirt/vdsm/jsonrpc/TestJsonRpcClientAMQP.java b/client/java/vdsm-json-rpc/src/test/java/org/ovirt/vdsm/jsonrpc/TestJsonRpcClientAMQP.java
new file mode 100644
index 0000000..9e0c24c
--- /dev/null
+++ b/client/java/vdsm-json-rpc/src/test/java/org/ovirt/vdsm/jsonrpc/TestJsonRpcClientAMQP.java
@@ -0,0 +1,10 @@
+package org.ovirt.vdsm.jsonrpc;
+
+public class TestJsonRpcClientAMQP extends TestJsonRpcClient {
+
+ @Override
+ protected ReactorTestHelper getHelper() {
+ return new AmqpReactorTestHelper();
+ }
+
+}
--
To view, visit http://gerrit.ovirt.org/15428
To unsubscribe, visit http://gerrit.ovirt.org/settings
Gerrit-MessageType: newchange
Gerrit-Change-Id: I94c52e118cb63d7df84b89a9b93da7b9e477be91
Gerrit-PatchSet: 1
Gerrit-Project: vdsm
Gerrit-Branch: master
Gerrit-Owner: Saggi Mizrahi <smizrahi(a)redhat.com>
7 years, 9 months
Change in vdsm[master]: gluster: command to create a public key file
by dnarayan@redhat.com
Hello Bala.FA,
I'd like you to do a code review. Please visit
http://gerrit.ovirt.org/17644
to review the following change.
Change subject: gluster: command to create a public key file
......................................................................
gluster: command to create a public key file
This executes the command to create a public key file
which will have public keys of all the hosts of source cluster.
This is needed for password-less communication between
slave cluster hosts during geo-replication
Change-Id: If8c979a89ce11a1622819c474b59dcf088733594
Signed-off-by: ndarshan <dnarayan(a)redhat.com>
---
M vdsm/gluster/cli.py
M vdsm/gluster/exception.py
2 files changed, 20 insertions(+), 0 deletions(-)
git pull ssh://gerrit.ovirt.org:29418/vdsm refs/changes/44/17644/1
diff --git a/vdsm/gluster/cli.py b/vdsm/gluster/cli.py
index bac6d1c..64529ae 100644
--- a/vdsm/gluster/cli.py
+++ b/vdsm/gluster/cli.py
@@ -897,3 +897,12 @@
return _parseVolumeProfileInfo(xmltree, nfs)
except _etreeExceptions:
raise ge.GlusterXmlErrorException(err=[etree.tostring(xmltree)])
+
+@makePublic
+def createPublicKeyFile():
+ command = _getGlusterSystemCmd() + ["execute", "gsec_create"]
+ rc, out, err = _execGluster(command)
+ if rc:
+ raise ge.GlusterGeoRepPublicKeyFileCreationFailedException(rc, out, err)
+ else:
+ return True
diff --git a/vdsm/gluster/exception.py b/vdsm/gluster/exception.py
index c569a9e..1ee73bb 100644
--- a/vdsm/gluster/exception.py
+++ b/vdsm/gluster/exception.py
@@ -484,3 +484,14 @@
prefix = "%s: " % (action)
self.message = prefix + "Service action is not supported"
self.err = [self.message]
+
+#geo-replication
+class GlusterGeoRepException(GlusterException):
+ code = 4560
+ message = "Gluster Geo-Replication Exception"
+
+
+class GlusterGeoRepPublicKeyFileCreationFailedException(GlusterGeoRepException):
+ code = 4561
+ message = "Creation of public key file failed"
+
--
To view, visit http://gerrit.ovirt.org/17644
To unsubscribe, visit http://gerrit.ovirt.org/settings
Gerrit-MessageType: newchange
Gerrit-Change-Id: If8c979a89ce11a1622819c474b59dcf088733594
Gerrit-PatchSet: 1
Gerrit-Project: vdsm
Gerrit-Branch: master
Gerrit-Owner: ndarshan <dnarayan(a)redhat.com>
Gerrit-Reviewer: Bala.FA <barumuga(a)redhat.com>
8 years, 2 months
Change in vdsm[master]: vdsm-tool: vdsm-id: add force option to force generate id
by Alon Bar-Lev
Alon Bar-Lev has uploaded a new change for review.
Change subject: vdsm-tool: vdsm-id: add force option to force generate id
......................................................................
vdsm-tool: vdsm-id: add force option to force generate id
this is handy to hide the existence and usage of /etc/vdsm/vdsm.id from
users (other components).
Change-Id: I89f1e29c9cdad0cadb32545fa27c1702ad2e116a
Signed-off-by: Alon Bar-Lev <alonbl(a)redhat.com>
---
M lib/vdsm/tool/vdsm-id.py
M lib/vdsm/utils.py
2 files changed, 35 insertions(+), 3 deletions(-)
git pull ssh://gerrit.ovirt.org:29418/vdsm refs/changes/08/20808/1
diff --git a/lib/vdsm/tool/vdsm-id.py b/lib/vdsm/tool/vdsm-id.py
index 109c382..01f94a9 100644
--- a/lib/vdsm/tool/vdsm-id.py
+++ b/lib/vdsm/tool/vdsm-id.py
@@ -17,9 +17,13 @@
# Refer to the README and COPYING files for full details of the license
#
+
+import sys
+import argparse
+
+
from vdsm.utils import getHostUUID
from vdsm.tool import expose
-import sys
@expose("vdsm-id")
@@ -27,7 +31,19 @@
"""
Printing host uuid
"""
- hostUUID = getHostUUID(False)
+ parser = argparse.ArgumentParser('vdsm-tool configure')
+ parser.add_argument(
+ '--force',
+ dest='force',
+ default=False,
+ action='store_true',
+ help='Generate vdsmid if not available',
+ )
+ args = parser.parse_args(sys.argv[2:])
+ hostUUID = getHostUUID(
+ legacy=False,
+ force=args.force,
+ )
if hostUUID is None:
raise RuntimeError('Cannot retrieve host UUID')
sys.stdout.write(hostUUID)
diff --git a/lib/vdsm/utils.py b/lib/vdsm/utils.py
index 78d055e..d38a273 100644
--- a/lib/vdsm/utils.py
+++ b/lib/vdsm/utils.py
@@ -48,6 +48,7 @@
import subprocess
import threading
import time
+import uuid
from cpopen import CPopen as BetterPopen
import constants
@@ -599,7 +600,7 @@
__hostUUID = None
-def getHostUUID(legacy=True):
+def getHostUUID(legacy=True, force=False):
global __hostUUID
if __hostUUID:
return __hostUUID
@@ -624,6 +625,14 @@
if p.returncode == 0 and 'Not' not in out:
#Avoid error string - 'Not Settable' or 'Not Present'
__hostUUID = out.strip()
+ elif force:
+ hostid = str(uuid.uuid4())
+ with open(constants.P_VDSM_NODE_ID, 'w') as f:
+ f.write("%s\n", hostid)
+ if isOvirtNode():
+ from ovirtnode import ovirtfunctions
+ ovirtfunctions.ovirt_store_config(constants.P_VDSM_NODE_ID)
+ __hostUUID = hostid
else:
logging.warning('Could not find host UUID.')
@@ -877,3 +886,10 @@
logging.error("Panic: %s", msg, exc_info=True)
os.killpg(0, 9)
sys.exit(-3)
+
+
+def isOvirtNode():
+ return (
+ os.path.exists('/etc/rhev-hypervisor-release') or
+ glob.glob('/etc/ovirt-node-*-release')
+ )
--
To view, visit http://gerrit.ovirt.org/20808
To unsubscribe, visit http://gerrit.ovirt.org/settings
Gerrit-MessageType: newchange
Gerrit-Change-Id: I89f1e29c9cdad0cadb32545fa27c1702ad2e116a
Gerrit-PatchSet: 1
Gerrit-Project: vdsm
Gerrit-Branch: master
Gerrit-Owner: Alon Bar-Lev <alonbl(a)redhat.com>
8 years, 3 months
Change in vdsm[master]: vdsm-gluster: Added gluster volume geo-replication start verb
by tjeyasin@redhat.com
Hello Ayal Baron, Bala.FA, Saggi Mizrahi, Dan Kenigsberg,
I'd like you to do a code review. Please visit
http://gerrit.ovirt.org/17766
to review the following change.
Change subject: vdsm-gluster: Added gluster volume geo-replication start verb
......................................................................
vdsm-gluster: Added gluster volume geo-replication start verb
Start the geo-replication session between the hosts.
Start distributed geo-replication on all the nodes that are a part
of the master-volume. Even if any node, that is a part of the
master-volume is down, the command will still be successful.
Change-Id: I3cf03c748cf9fe28efe7d407727cd52da20701c5
Signed-off-by: Timothy Asir <tjeyasin(a)redhat.com>
---
M client/vdsClientGluster.py
M vdsm/gluster/api.py
M vdsm/gluster/cli.py
M vdsm/gluster/exception.py
4 files changed, 100 insertions(+), 0 deletions(-)
git pull ssh://gerrit.ovirt.org:29418/vdsm refs/changes/66/17766/1
diff --git a/client/vdsClientGluster.py b/client/vdsClientGluster.py
index 90af83e..feb6387 100644
--- a/client/vdsClientGluster.py
+++ b/client/vdsClientGluster.py
@@ -424,6 +424,34 @@
pp.pprint(status)
return status['status']['code'], status['status']['message']
+ def do_glusterVolumeGeoRepStart(self, args):
+ params = self._eqSplit(args)
+ masterVolName = params.get('masterVolName', '')
+ slaveHost = params.get('slaveHost', '')
+ slaveVolName = params.get('slaveVolName', '')
+ if not(masterVolName and slaveHost and slaveVolName):
+ raise ValueError
+
+ status = self.s.glusterVolumeGeoRepStart(masterVolName,
+ slaveHost,
+ slaveVolName)
+ pp.pprint(status)
+ return status['status']['code'], status['status']['message']
+
+ def do_glusterVolumeGeoRepStop(self, args):
+ params = self._eqSplit(args)
+ masterVolName = params.get('masterVolName', '')
+ slaveHost = params.get('slaveHost', '')
+ slaveVolName = params.get('slaveVolName', '')
+ if not(masterVolName and slaveHost and slaveVolName):
+ raise ValueError
+
+ status = self.s.glusterVolumeGeoRepStop(masterVolName,
+ slaveHost,
+ slaveVolName)
+ pp.pprint(status)
+ return status['status']['code'], status['status']['message']
+
def getGlusterCmdDict(serv):
return \
@@ -705,4 +733,26 @@
'not set'
'(swift, glusterd, smb, memcached)'
)),
+ 'glusterVolumeGeoRepStart': (
+ serv.do_glusterVolumeGeoRepStart,
+ ('masterVolName=<master_volume_name> slaveHost=<slave_host> '
+ 'slaveVolName=<slave_volume_name>\n\t'
+ '<master_volume_name> is an existing volume name in the '
+ 'master node\n\t'
+ '<slave_host> is slave host name\n\t'
+ '<slave_volume_name> is an existing volume name in the '
+ 'slave node',
+ 'start volume geo-replication'
+ )),
+ 'glusterVolumeGeoRepStop': (
+ serv.do_glusterVolumeGeoRepStop,
+ ('masterVolName=<master_volume_name> slaveHost=<slave_host> '
+ 'slaveVolName=<slave_volume_name>\n\t'
+ '<master_volume_name> is an existing volume name in the '
+ 'master node\n\t'
+ '<slave_host> is slave host name\n\t'
+ '<slave_volume_name> is an existing volume name in the '
+ 'slave node',
+ 'stop volume geo-replication'
+ )),
}
diff --git a/vdsm/gluster/api.py b/vdsm/gluster/api.py
index 4bd8308..ed9f5ae 100644
--- a/vdsm/gluster/api.py
+++ b/vdsm/gluster/api.py
@@ -287,6 +287,20 @@
status = self.svdsmProxy.glusterServicesGet(serviceNames)
return {'services': status}
+ @exportAsVerb
+ def volumeGeoRepStart(self, masterVolName, slaveHost, slaveVolName,
+ options=None):
+ self.svdsmProxy.glusterVolumeGeoRepStart(masterVolName,
+ slaveHost,
+ slaveVolName)
+
+ @exportAsVerb
+ def volumeGeoRepStop(self, masterVolName, slaveHost, slaveVolName,
+ options=None):
+ self.svdsmProxy.glusterVolumeGeoRepStop(masterVolName,
+ slaveHost,
+ slaveVolName)
+
def getGlusterMethods(gluster):
l = []
diff --git a/vdsm/gluster/cli.py b/vdsm/gluster/cli.py
index bac6d1c..e4d6615 100644
--- a/vdsm/gluster/cli.py
+++ b/vdsm/gluster/cli.py
@@ -897,3 +897,29 @@
return _parseVolumeProfileInfo(xmltree, nfs)
except _etreeExceptions:
raise ge.GlusterXmlErrorException(err=[etree.tostring(xmltree)])
+
+
+@makePublic
+def volumeGeoRepStart(masterVolName, slaveHost, slaveVolName):
+ command = _getGlusterVolCmd() + ["geo-replication", masterVolName,
+ "%s::%s" % (slaveHost, slaveVolName),
+ "start"]
+ try:
+ _execGlusterXml(command)
+ return True
+ except ge.GlusterCmdFailedException as e:
+ raise ge.GlusterVolumeGeoRepStartFailedException(rc=e.rc,
+ err=e.err)
+
+
+@makePublic
+def volumeGeoRepStop(masterVolName, slaveHost, slaveVolName):
+ command = _getGlusterVolCmd() + ["geo-replication", masterVolName,
+ "%s::%s" % (slaveHost, slaveVolName),
+ "stop"]
+ try:
+ _execGlusterXml(command)
+ return True
+ except ge.GlusterCmdFailedException as e:
+ raise ge.GlusterVolumeGeoRepStopFailedException(rc=e.rc,
+ err=e.err)
diff --git a/vdsm/gluster/exception.py b/vdsm/gluster/exception.py
index c569a9e..259df32 100644
--- a/vdsm/gluster/exception.py
+++ b/vdsm/gluster/exception.py
@@ -484,3 +484,13 @@
prefix = "%s: " % (action)
self.message = prefix + "Service action is not supported"
self.err = [self.message]
+
+
+class GlusterVolumeGeoRepStartFailedException(GlusterVolumeException):
+ code = 4164
+ message = "Volume geo-replication start failed"
+
+
+class GlusterVolumeGeoRepStopFailedException(GlusterVolumeException):
+ code = 4165
+ message = "Volume geo-replication stop failed"
--
To view, visit http://gerrit.ovirt.org/17766
To unsubscribe, visit http://gerrit.ovirt.org/settings
Gerrit-MessageType: newchange
Gerrit-Change-Id: I3cf03c748cf9fe28efe7d407727cd52da20701c5
Gerrit-PatchSet: 1
Gerrit-Project: vdsm
Gerrit-Branch: master
Gerrit-Owner: Timothy Asir <tjeyasin(a)redhat.com>
Gerrit-Reviewer: Ayal Baron <abaron(a)redhat.com>
Gerrit-Reviewer: Bala.FA <barumuga(a)redhat.com>
Gerrit-Reviewer: Dan Kenigsberg <danken(a)redhat.com>
Gerrit-Reviewer: Saggi Mizrahi <smizrahi(a)redhat.com>
8 years, 4 months
Change in vdsm[master]: gluster: geo replication status and status detail
by dnarayan@redhat.com
Hello Bala.FA,
I'd like you to do a code review. Please visit
http://gerrit.ovirt.org/18414
to review the following change.
Change subject: gluster: geo replication status and status detail
......................................................................
gluster: geo replication status and status detail
this has two verbs, status: provides geo-replication status of all running
sessions or all sessions associated with a perticular source volume or
session between a source and remote volume. status detail: provides detailed
status of geo-repliction session between source and remote volume
Change-Id: I4f37f35a5480fbe049a67758e122d4a0c2eba513
Signed-off-by: ndarshan <dnarayan(a)redhat.com>
---
M client/vdsClientGluster.py
M vdsm/gluster/api.py
M vdsm/gluster/cli.py
M vdsm/gluster/exception.py
M vdsm/gluster/vdsmapi-gluster-schema.json
5 files changed, 223 insertions(+), 0 deletions(-)
git pull ssh://gerrit.ovirt.org:29418/vdsm refs/changes/14/18414/1
diff --git a/client/vdsClientGluster.py b/client/vdsClientGluster.py
index 90af83e..76a5ba8 100644
--- a/client/vdsClientGluster.py
+++ b/client/vdsClientGluster.py
@@ -424,6 +424,35 @@
pp.pprint(status)
return status['status']['code'], status['status']['message']
+ def do_glusterVolumeGeoRepStatus(self, args):
+ params = self._eqSplit(args)
+ try:
+ volName = params.get('volName', '')
+ remoteHost = params.get('remoteHost', '')
+ remoteVolName = params.get('remoteVolName', '')
+ except:
+ raise ValueError
+ status = self.s.glusterVolumeGeoRepStatus(volName, remoteHost,
+ remoteVolName)
+ pp.pprint(status)
+ return status['status']['code'], status['status']['message']
+
+ def do_glusterVolumeGeoRepStatusDetail(self, args):
+ params = self._eqSplit(args)
+ try:
+ volName = params.get('volName', '')
+ remoteHost = params.get('remoteHost', '')
+ remoteVolName = params.get('remoteVolName', '')
+ except:
+ raise ValueError
+ if not (volName and remoteHost and remoteVolName):
+ raise ValueError
+ status = self.s.glusterVolumeGeoRepStatusDetail(volName,
+ remoteHost,
+ remoteVolName)
+ pp.pprint(status)
+ return status['status']['code'], status['status']['message']
+
def getGlusterCmdDict(serv):
return \
@@ -705,4 +734,24 @@
'not set'
'(swift, glusterd, smb, memcached)'
)),
+ 'glusterVolumeGeoRepStatus': (
+ serv.do_glusterVolumeGeoRepStatus,
+ ('volName=<master_volume_name> '
+ 'remoteHost=<slave_host_name> '
+ 'remoteVolName=<slave_volume_name> '
+ '<master_volume_name>existing volume name in the master node\n\t'
+ '<slave_host_name>is remote slave host name or ip\n\t'
+ '<slave_volume_name>existing volume name in the slave node',
+ 'Returns ths status of geo-replication'
+ )),
+ 'glusterVolumeGeoRepStatusDetail': (
+ serv.do_glusterVolumeGeoRepStatusDetail,
+ ('volName=<master_volume_name> '
+ 'remoteHost=<slave_host_name> '
+ 'remoteVolName=<slave_volume_name> '
+ '<master_volume_name>existing volume name in the master node\n\t'
+ '<slave_host_name>is remote slave host name or ip\n\t'
+ '<slave_volume_name>existing volume name in the slave node',
+ 'Returns the Detailed status of geo-replication'
+ ))
}
diff --git a/vdsm/gluster/api.py b/vdsm/gluster/api.py
index 4bd8308..d24e700 100644
--- a/vdsm/gluster/api.py
+++ b/vdsm/gluster/api.py
@@ -287,6 +287,22 @@
status = self.svdsmProxy.glusterServicesGet(serviceNames)
return {'services': status}
+ @exportAsVerb
+ def volumeGeoRepStatus(self, volName=None, remoteHost=None,
+ remoteVolName=None, options=None):
+ status = self.svdsmProxy.glusterVolumeGeoRepStatus(volName,
+ remoteHost,
+ remoteVolName)
+ return {'geo-rep': status}
+
+ @exportAsVerb
+ def volumeGeoRepStatusDetail(self, volName, remoteHost,
+ remoteVolName, options=None):
+ status = self.svdsmProxy.glusterVolumeGeoRepStatusDetail(volName,
+ remoteHost,
+ remoteVolName)
+ return {'geo-rep': status}
+
def getGlusterMethods(gluster):
l = []
diff --git a/vdsm/gluster/cli.py b/vdsm/gluster/cli.py
index bac6d1c..1cf0e12 100644
--- a/vdsm/gluster/cli.py
+++ b/vdsm/gluster/cli.py
@@ -897,3 +897,59 @@
return _parseVolumeProfileInfo(xmltree, nfs)
except _etreeExceptions:
raise ge.GlusterXmlErrorException(err=[etree.tostring(xmltree)])
+
+
+def _parseGeoRepStatusDetail(tree):
+ status = {'node': tree.find('geoRep/node').text,
+ 'health': tree.find('geoRep/health').text,
+ 'uptime': tree.find('geoRep/uptime').text,
+ 'filesSyncd': tree.find('geoRep/filesSyncd').text,
+ 'filesPending': tree.find('geoRep/filesPending').text,
+ 'bytesPending': tree.find('geoRep/bytesPending').text,
+ 'deletesPending': tree.find('geoRep/deletesPending').text}
+ return status
+
+
+def _parseGeoRepStatus(tree):
+ pairs = []
+ for el in tree.findall('geoRep/pair'):
+ value = {}
+ value['node'] = el.find('node').text
+ value['master'] = el.find('master').text
+ value['slave'] = el.find('slave').text
+ value['health'] = el.find('health').text
+ value['uptime'] = el.find('uptime').text
+ pairs.append(value)
+ return pairs
+
+
+@makePublic
+def volumeGeoRepStatus(volName=None, remoteHost=None, remoteVolName=None,
+ ):
+ command = _getGlusterVolCmd() + ["geo-replication", volName,
+ "%s::%s" % (remoteHost, remoteVolName),
+ "status"]
+ try:
+ xmltree = _execGlusterXml(command)
+ except ge.GlusterCmdFailedException as e:
+ raise ge.GlusterGeoRepStatusFailedException(rc=e.rc, err=e.err)
+ try:
+ return _parseGeoRepStatus(xmltree)
+ except _etreeExceptions:
+ raise ge.GlusterXmlErrorException(err=[etree.tostring(xmltree)])
+
+
+@makePublic
+def volumeGeoRepStatusDetail(volName, remoteHost, remoteVolName,
+ ):
+ command = _getGlusterVolCmd() + ["geo-replication", volName,
+ "%s::%s" % (remoteHost, remoteVolName),
+ "status", "detail"]
+ try:
+ xmltree = _execGlusterXml(command)
+ except ge.GlusterCmdFailedException as e:
+ raise ge.GlusterGeoRepStatusDetailFailedException(rc=e.rc, err=e.err)
+ try:
+ return _parseGeoRepStatusDetail(xmltree)
+ except _etreeExceptions:
+ raise ge.GlusterXmlErrorException(err=[etree.tostring(xmltree)])
diff --git a/vdsm/gluster/exception.py b/vdsm/gluster/exception.py
index c569a9e..d95b168 100644
--- a/vdsm/gluster/exception.py
+++ b/vdsm/gluster/exception.py
@@ -484,3 +484,19 @@
prefix = "%s: " % (action)
self.message = prefix + "Service action is not supported"
self.err = [self.message]
+
+
+#geo-replication
+class GlusterGeoRepException(GlusterException):
+ code = 4560
+ message = "Gluster Geo-Replication Exception"
+
+
+class GlusterGeoRepStatusFailedException(GlusterGeoRepException):
+ code = 4565
+ message = "Geo Rep status failed"
+
+
+class GlusterGeoRepStatusDetailFailedException(GlusterGeoRepException):
+ code = 4566
+ message = "Geo Rep status detail failed"
diff --git a/vdsm/gluster/vdsmapi-gluster-schema.json b/vdsm/gluster/vdsmapi-gluster-schema.json
index 7a4c034..557c750 100644
--- a/vdsm/gluster/vdsmapi-gluster-schema.json
+++ b/vdsm/gluster/vdsmapi-gluster-schema.json
@@ -372,3 +372,89 @@
{'command': {'class': 'GlusterService', 'name': 'action'},
'data': {'serviceName': 'str', 'action': 'GlusterServiceAction'},
'returns': 'GlusterServicesStatusInfo'}
+
+##
+# @GlusterGeoRepStatus:
+#
+# Gluster geo-replication status information.
+#
+# @node: The node where geo-replication is started
+#
+# @master: The source for geo-replication
+#
+# @slave: The destination of geo-replication
+#
+# @health: The status of the geo-replication session
+#
+# @uptime: The time since the geo-replication started
+#
+# Since: 4.10.3
+##
+{'type': 'GlusterGeoRepStatus',
+ 'data': {'node': 'str', 'master': 'str', 'slave': 'str', 'health': 'str', 'uptime': 'int'}}
+
+
+##
+# @GlusterVolume.geoRepStatus:
+#
+# Gets the status of geo-Replication session
+#
+# @masterVolName: Is an existing volume name in the master node
+#
+# @slaveHost: Is remote slave host name or ip
+#
+# @slaveVolName: Is an available existing volume name in the slave node
+#
+# Returns:
+# status information for geo-replication
+#
+# Since: 4.10.3
+##
+{'command': {'class': 'GlusterVolume', 'name': 'geoRepStatus'},
+ 'data': {'masterVolName': 'str', 'slaveHost': 'str', 'slaveVolName': 'str'},
+ 'returns': 'GlusterGeoRepStatus'}
+
+##
+# @GlusterGeoRepStatusDetail:
+#
+# Gluster geo-replication detailed status information.
+#
+# @node: The node where geo-replication is started
+#
+# @health: The status of the geo-replication session
+#
+# @uptime: The time since the geo-replication started
+#
+# @filesSyncd: The number of files that are synced
+#
+# @filesPending: The number of files that are pending to be synced
+#
+# @bytesPending: The number of bytes that are pending to be synced
+#
+# @deletesPending: The number of deletes that are pending
+#
+# Since: 4.10.3
+##
+{'type': 'GlusterGeoRepStatusDetail',
+ 'data': {'node': 'str', 'health': 'str', 'uptime': 'int', 'filesSyncd': 'int', 'filesPending': 'int',
+ 'bytesPending': 'int','deletesPending': 'int'}}
+
+##
+# @GlusterVolume.geoRepStatusDetail:
+#
+# Gets the detailed status of geo-Replication session
+#
+# @masterVolName: Is an existing volume name in the master node
+#
+# @slaveHost: Is remote slave host name or ip
+#
+# @slaveVolName: Is an available existing volume name in the slave node
+#
+# Returns:
+# detailed status information of geo-replication session
+#
+# Since: 4.10.3
+##
+{'command': {'class': 'GlusterVolume', 'name': 'geoRepStatusDetail'},
+ 'data': {'masterVolName': 'str', 'slaveHost': 'str', 'slaveVolName': 'str'},
+ 'returns': 'GlusterGeoRepStatusDetail'}
--
To view, visit http://gerrit.ovirt.org/18414
To unsubscribe, visit http://gerrit.ovirt.org/settings
Gerrit-MessageType: newchange
Gerrit-Change-Id: I4f37f35a5480fbe049a67758e122d4a0c2eba513
Gerrit-PatchSet: 1
Gerrit-Project: vdsm
Gerrit-Branch: master
Gerrit-Owner: ndarshan <dnarayan(a)redhat.com>
Gerrit-Reviewer: Bala.FA <barumuga(a)redhat.com>
8 years, 4 months
Change in vdsm[master]: cleanup: drop several unused local variables
by asegurap@redhat.com
Antoni Segura Puimedon has uploaded a new change for review.
Change subject: cleanup: drop several unused local variables
......................................................................
cleanup: drop several unused local variables
Change-Id: Ib81c292f900154819e8852c21ae389c323034999
Signed-off-by: Antoni S. Puimedon <asegurap(a)redhat.com>
---
M client/vdsClient.py
M lib/vdsm/netinfo.py
M lib/yajsonrpc/protonReactor.py
M tests/functional/networkTests.py
M tests/functional/virtTests.py
M tests/hookValidation.py
M tests/hooksTests.py
M tests/jsonRpcTests.py
M tests/miscTests.py
M tests/testValidation.py
M tests/vmTests.py
M vds_bootstrap/setup
M vds_bootstrap/vds_bootstrap.py
M vds_bootstrap/vds_bootstrap_complete.py
M vdsm/storage/hsm.py
M vdsm/storage/iscsi.py
M vdsm/storage/misc.py
M vdsm/storage/remoteFileHandler.py
M vdsm/storage/resourceManager.py
M vdsm/storage/sp.py
M vdsm/storage/task.py
M vdsm/vm.py
M vdsm_api/Bridge.py
M vdsm_api/process-schema.py
M vdsm_api/vdsmapi.py
25 files changed, 23 insertions(+), 49 deletions(-)
git pull ssh://gerrit.ovirt.org:29418/vdsm refs/changes/35/20535/1
diff --git a/client/vdsClient.py b/client/vdsClient.py
index 37dd7cb..4c09546 100644
--- a/client/vdsClient.py
+++ b/client/vdsClient.py
@@ -842,7 +842,6 @@
masterDom = args[3]
domList = args[4].split(",")
mVer = int(args[5])
- pool = None
if len(args) > 6:
pool = self.s.createStoragePool(poolType, spUUID,
poolName, masterDom,
diff --git a/lib/vdsm/netinfo.py b/lib/vdsm/netinfo.py
index e8f2b8d..cf70089 100644
--- a/lib/vdsm/netinfo.py
+++ b/lib/vdsm/netinfo.py
@@ -93,8 +93,6 @@
The list of nics is built by filtering out nics defined
as hidden, fake or hidden bonds (with related nics'slaves).
"""
- res = []
-
def isHiddenNic(device):
"""
Returns boolean given the device name stating
@@ -397,7 +395,7 @@
"Convert an integer to the corresponding ip address in the dot-notation"
ip_address = []
- for i in xrange(4):
+ for _ in xrange(4):
ip_num, ip_val = divmod(ip_num, 256)
ip_address.append(str(ip_val))
diff --git a/lib/yajsonrpc/protonReactor.py b/lib/yajsonrpc/protonReactor.py
index 557600c..7892e3c 100644
--- a/lib/yajsonrpc/protonReactor.py
+++ b/lib/yajsonrpc/protonReactor.py
@@ -376,7 +376,6 @@
proton.pn_link_advance(link)
def createListener(self, address, acceptHandler):
- host, port = address
return self._scheduleOp(True, self._createListener, address,
acceptHandler)
diff --git a/tests/functional/networkTests.py b/tests/functional/networkTests.py
index a9149be..ba93343 100644
--- a/tests/functional/networkTests.py
+++ b/tests/functional/networkTests.py
@@ -377,7 +377,7 @@
for index in range(VLAN_COUNT)]
with dummyIf(1) as nics:
firstVlan, firstVlanId = NET_VLANS[0]
- status, msg = self.vdsm_net.addNetwork(firstVlan, vlan=firstVlanId,
+ _ = self.vdsm_net.addNetwork(firstVlan, vlan=firstVlanId,
bond=BONDING_NAME,
nics=nics, opts=opts)
with nonChangingOperstate(BONDING_NAME):
diff --git a/tests/functional/virtTests.py b/tests/functional/virtTests.py
index cdb695a..85781f7 100644
--- a/tests/functional/virtTests.py
+++ b/tests/functional/virtTests.py
@@ -83,7 +83,7 @@
def _genInitramfs():
fd, path = tempfile.mkstemp()
cmd = [_mkinitrd.cmd, "-f", path, _kernelVer]
- rc, out, err = execCmd(cmd, sudo=False)
+ _ = execCmd(cmd, sudo=False)
os.chmod(path, 0o644)
return path
diff --git a/tests/hookValidation.py b/tests/hookValidation.py
index 80e7239..208ed35 100644
--- a/tests/hookValidation.py
+++ b/tests/hookValidation.py
@@ -67,8 +67,6 @@
cookie_file = _createHookScript(hook_path, hook_name, hook_script)
- output = None
-
try:
kwargs['hook_cookiefile'] = cookie_file
output = test_function(*args, **kwargs)
diff --git a/tests/hooksTests.py b/tests/hooksTests.py
index 1018a4e..ddb3530 100644
--- a/tests/hooksTests.py
+++ b/tests/hooksTests.py
@@ -42,7 +42,7 @@
echo -n %s >> "$_hook_domxml"
"""
scripts = [tempfile.NamedTemporaryFile(dir=dirName, delete=False)
- for n in xrange(Q)]
+ for _ in xrange(Q)]
scripts.sort(key=lambda f: f.name)
for n, script in enumerate(scripts):
script.write(code % n)
diff --git a/tests/jsonRpcTests.py b/tests/jsonRpcTests.py
index a7b565f..00025ae 100644
--- a/tests/jsonRpcTests.py
+++ b/tests/jsonRpcTests.py
@@ -85,7 +85,7 @@
def serve(reactor):
try:
reactor.process_requests()
- except socket.error as e:
+ except socket.error:
pass
except Exception as e:
self.log.error("Reactor died unexpectedly", exc_info=True)
diff --git a/tests/miscTests.py b/tests/miscTests.py
index c836e55..1a9a16c 100644
--- a/tests/miscTests.py
+++ b/tests/miscTests.py
@@ -432,7 +432,7 @@
os.chmod(dstPath, 0o666)
#Copy
- rc, out, err = misc.ddWatchCopy(srcPath, dstPath, None, len(data))
+ _ = misc.ddWatchCopy(srcPath, dstPath, None, len(data))
#Get copied data
readData = open(dstPath).read()
@@ -448,7 +448,7 @@
fd, path = tempfile.mkstemp()
try:
- for i in xrange(repetitions):
+ for _ in xrange(repetitions):
os.write(fd, data)
self.assertEquals(os.stat(path).st_size, misc.MEGA)
except:
@@ -474,7 +474,7 @@
self.assertEquals(os.stat(path).st_size, misc.MEGA * 2)
with open(path, "r") as f:
- for i in xrange(repetitions):
+ for _ in xrange(repetitions):
self.assertEquals(f.read(len(data)), data)
finally:
os.unlink(path)
@@ -501,7 +501,7 @@
misc.MEGA * 2 + len(add_data))
with open(path, "r") as f:
- for i in xrange(repetitions):
+ for _ in xrange(repetitions):
self.assertEquals(f.read(len(data)), data)
# Checking the additional data
self.assertEquals(f.read(len(add_data)), add_data)
@@ -535,7 +535,7 @@
os.chmod(dstPath, 0o666)
#Copy
- rc, out, err = misc.ddWatchCopy(srcPath, dstPath, None, len(data))
+ _ = misc.ddWatchCopy(srcPath, dstPath, None, len(data))
#Get copied data
readData = open(dstPath).read()
diff --git a/tests/testValidation.py b/tests/testValidation.py
index d370971..92790d9 100644
--- a/tests/testValidation.py
+++ b/tests/testValidation.py
@@ -110,7 +110,7 @@
def wrapper(*args, **kwargs):
if not os.path.exists('/sys/module/dummy'):
cmd_modprobe = [modprobe.cmd, "dummy"]
- rc, out, err = utils.execCmd(cmd_modprobe, sudo=True)
+ _ = utils.execCmd(cmd_modprobe, sudo=True)
return f(*args, **kwargs)
return wrapper
diff --git a/tests/vmTests.py b/tests/vmTests.py
index 1f69f0a..9d91723 100644
--- a/tests/vmTests.py
+++ b/tests/vmTests.py
@@ -390,7 +390,7 @@
driveInput.update({'shared': 'UNKNOWN-VALUE'})
with self.assertRaises(ValueError):
- drive = vm.Drive({}, self.log, **driveInput)
+ _ = vm.Drive({}, self.log, **driveInput)
def testDriveXML(self):
SERIAL = '54-a672-23e5b495a9ea'
diff --git a/vds_bootstrap/setup b/vds_bootstrap/setup
index 778dc12..701df8b 100755
--- a/vds_bootstrap/setup
+++ b/vds_bootstrap/setup
@@ -63,7 +63,6 @@
return False, HYPERVISOR_RELEASE_FILE + ", " + REDHAT_RELEASE_FILE
def get_id_line():
- line = ''
RELEASE_FILE = None
try:
@@ -193,7 +192,6 @@
import calendar
return_value = False
- ticket = None
try:
time_struct = time.strptime(systime, '%Y-%m-%dT%H:%M:%S')
diff --git a/vds_bootstrap/vds_bootstrap.py b/vds_bootstrap/vds_bootstrap.py
index a9dc901..e45c8b6 100755
--- a/vds_bootstrap/vds_bootstrap.py
+++ b/vds_bootstrap/vds_bootstrap.py
@@ -289,7 +289,6 @@
"""
status = "OK"
message = 'Host properly registered with RHN/Satellite.'
- rc = True
try:
rc = bool(deployUtil.yumListPackages(VDSM_NAME))
@@ -316,7 +315,6 @@
"""
status = "OK"
message = 'Available VDSM matches requirements'
- rc = True
try:
rc = deployUtil.yumSearchVersion(VDSM_NAME, VDSM_MIN_VER)
@@ -393,7 +391,6 @@
"""
os_status = "FAIL"
kernel_status = "FAIL"
- os_message = "Unsupported platform version"
os_name = "Unknown OS"
kernel_message = ''
self.rc = True
@@ -741,8 +738,6 @@
return self.rc
def _addNetwork(self, vdcName, vdcPort):
- fReturn = True
-
#add management bridge
try:
fReturn = deployUtil.makeBridge(
@@ -859,9 +854,6 @@
# TODO remove legacy
if deployUtil.getBootstrapInterfaceVersion() == 1 and \
engine_ssh_key is None:
- vdcAddress = None
- vdcPort = None
-
vdcAddress, vdcPort = deployUtil.getAddress(url)
if vdcAddress is not None:
strKey = deployUtil.getAuthKeysFile(vdcAddress, vdcPort)
diff --git a/vds_bootstrap/vds_bootstrap_complete.py b/vds_bootstrap/vds_bootstrap_complete.py
index fd18847..07c3610 100755
--- a/vds_bootstrap/vds_bootstrap_complete.py
+++ b/vds_bootstrap/vds_bootstrap_complete.py
@@ -101,7 +101,6 @@
except:
arg = 1
- res = True
try:
res = deployUtil.instCert(rnum, VDSM_CONF_FILE)
if res:
diff --git a/vdsm/storage/hsm.py b/vdsm/storage/hsm.py
index 4579763..322ee8b 100644
--- a/vdsm/storage/hsm.py
+++ b/vdsm/storage/hsm.py
@@ -1095,7 +1095,7 @@
misc.validateN(hostID, 'hostID')
# already disconnected/or pool is just unknown - return OK
try:
- pool = self.getPool(spUUID)
+ _ = self.getPool(spUUID)
except se.StoragePoolUnknown:
self.log.warning("disconnect sp: %s failed. Known pools %s",
spUUID, self.pools)
@@ -1861,7 +1861,7 @@
self.log.info("spUUID=%s master=%s", spUUID, masterDom)
try:
- pool = self.getPool(spUUID)
+ _ = self.getPool(spUUID)
except se.StoragePoolUnknown:
pool = sp.StoragePool(spUUID, self.domainMonitor, self.taskMng)
else:
diff --git a/vdsm/storage/iscsi.py b/vdsm/storage/iscsi.py
index 7da94ab..9976026 100644
--- a/vdsm/storage/iscsi.py
+++ b/vdsm/storage/iscsi.py
@@ -415,7 +415,7 @@
log.debug("Performing SCSI scan, this will take up to %s seconds",
maxTimeout)
time.sleep(minTimeout)
- for i in xrange(maxTimeout - minTimeout):
+ for _ in xrange(maxTimeout - minTimeout):
for p in processes[:]:
(hba, proc) = p
if proc.wait(0):
@@ -429,7 +429,7 @@
time.sleep(1)
else:
log.warning("Still waiting for scsi scan of hbas: %s",
- tuple(hba for p in processes))
+ tuple(hba for _ in processes))
def devIsiSCSI(dev):
diff --git a/vdsm/storage/misc.py b/vdsm/storage/misc.py
index fc13a9c..5245264 100644
--- a/vdsm/storage/misc.py
+++ b/vdsm/storage/misc.py
@@ -484,7 +484,6 @@
log.debug("dir: %s, prefixName: %s, versions: %s" %
(directory, prefixName, gen))
gen = int(gen)
- files = os.listdir(directory)
files = glob.glob("%s*" % prefixName)
fd = {}
for fname in files:
@@ -614,7 +613,6 @@
return self.acquire(True)
def acquire(self, exclusive):
- currentEvent = None
currentThread = threading.currentThread()
# Handle reacquiring lock in the same thread
@@ -1081,7 +1079,7 @@
maxthreads -= 1
# waiting for rest threads to end
- for i in xrange(threadsCount):
+ for _ in xrange(threadsCount):
yield respQueue.get()
diff --git a/vdsm/storage/remoteFileHandler.py b/vdsm/storage/remoteFileHandler.py
index 5b24053..accf51c 100644
--- a/vdsm/storage/remoteFileHandler.py
+++ b/vdsm/storage/remoteFileHandler.py
@@ -275,7 +275,7 @@
def __init__(self, numOfHandlers):
self._numOfHandlers = numOfHandlers
self.handlers = [None] * numOfHandlers
- self.occupied = [Lock() for i in xrange(numOfHandlers)]
+ self.occupied = [Lock() for _ in xrange(numOfHandlers)]
def _isHandlerAvailable(self, poolHandler):
if poolHandler is None:
diff --git a/vdsm/storage/resourceManager.py b/vdsm/storage/resourceManager.py
index 14049dc..486ea18 100644
--- a/vdsm/storage/resourceManager.py
+++ b/vdsm/storage/resourceManager.py
@@ -926,7 +926,7 @@
return req.wait(timeout)
# req not found - check that it is not granted
- for fullName in self.resources:
+ for _ in self.resources:
return True
# Note that there is a risk of another thread that is racing with us
diff --git a/vdsm/storage/sp.py b/vdsm/storage/sp.py
index 38cd453..db66662 100644
--- a/vdsm/storage/sp.py
+++ b/vdsm/storage/sp.py
@@ -1326,7 +1326,6 @@
self.log.info("spUUID=%s sdUUID=%s", self.spUUID, sdUUID)
vms = self._getVMsPath(sdUUID)
# We should exclude 'masterd' link from IMG_METAPATTERN globing
- vmUUID = ovf = imgList = ''
for vm in vmList:
if not vm:
continue
diff --git a/vdsm/storage/task.py b/vdsm/storage/task.py
index 4eff5c1..0532b02 100644
--- a/vdsm/storage/task.py
+++ b/vdsm/storage/task.py
@@ -872,10 +872,7 @@
def _runJobs(self):
result = ""
- code = 100
- message = "Unknown Error"
i = 0
- j = None
try:
if self.aborting():
raise se.TaskAborted("shutting down")
@@ -891,7 +888,6 @@
if result is None:
result = ""
i += 1
- j = None
self._updateResult(0, "%s jobs completed successfully" % i, result)
self._updateState(State.finished)
self.log.debug('Task.run: exit - success: result %s' % result)
diff --git a/vdsm/vm.py b/vdsm/vm.py
index 0c12334..5e1c7f1 100644
--- a/vdsm/vm.py
+++ b/vdsm/vm.py
@@ -3058,7 +3058,7 @@
self._dom.attachDevice(nicXml)
except libvirt.libvirtError as e:
self.log.error("Hotplug failed", exc_info=True)
- nicXml = hooks.after_nic_hotplug_fail(
+ _ = hooks.after_nic_hotplug_fail(
nicXml, self.conf, params=customProps)
if e.get_error_code() == libvirt.VIR_ERR_NO_DOMAIN:
return errCode['noVM']
@@ -3760,7 +3760,7 @@
"trying again without it (%s)", e)
try:
self._dom.snapshotCreateXML(snapxml, snapFlags)
- except Exception as e:
+ except Exception:
self.log.error("Unable to take snapshot", exc_info=True)
if memoryParams:
self.cif.teardownVolumePath(memoryVol)
diff --git a/vdsm_api/Bridge.py b/vdsm_api/Bridge.py
index b9fdaf8..4812354 100644
--- a/vdsm_api/Bridge.py
+++ b/vdsm_api/Bridge.py
@@ -34,7 +34,6 @@
def dispatch(self, name, argobj):
methodName = name.replace('.', '_')
- result = None
try:
fn = getattr(self, methodName)
except AttributeError:
diff --git a/vdsm_api/process-schema.py b/vdsm_api/process-schema.py
index c4bda0d..307d498 100755
--- a/vdsm_api/process-schema.py
+++ b/vdsm_api/process-schema.py
@@ -255,12 +255,12 @@
# Union member types
names = strip_stars(s.get('data', []))
types = filter_types(names)
- details = [None for n in names]
+ details = [None for _ in names]
attr_table('Types', names, types, details)
elif 'enum' in s:
# Enum values
names = strip_stars(s.get('data', []))
- types = [None for n in names]
+ types = [None for _ in names]
details = [s['info_data'][n] for n in names]
attr_table('Values', names, types, details)
elif 'map' in s:
diff --git a/vdsm_api/vdsmapi.py b/vdsm_api/vdsmapi.py
index db29c13..c38ff01 100644
--- a/vdsm_api/vdsmapi.py
+++ b/vdsm_api/vdsmapi.py
@@ -92,7 +92,6 @@
def parse_schema(fp):
exprs = []
expr = ''
- expr_eval = None
for line in fp:
if line.startswith('#') or line == '\n':
--
To view, visit http://gerrit.ovirt.org/20535
To unsubscribe, visit http://gerrit.ovirt.org/settings
Gerrit-MessageType: newchange
Gerrit-Change-Id: Ib81c292f900154819e8852c21ae389c323034999
Gerrit-PatchSet: 1
Gerrit-Project: vdsm
Gerrit-Branch: master
Gerrit-Owner: Antoni Segura Puimedon <asegurap(a)redhat.com>
8 years, 7 months
Change in vdsm[master]: vdsm: Refactoring of retrieving device info from xml
by Vinzenz Feenstra
Vinzenz Feenstra has uploaded a new change for review.
Change subject: vdsm: Refactoring of retrieving device info from xml
......................................................................
vdsm: Refactoring of retrieving device info from xml
Reworked a bit the retrieval of device info from the libvirt domain xml.
Now VDSM won't parse the code in lastXmlDesc every time and the retrieval
of elements from the domain xml has been a bit abstracted.
Additionally the retrieval of an alias has been moved into a separate
function call to make the readability a bit better.
Change-Id: I7e106b2f2d3f4160d4e882f1a2880cb1b52fbb22
Signed-off-by: Vinzenz Feenstra <vfeenstr(a)redhat.com>
---
M vdsm/vm.py
1 file changed, 63 insertions(+), 76 deletions(-)
git pull ssh://gerrit.ovirt.org:29418/vdsm refs/changes/94/17694/1
diff --git a/vdsm/vm.py b/vdsm/vm.py
index dc52909..e51050e 100644
--- a/vdsm/vm.py
+++ b/vdsm/vm.py
@@ -1698,6 +1698,7 @@
self._guestSocketFile = self._makeChannelPath(_VMCHANNEL_DEVICE_NAME)
self._qemuguestSocketFile = self._makeChannelPath(_QEMU_GA_DEVICE_NAME)
self._lastXMLDesc = '<domain><uuid>%s</uuid></domain>' % self.id
+ self._lastParsedXmlDesc = _domParseStr(self._lastXMLDesc)
self._devXmlHash = '0'
self._released = False
self._releaseLock = threading.Lock()
@@ -2722,24 +2723,30 @@
self._guestCpuRunning = (self._dom.info()[0] ==
libvirt.VIR_DOMAIN_RUNNING)
+ def _getDevicesXml(self, parsedXml=None):
+ parsedXml = parsedXml or self._lastParsedXmlDesc
+ return parsedXml.childNodes[0].getElementsByTagName('devices')[0]
+
def _getUnderlyingVmDevicesInfo(self):
"""
Obtain underlying vm's devices info from libvirt.
"""
- self._getUnderlyingNetworkInterfaceInfo()
- self._getUnderlyingDriveInfo()
- self._getUnderlyingDisplayPort()
- self._getUnderlyingSoundDeviceInfo()
- self._getUnderlyingVideoDeviceInfo()
- self._getUnderlyingControllerDeviceInfo()
- self._getUnderlyingBalloonDeviceInfo()
- self._getUnderlyingWatchdogDeviceInfo()
- self._getUnderlyingSmartcardDeviceInfo()
- self._getUnderlyingConsoleDeviceInfo()
+ devicesXml = self._getDevicesXml(parsedXml=self._lastParsedXmlDesc)
+ self._getUnderlyingNetworkInterfaceInfo(devicesXml=devicesXml)
+ self._getUnderlyingDriveInfo(devicesXml=devicesXml)
+ self._getUnderlyingDisplayPort(xml=self._lastParsedXmlDesc)
+ self._getUnderlyingSoundDeviceInfo(devicesXml=devicesXml)
+ self._getUnderlyingVideoDeviceInfo(devicesXml=devicesXml)
+ self._getUnderlyingControllerDeviceInfo(devicesXml=devicesXml)
+ self._getUnderlyingBalloonDeviceInfo(devicesXml=devicesXml)
+ self._getUnderlyingWatchdogDeviceInfo(devicesXml=devicesXml)
+ self._getUnderlyingSmartcardDeviceInfo(devicesXml=devicesXml)
+ self._getUnderlyingConsoleDeviceInfo(devicesXml=devicesXml)
# Obtain info of all unknown devices. Must be last!
- self._getUnderlyingUnknownDeviceInfo()
+ self._getUnderlyingUnknownDeviceInfo(devicesXml=devicesXml)
+ self._updateAgentChannels(devicesXml=devicesXml)
- def _updateAgentChannels(self):
+ def _updateAgentChannels(self, devicesXml):
"""
We moved the naming of guest agent channel sockets. To keep backwards
compatability we need to make symlinks from the old channel sockets, to
@@ -2747,9 +2754,7 @@
This is necessary to prevent incoming migrations, restoring of VMs and
the upgrade of VDSM with running VMs to fail on this.
"""
- agentChannelXml = _domParseStr(self._lastXMLDesc).childNodes[0]. \
- getElementsByTagName('devices')[0]. \
- getElementsByTagName('channel')
+ agentChannelXml = devicesXml.getElementsByTagName('channel')
for channel in agentChannelXml:
try:
name = channel.getElementsByTagName('target')[0].\
@@ -2781,7 +2786,6 @@
self._getUnderlyingVmInfo()
self._getUnderlyingVmDevicesInfo()
- self._updateAgentChannels()
#Currently there is no protection agains mirroring a network twice,
for nic in self._devices[NIC_DEVICES]:
@@ -2937,9 +2941,8 @@
or revert to snapshot.
"""
parsedSrcDomXML = _domParseStr(srcDomXML)
-
- allDiskDeviceXmlElements = parsedSrcDomXML.childNodes[0]. \
- getElementsByTagName('devices')[0].getElementsByTagName('disk')
+ devicesXml = self._getDevicesXml(parsedXml=parsedSrcDomXML)
+ allDiskDeviceXmlElements = devicesXml.getElementsByTagName('disk')
snappableDiskDeviceXmlElements = \
_filterSnappableDiskDevices(allDiskDeviceXmlElements)
@@ -3008,7 +3011,8 @@
with self._confLock:
self.conf['devices'].append(nicParams)
self.saveState()
- self._getUnderlyingNetworkInterfaceInfo()
+ self._getUnderlyingNetworkInterfaceInfo(
+ devicesXml=self._getDevicesXml())
hooks.after_nic_hotplug(nicXml, self.conf,
params=customProps)
@@ -3264,7 +3268,7 @@
with self._confLock:
self.conf['devices'].append(diskParams)
self.saveState()
- self._getUnderlyingDriveInfo()
+ self._getUnderlyingDriveInfo(devicesXml=self._getDevicesXml())
hooks.after_disk_hotplug(driveXml, self.conf,
params=customProps)
@@ -4181,8 +4185,8 @@
def _getUnderlyingVmInfo(self):
self._lastXMLDesc = self._dom.XMLDesc(0)
- devxml = _domParseStr(self._lastXMLDesc).childNodes[0]. \
- getElementsByTagName('devices')[0]
+ self._lastParsedXmlDesc = _domParseStr(self._lastXMLDesc)
+ devxml = self._getDevicesXml()
self._devXmlHash = str(hash(devxml.toxml()))
return self._lastXMLDesc
@@ -4331,6 +4335,9 @@
self.saveState()
return {'status': doneCode}
+ def _getUnderlyingDeviceAliasName(self, devXml):
+ return devXml.getElementsByTagName('alias')[0].getAttribute('name')
+
def _getUnderlyingDeviceAddress(self, devXml):
"""
Obtain device's address from libvirt
@@ -4347,7 +4354,7 @@
return address
- def _getUnderlyingUnknownDeviceInfo(self):
+ def _getUnderlyingUnknownDeviceInfo(self, devicesXml):
"""
Obtain unknown devices info from libvirt.
@@ -4360,16 +4367,13 @@
return True
return False
- devsxml = _domParseStr(self._lastXMLDesc).childNodes[0]. \
- getElementsByTagName('devices')[0]
-
- for x in devsxml.childNodes:
+ for x in devicesXml.childNodes:
# Ignore empty nodes and devices without address
if (x.nodeName == '#text' or
not x.getElementsByTagName('address')):
continue
- alias = x.getElementsByTagName('alias')[0].getAttribute('name')
+ alias = self._getUnderlyingDeviceAliasName(x)
if not isKnownDevice(alias):
address = self._getUnderlyingDeviceAddress(x)
# I general case we assume that device has attribute 'type',
@@ -4381,18 +4385,16 @@
'address': address}
self.conf['devices'].append(newDev)
- def _getUnderlyingControllerDeviceInfo(self):
+ def _getUnderlyingControllerDeviceInfo(self, devicesXml):
"""
Obtain controller devices info from libvirt.
"""
- ctrlsxml = _domParseStr(self._lastXMLDesc).childNodes[0]. \
- getElementsByTagName('devices')[0]. \
- getElementsByTagName('controller')
+ ctrlsxml = devicesXml.getElementsByTagName('controller')
for x in ctrlsxml:
# Ignore controller devices without address
if not x.getElementsByTagName('address'):
continue
- alias = x.getElementsByTagName('alias')[0].getAttribute('name')
+ alias = self._getUnderlyingDeviceAliasName(x)
device = x.getAttribute('type')
# Get model and index. Relevant for USB controllers.
model = x.getAttribute('model')
@@ -4428,20 +4430,18 @@
'address': address,
'alias': alias})
- def _getUnderlyingBalloonDeviceInfo(self):
+ def _getUnderlyingBalloonDeviceInfo(self, devicesXml):
"""
Obtain balloon device info from libvirt.
"""
- balloonxml = _domParseStr(self._lastXMLDesc).childNodes[0]. \
- getElementsByTagName('devices')[0]. \
- getElementsByTagName('memballoon')
+ balloonxml = devicesXml.getElementsByTagName('memballoon')
for x in balloonxml:
# Ignore balloon devices without address.
if not x.getElementsByTagName('address'):
address = None
else:
address = self._getUnderlyingDeviceAddress(x)
- alias = x.getElementsByTagName('alias')[0].getAttribute('name')
+ alias = self._getUnderlyingDeviceAliasName(x)
for dev in self._devices[BALLOON_DEVICES]:
if address and not hasattr(dev, 'address'):
@@ -4456,16 +4456,14 @@
if not dev.get('alias'):
dev['alias'] = alias
- def _getUnderlyingConsoleDeviceInfo(self):
+ def _getUnderlyingConsoleDeviceInfo(self, devicesXml):
"""
Obtain the alias for the console device from libvirt
"""
- consolexml = _domParseStr(self._lastXMLDesc).childNodes[0].\
- getElementsByTagName('devices')[0].\
- getElementsByTagName('console')
+ consolexml = devicesXml.getElementsByTagName('console')
for x in consolexml:
# All we care about is the alias
- alias = x.getElementsByTagName('alias')[0].getAttribute('name')
+ alias = self._getUnderlyingDeviceAliasName(x)
for dev in self._devices[CONSOLE_DEVICES]:
if not hasattr(dev, 'alias'):
dev.alias = alias
@@ -4475,19 +4473,17 @@
not dev.get('alias'):
dev['alias'] = alias
- def _getUnderlyingSmartcardDeviceInfo(self):
+ def _getUnderlyingSmartcardDeviceInfo(self, devicesXml):
"""
Obtain smartcard device info from libvirt.
"""
- smartcardxml = _domParseStr(self._lastXMLDesc).childNodes[0].\
- getElementsByTagName('devices')[0].\
- getElementsByTagName('smartcard')
+ smartcardxml = devicesXml.getElementsByTagName('smartcard')
for x in smartcardxml:
if not x.getElementsByTagName('address'):
continue
address = self._getUnderlyingDeviceAddress(x)
- alias = x.getElementsByTagName('alias')[0].getAttribute('name')
+ alias = self._getUnderlyingDeviceAliasName(x)
for dev in self._devices[SMARTCARD_DEVICES]:
if not hasattr(dev, 'address'):
@@ -4500,19 +4496,17 @@
dev['address'] = address
dev['alias'] = alias
- def _getUnderlyingWatchdogDeviceInfo(self):
+ def _getUnderlyingWatchdogDeviceInfo(self, devicesXml):
"""
Obtain watchdog device info from libvirt.
"""
- watchdogxml = _domParseStr(self._lastXMLDesc).childNodes[0]. \
- getElementsByTagName('devices')[0]. \
- getElementsByTagName('watchdog')
+ watchdogxml = devicesXml.getElementsByTagName('watchdog')
for x in watchdogxml:
# PCI watchdog has "address" different from ISA watchdog
if x.getElementsByTagName('address'):
address = self._getUnderlyingDeviceAddress(x)
- alias = x.getElementsByTagName('alias')[0].getAttribute('name')
+ alias = self._getUnderlyingDeviceAliasName(x)
for wd in self._devices[WATCHDOG_DEVICES]:
if not hasattr(wd, 'address') or not hasattr(wd, 'alias'):
@@ -4525,14 +4519,13 @@
dev['address'] = address
dev['alias'] = alias
- def _getUnderlyingVideoDeviceInfo(self):
+ def _getUnderlyingVideoDeviceInfo(self, devicesXml):
"""
Obtain video devices info from libvirt.
"""
- videosxml = _domParseStr(self._lastXMLDesc).childNodes[0]. \
- getElementsByTagName('devices')[0].getElementsByTagName('video')
+ videosxml = devicesXml.getElementsByTagName('video')
for x in videosxml:
- alias = x.getElementsByTagName('alias')[0].getAttribute('name')
+ alias = self._getUnderlyingDeviceAliasName(x)
# Get video card address
address = self._getUnderlyingDeviceAddress(x)
@@ -4553,14 +4546,13 @@
dev['alias'] = alias
break
- def _getUnderlyingSoundDeviceInfo(self):
+ def _getUnderlyingSoundDeviceInfo(self, devicesXml):
"""
Obtain sound devices info from libvirt.
"""
- soundsxml = _domParseStr(self._lastXMLDesc).childNodes[0]. \
- getElementsByTagName('devices')[0].getElementsByTagName('sound')
+ soundsxml = devicesXml.getElementsByTagName('sound')
for x in soundsxml:
- alias = x.getElementsByTagName('alias')[0].getAttribute('name')
+ alias = self._getUnderlyingDeviceAliasName(x)
# Get sound card address
address = self._getUnderlyingDeviceAddress(x)
@@ -4581,12 +4573,11 @@
dev['alias'] = alias
break
- def _getUnderlyingDriveInfo(self):
+ def _getUnderlyingDriveInfo(self, devicesXml):
"""
Obtain block devices info from libvirt.
"""
- disksxml = _domParseStr(self._lastXMLDesc).childNodes[0]. \
- getElementsByTagName('devices')[0].getElementsByTagName('disk')
+ disksxml = devicesXml.getElementsByTagName('disk')
# FIXME! We need to gather as much info as possible from the libvirt.
# In the future we can return this real data to management instead of
# vm's conf
@@ -4600,7 +4591,7 @@
target = x.getElementsByTagName('target')
name = target[0].getAttribute('dev') if target else ''
- alias = x.getElementsByTagName('alias')[0].getAttribute('name')
+ alias = self._getUnderlyingDeviceAliasName(x)
readonly = bool(x.getElementsByTagName('readonly'))
boot = x.getElementsByTagName('boot')
bootOrder = boot[0].getAttribute('order') if boot else ''
@@ -4646,12 +4637,11 @@
diskDev['bootOrder'] = bootOrder
self.conf['devices'].append(diskDev)
- def _getUnderlyingDisplayPort(self):
+ def _getUnderlyingDisplayPort(self, xml):
"""
Obtain display port info from libvirt.
"""
- graphics = _domParseStr(self._lastXMLDesc).childNodes[0]. \
- getElementsByTagName('graphics')[0]
+ graphics = xml.childNodes[0].getElementsByTagName('graphics')[0]
port = graphics.getAttribute('port')
if port:
self.conf['displayPort'] = port
@@ -4659,18 +4649,16 @@
if port:
self.conf['displaySecurePort'] = port
- def _getUnderlyingNetworkInterfaceInfo(self):
+ def _getUnderlyingNetworkInterfaceInfo(self, devicesXml):
"""
Obtain network interface info from libvirt.
"""
# TODO use xpath instead of parseString (here and elsewhere)
- ifsxml = _domParseStr(self._lastXMLDesc).childNodes[0]. \
- getElementsByTagName('devices')[0]. \
- getElementsByTagName('interface')
+ ifsxml = devicesXml.getElementsByTagName('interface')
for x in ifsxml:
devType = x.getAttribute('type')
mac = x.getElementsByTagName('mac')[0].getAttribute('address')
- alias = x.getElementsByTagName('alias')[0].getAttribute('name')
+ alias = self._getUnderlyingDeviceAliasName(x)
if devType == 'hostdev':
name = alias
model = 'passthrough'
@@ -4802,8 +4790,7 @@
"during migration at destination host" %
devType)
- devices = _domParseStr(xml).childNodes[0]. \
- getElementsByTagName('devices')[0]
+ devices = self._getDevicesXml(parsedXml=_domParseStr(xml))
for deviceXML in devices.childNodes:
if deviceXML.nodeType != Node.ELEMENT_NODE:
--
To view, visit http://gerrit.ovirt.org/17694
To unsubscribe, visit http://gerrit.ovirt.org/settings
Gerrit-MessageType: newchange
Gerrit-Change-Id: I7e106b2f2d3f4160d4e882f1a2880cb1b52fbb22
Gerrit-PatchSet: 1
Gerrit-Project: vdsm
Gerrit-Branch: master
Gerrit-Owner: Vinzenz Feenstra <vfeenstr(a)redhat.com>
8 years, 7 months
Change in vdsm[master]: add xmlrpcTests for cpu pinning
by lvroyce@linux.vnet.ibm.com
Royce Lv has uploaded a new change for review.
Change subject: add xmlrpcTests for cpu pinning
......................................................................
add xmlrpcTests for cpu pinning
Change-Id: Ia865f0d5eb4c9aabff6cef57b088c55df73a309e
Signed-off-by: Royce Lv<lvroyce(a)linux.vnet.ibm.com>
---
M tests/functional/xmlrpcTests.py
M tests/vdsClientTests.py
2 files changed, 40 insertions(+), 0 deletions(-)
git pull ssh://gerrit.ovirt.org:29418/vdsm refs/changes/12/8412/1
diff --git a/tests/functional/xmlrpcTests.py b/tests/functional/xmlrpcTests.py
index 9c865db..2684d0f 100644
--- a/tests/functional/xmlrpcTests.py
+++ b/tests/functional/xmlrpcTests.py
@@ -174,3 +174,33 @@
destroyResult = self.s.destroy(VMID)
self.assertVdsOK(destroyResult)
+
+ def testCpuPin(self):
+ self.skipNoKVM()
+
+ def assertVMAndGuestUp():
+ self.assertVmUp(VMID)
+ self.assertGuestUp(VMID)
+
+ VMID = '77777777-ffff-3333-aaaa-222222222222'
+
+ with kernelBootImages() as (kernelPath, initramfsPath):
+ conf = {'display': 'vnc',
+ 'kernel': kernelPath,
+ 'initrd': initramfsPath,
+ 'kernelArgs': 'rd.break=cmdline rd.shell rd.skipfsck',
+ 'kvmEnable': 'true',
+ 'memSize': '256',
+ 'vmId': VMID,
+ 'vmName': 'vdsm_testPinVM',
+ 'vmType': 'kvm',
+ 'cpuPinning': {'emulator': '0', '0': '1'}}
+
+ try:
+ self.assertVdsOK(self.s.create(conf))
+ # wait 65 seconds for VM to come up until timeout
+ self.retryAssert(assertVMAndGuestUp, 65, 1)
+ finally:
+ destroyResult = self.s.destroy(VMID)
+
+ self.assertVdsOK(destroyResult)
diff --git a/tests/vdsClientTests.py b/tests/vdsClientTests.py
index abf3242..57e6e74 100644
--- a/tests/vdsClientTests.py
+++ b/tests/vdsClientTests.py
@@ -118,3 +118,13 @@
allArgs[-1] = 'cpuPinning={0:1,1:0}'
r4 = serv.do_create(['/dev/null'] + allArgs)
self.assertNotEquals(r4, expectResult)
+
+ # test just pin emulator
+ allArgs[-1] = "cpuPinning={emulator:1-3}"
+ r5 = serv.do_create(['/dev/null'] + allArgs)
+ self.assertEquals(r5['cpuPinning'],{'emulator':'1-3'})
+
+ # test pin emultor and vcpu
+ allArgs[-1] = "cpuPinning={emulator:1-3,1:0}"
+ r6 = serv.do_create(['/dev/null'] + allArgs)
+ self.assertEquals(r6['cpuPinning'],{'emulator':'1-3','1':'0'})
--
To view, visit http://gerrit.ovirt.org/8412
To unsubscribe, visit http://gerrit.ovirt.org/settings
Gerrit-MessageType: newchange
Gerrit-Change-Id: Ia865f0d5eb4c9aabff6cef57b088c55df73a309e
Gerrit-PatchSet: 1
Gerrit-Project: vdsm
Gerrit-Branch: master
Gerrit-Owner: Royce Lv <lvroyce(a)linux.vnet.ibm.com>
8 years, 8 months
Change in vdsm[master]: [WIP]add simple balloon functional testcase
by lvroyce@linux.vnet.ibm.com
Royce Lv has uploaded a new change for review.
Change subject: [WIP]add simple balloon functional testcase
......................................................................
[WIP]add simple balloon functional testcase
Change-Id: Ie8140fe1c754d9d4026c503a19420e6552a3f4fe
Signed-off-by: Royce Lv<lvroyce(a)linux.vnet.ibm.com>
---
M tests/functional/xmlrpcTests.py
1 file changed, 34 insertions(+), 0 deletions(-)
git pull ssh://gerrit.ovirt.org:29418/vdsm refs/changes/20/12820/1
diff --git a/tests/functional/xmlrpcTests.py b/tests/functional/xmlrpcTests.py
index 3eb65e4..88dd2c5 100644
--- a/tests/functional/xmlrpcTests.py
+++ b/tests/functional/xmlrpcTests.py
@@ -19,6 +19,7 @@
#
import os
+import time
import tempfile
import pwd
import grp
@@ -29,6 +30,7 @@
from testrunner import VdsmTestCase as TestCaseBase
from testrunner import permutations, expandPermutations
from nose.plugins.skip import SkipTest
+from momTests import skipNoMOM
try:
import rtslib
except ImportError:
@@ -169,6 +171,38 @@
with RollbackContext() as rollback:
self._runVMKernelBootTemplate(rollback, customization)
+ @skipNoKVM
+ @skipNoMOM
+ def testSmallVMBallooning(self):
+ policyStr = """
+ (def set_guest (guest)
+ {
+ (guest.Control "balloon_target" 0)
+ })
+ (with Guests guest (set_guest guest))"""
+ balloonSpec = {'device': 'memballoon',
+ 'type': 'balloon',
+ 'specParams': {'model': 'virtio'}}
+ customization = {'vmId': '77777777-ffff-3333-bbbb-555555555555',
+ 'vmName': 'vdsm_testBalloonVM',
+ 'devices': [balloonSpec]}
+ policy = {'balloon': policyStr}
+
+ with RollbackContext() as rollback:
+ self._runVMKernelBootTemplate(rollback, customization)
+ self._enableBalloonPolicy(policy, rollback)
+ time.sleep(12) # MOM policy engine wake up evey 10s
+ balloonInf = self.s.getVmStats(
+ customization['vmId'])['statsList'][0]['balloonInfo']
+ self.assertEqual(balloonInf['balloon_cur'], 0)
+
+ def _enableBalloonPolicy(self, policy, rollback):
+ r = self.s.setMOMPolicy(policy)
+ self.assertVdsOK(r)
+ undo = lambda: \
+ self.assertVdsOK(self.s.resetMOMPolicy())
+ rollback.prependDefer(undo)
+
def _runVMKernelBootTemplate(self, rollback, vmDef={}, distro='fedora'):
kernelArgsDistro = {
# Fedora: The initramfs is generated by dracut. The following
--
To view, visit http://gerrit.ovirt.org/12820
To unsubscribe, visit http://gerrit.ovirt.org/settings
Gerrit-MessageType: newchange
Gerrit-Change-Id: Ie8140fe1c754d9d4026c503a19420e6552a3f4fe
Gerrit-PatchSet: 1
Gerrit-Project: vdsm
Gerrit-Branch: master
Gerrit-Owner: Royce Lv <lvroyce(a)linux.vnet.ibm.com>
8 years, 9 months