Skip to content

Commit

Permalink
Merge pull request #2851 from sgilbride/hotfix/8.1.3
Browse files Browse the repository at this point in the history
Fix VCP Install Agent Bug (hotfix 8.1.3)
  • Loading branch information
craig8 authored Jan 12, 2022
2 parents 6252865 + 55b2b75 commit 2f1c89d
Show file tree
Hide file tree
Showing 7 changed files with 65 additions and 72 deletions.
4 changes: 2 additions & 2 deletions docs/source/conf.py
Original file line number Diff line number Diff line change
Expand Up @@ -43,9 +43,9 @@ def __getattr__(cls, name):
author = 'The VOLTTRON Community'

# The short X.Y version
version = '8.1.2'
version = '8.1.3'
# The full version, including alpha/beta/rc tags
release = '8.1.2'
release = '8.1.3'


# -- General configuration ---------------------------------------------------
Expand Down
4 changes: 3 additions & 1 deletion services/core/VolttronCentral/tests/test_webapi.py
Original file line number Diff line number Diff line change
Expand Up @@ -299,10 +299,12 @@ def test_installagent(auto_registered_local):
print(f"Package is {hold}")
filestr = "base64,"+base64.b64encode(hold).decode('utf-8')
print(f"file string is {filestr}")
vip_id = f"test_listener_{random.randint(1,100000)}"
file_props = dict(
file_name=os.path.basename(agent_wheel),
file=filestr,
vip_identity='bar.full.{}'.format(random.randint(1, 100000))
vip_identity=vip_id,
force=True
)
gevent.sleep(5)
platform = webapi.list_platforms()[0]
Expand Down
30 changes: 25 additions & 5 deletions services/core/VolttronCentralPlatform/vcplatform/agent.py
Original file line number Diff line number Diff line change
Expand Up @@ -50,13 +50,15 @@
import tempfile
import urllib.parse
from collections import defaultdict
from argparse import Namespace

import gevent
import gevent.event
import psutil
from enum import Enum

from volttron.platform.agent import utils
from volttron.platform.install_agents import install_agent_local

utils.setup_logging()
_log = logging.getLogger(__name__)
Expand Down Expand Up @@ -129,7 +131,7 @@ class VolttronCentralPlatform(Agent):
def __init__(self, reconnect_interval, vc_address,
vc_serverkey, instance_name, stats_publish_interval,
topic_replace_map, device_status_interval, platform_driver_ids, **kwargs):
super(VolttronCentralPlatform, self).__init__(**kwargs)
super(VolttronCentralPlatform, self).__init__(enable_channel=True, **kwargs)

# This is scheduled after first call to the reconnect function
self._scheduled_connection_event = None
Expand Down Expand Up @@ -1147,6 +1149,14 @@ def _install_agent(self, fileargs):
try:
_log.debug('Installing agent FILEARGS: {}'.format(fileargs))
vip_identity = fileargs.get('vip_identity', None)
agent_tag = fileargs.get('tag', None)
agent_enable = fileargs.get('enable', None)
agent_start = fileargs.get('start', None)
agent_priority = fileargs.get('priority', -1)
agent_force = fileargs.get('force', False)
agent_csv = fileargs.get('csv', None)
agent_json = fileargs.get('json', None)
agent_st = fileargs.get('st', 5)
if 'local' in fileargs:
path = fileargs['file_name']
else:
Expand All @@ -1160,13 +1170,23 @@ def _install_agent(self, fileargs):
# after base64,
with open(path, 'wb') as fout:
fout.write(
base64.decodestring(
base64.decodebytes(
fileargs['file'].split(base64_sep)[1].encode('utf-8')
)
)
uuid = self.vip.rpc.call(CONTROL, 'install_agent_local',
path, vip_identity=vip_identity
).get(timeout=30)
opts = Namespace(connection=self._vc_connection,
install_path=path,
vip_identity=vip_identity,
tag=agent_tag,
enable=agent_enable,
start=agent_start,
priority=agent_priority,
force=agent_force,
csv=agent_csv,
json=agent_json,
st=agent_st
)
uuid = install_agent_local(opts)
result = dict(uuid=uuid)
except Exception as e:
err_str = "EXCEPTION: " + str(e)
Expand Down
65 changes: 8 additions & 57 deletions services/core/VolttronCentralPlatform/vcplatform/vcconnection.py
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@
import logging

from volttron.platform.agent.known_identities import (
VOLTTRON_CENTRAL)
VOLTTRON_CENTRAL, CONTROL)
from volttron.platform.vip.agent import (Agent, RPC)

_log = logging.getLogger(__name__)
Expand All @@ -59,6 +59,8 @@ def __init__(self, **kwargs):
self._log = logging.getLogger(self.__class__.__name__)
super(VCConnection, self).__init__(**kwargs)
self._main_agent = None
self.server = None
self.peer = CONTROL

def set_main_agent(self, main_agent):
"""
Expand All @@ -69,6 +71,7 @@ def set_main_agent(self, main_agent):
:type VolttronCentralPlatform:
"""
self._main_agent = main_agent
self.server = self._main_agent

def publish_to_vc(self, topic, message=None, headers={}):
"""
Expand Down Expand Up @@ -287,6 +290,10 @@ def subscription_wrapper(peer, sender, bus, topic, headers,
def call(self, platform_method, *args, **kwargs):
return self._main_agent.call(platform_method, *args, **kwargs)

def kill(self):
"""Dummy method to use install_agent_vctl"""
pass

def is_connected(self):
connected = self.vip.hello().get(timeout=5) is not None
self._log.debug("is_connected returning {}".format(connected))
Expand Down Expand Up @@ -328,35 +335,6 @@ def get_vip_addresses(self):
def get_instance_name(self):
return self._main_agent.get_instance_name()

@RPC.export
def start_agent(self, agent_uuid):
"""
Calls start_agent method on the vcp main agent instance.
.. note::
This method only valid for installed agents not dynamic agents.
:param agent_uuid:
:return:
"""
self._main_agent.start_agent(agent_uuid)

@RPC.export
def stop_agent(self, agent_uuid):
"""
Calls stop_agent method on the vcp main agent instance.
.. note::
This method only valid for installed agents not dynamic agents.
:param agent_uuid:
:return:
"""
proc_result = self._main_agent.stop_agent(agent_uuid)
return proc_result

@RPC.export
def restart_agent(self, agent_uuid):
"""
Expand All @@ -371,33 +349,6 @@ def restart_agent(self, agent_uuid):
"""
return self._main_agent.restart(agent_uuid)

@RPC.export
def agent_status(self, agent_uuid):
"""
Calls agent_status method on the vcp main agent instance.
.. note::
This method only valid for installed agents not dynamic agents.
:param agent_uuid:
:return:
"""
return self._main_agent.agent_status(agent_uuid)

@RPC.export
def status_agents(self):
"""
Calls status_agents method on the vcp main agent instance.
.. note::
This method only valid for installed agents not dynamic agents.
:return:
"""
return self._main_agent.status_agents()

@RPC.export
def list_agents(self):
"""
Expand Down
2 changes: 1 addition & 1 deletion volttron/platform/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@
from urllib.parse import urlparse

from ..utils.frozendict import FrozenDict
__version__ = '8.1.2'
__version__ = '8.1.3'

_log = logging.getLogger(__name__)

Expand Down
1 change: 1 addition & 0 deletions volttron/platform/control.py
Original file line number Diff line number Diff line change
Expand Up @@ -607,6 +607,7 @@ def _install_wheel_to_platform(
)
_log.debug(f"Returning {agent_uuid}")
return agent_uuid


@RPC.export
def install_agent(
Expand Down
31 changes: 25 additions & 6 deletions volttron/platform/install_agents.py
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,6 @@ def install_agent_directory(opts, publickey=None, secretkey=None):
if agent_default_id_file.is_file():
with open(str(agent_default_id_file)) as fin:
opts.vip_identity = fin.read().strip()
agent_uuid = None

# Verify and load agent_config up from the opts. agent_config will
# be a yaml config file.
Expand Down Expand Up @@ -141,7 +140,8 @@ def install_agent_directory(opts, publickey=None, secretkey=None):
except FileNotFoundError:
raise InstallRuntimeError(f"File not found: {config_file}")

_send_and_intialize_agent(opts, publickey, secretkey)
agent_uuid = _send_and_intialize_agent(opts, publickey, secretkey)
return agent_uuid


def _send_and_intialize_agent(opts, publickey, secretkey):
Expand Down Expand Up @@ -211,12 +211,27 @@ def _send_and_intialize_agent(opts, publickey, secretkey):
keyline += "%s" % keys[k]
valueline += "%s" % output_dict[keys[k]]
sys.stdout.write("%s\n%s\n" % (keyline, valueline))
return agent_uuid


def install_agent_vctl(opts, publickey=None, secretkey=None, callback=None):
"""
The `install_agent_vctl` function is called from the volttron-ctl or vctl install
sub-parser.
The `install_agent_vctl` function is called from the volttron-ctl or
vctl install sub-parser.
"""

agent_uuid = install_agent_local(opts, publickey=publickey,
secretkey=secretkey, callback=callback)
if agent_uuid:
return 0
else:
return 1


def install_agent_local(opts, publickey=None, secretkey=None, callback=None):
"""
Install agents via either directory or wheel
Used by VC and VCTL
"""
try:
install_path = opts.install_path
Expand All @@ -231,16 +246,20 @@ def install_agent_vctl(opts, publickey=None, secretkey=None, callback=None):
opts.connection.kill()
raise InstallRuntimeError("Identity already exists. Pass --force option to re-install.")

agent_uuid = None

if os.path.isdir(install_path):
install_agent_directory(opts, publickey, secretkey)
agent_uuid = install_agent_directory(opts, publickey, secretkey)
if opts.connection is not None:
opts.connection.kill()
else:
opts.package = opts.install_path
if not os.path.exists(opts.package):
opts.connection.kill()
raise FileNotFoundError(f"Invalid file {opts.package}")
_send_and_intialize_agent(opts, publickey, secretkey)
agent_uuid = _send_and_intialize_agent(opts, publickey, secretkey)

return agent_uuid


def send_agent(connection: "ControlConnection", wheel_file: str, vip_identity: str , publickey: str,
Expand Down

0 comments on commit 2f1c89d

Please sign in to comment.