Skip to content

Commit 2c24f41

Browse files
author
Eric Diven
committed
Add presto yarn package install and uninstall
The presto-yarn package is installed and uninstalled by running slider commands on the slider master. Product tests for the new functionality check both that: 1) The package ends up in the right place in HDFS 2) Slider recognizes that the package has been installed Doing 2. requires running slider as the configured user; this required updating docker-py to support the user= kwarg to exec_create, which in turn required updating how we pass the mem_limit parameter in docker_cluster.py. Testing: unit tests, product tests, some manual testing.
1 parent 4ed65ae commit 2c24f41

28 files changed

+633
-180
lines changed

.gitignore

+3
Original file line numberDiff line numberDiff line change
@@ -31,3 +31,6 @@ dist/
3131

3232
#mvn targets
3333
presto-admin-test/target
34+
35+
# presto yarn package for product tests
36+
presto-yarn-package.zip

prestoadmin/__init__.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -42,5 +42,5 @@
4242
import package
4343
import script
4444
import server
45-
import slider.server as slider
45+
import yarn_slider.server as slider
4646
import topology

prestoadmin/main.py

+21-2
Original file line numberDiff line numberDiff line change
@@ -852,10 +852,29 @@ def _exit_code(results):
852852
If every entry in the dict has a value of None, the exit code is 0.
853853
If any entry has a value that is not None, something failed, and we should
854854
exit with a non-zero exit code.
855+
856+
That isn't really the whole story: Any task that calls tasks.execute() and
857+
returns that as the result will have an item in the dictionary of the form
858+
hostname: {hostname: Exception | None}. This means that we need to
859+
recursively check any values in the map that are of type dict following the
860+
above scheme.
855861
"""
856862
for v in results.values():
857-
if v is not None:
858-
return 1
863+
# No exception, inspect the next value.
864+
if v is None:
865+
continue
866+
867+
# The value is a dict resulting from calling fabric.tasks.execute.
868+
# Check the results recursively
869+
if type(v) is dict:
870+
exit_code = _exit_code(v)
871+
if exit_code != 0:
872+
return exit_code
873+
continue
874+
875+
# In any case where things were OK above, we've continued the loop. At
876+
# this point, we know something failed.
877+
return 1
859878
return 0
860879

861880

prestoadmin/slider/server.py

-67
This file was deleted.

prestoadmin/standalone/config.py

+7-1
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,8 @@
1717
"""
1818
from fabric.api import env
1919

20+
from overrides import overrides
21+
2022
from prestoadmin import config
2123
from prestoadmin.util import constants
2224
from prestoadmin.util.base_config import BaseConfig, SingleConfigItem
@@ -135,7 +137,8 @@ def __init__(self):
135137
super(StandaloneConfig, self).__init__(constants.TOPOLOGY_CONFIG_PATH,
136138
_TOPOLOGY_CONFIG)
137139

138-
def load_conf(self):
140+
@overrides
141+
def read_conf(self):
139142
conf = self._get_conf_from_file()
140143
config.fill_defaults(conf, DEFAULT_PROPERTIES)
141144
validate(conf)
@@ -144,13 +147,16 @@ def load_conf(self):
144147
def _get_conf_from_file(self):
145148
return config.get_conf_from_json_file(self.config_path)
146149

150+
@overrides
147151
def is_config_loaded(self):
148152
return STANDALONE_CONFIG_LOADED in env and \
149153
env[STANDALONE_CONFIG_LOADED]
150154

155+
@overrides
151156
def set_config_loaded(self):
152157
env[STANDALONE_CONFIG_LOADED] = True
153158

159+
@overrides
154160
def set_env_from_conf(self, conf):
155161
env.user = conf['username']
156162
env.port = conf['port']

prestoadmin/util/base_config.py

+4-4
Original file line numberDiff line numberDiff line change
@@ -104,10 +104,10 @@ def __init__(self, config_path, config_items):
104104
self.config_path = config_path
105105
self.config_items = config_items
106106

107-
def load_conf(self):
107+
def read_conf(self):
108108
return config.get_conf_from_json_file(self.config_path)
109109

110-
def store_conf(self, conf):
110+
def write_conf(self, conf):
111111
config.write(config.json_to_string(conf), self.config_path)
112112
return self.config_path
113113

@@ -122,10 +122,10 @@ def get_config(self):
122122
if not self.is_config_loaded():
123123
conf = {}
124124
try:
125-
conf = self.load_conf()
125+
conf = self.read_conf()
126126
except ConfigFileNotFoundError:
127127
conf = self.get_conf_interactive()
128-
self.store_conf(conf)
128+
self.write_conf(conf)
129129

130130
self.set_env_from_conf(conf)
131131
self.set_config_loaded()
File renamed without changes.

prestoadmin/slider/config.py prestoadmin/yarn_slider/config.py

+42-7
Original file line numberDiff line numberDiff line change
@@ -14,11 +14,13 @@
1414

1515

1616
"""
17-
Module for setting and validating the presto-admin slider config
17+
Module for setting and validating the presto-admin Apache Slider config
1818
"""
1919

2020
import os
2121

22+
from overrides import overrides
23+
2224
from fabric.state import env
2325

2426
from prestoadmin.util.base_config import BaseConfig, SingleConfigItem, \
@@ -28,7 +30,8 @@
2830
validate_username, validate_can_connect, validate_can_sudo
2931

3032
SLIDER_CONFIG_LOADED = 'slider_config_loaded'
31-
SLIDER_CONFIG_PATH = os.path.join(LOCAL_CONF_DIR, 'slider', 'config.json')
33+
SLIDER_CONFIG_DIR = os.path.join(LOCAL_CONF_DIR, 'slider')
34+
SLIDER_CONFIG_PATH = os.path.join(SLIDER_CONFIG_DIR, 'config.json')
3235
SLIDER_MASTER = 'slider_master'
3336

3437
HOST = 'slider_master'
@@ -42,6 +45,10 @@
4245
JAVA_HOME = 'JAVA_HOME'
4346
HADOOP_CONF = 'HADOOP_CONF'
4447

48+
# This key comes from the server install step, NOT a user prompt. Accordingly,
49+
# there is no SliderConfigItem for it in _SLIDER_CONFIG
50+
PRESTO_PACKAGE = 'presto_slider_package'
51+
4552

4653
_SLIDER_CONFIG = [
4754
MultiConfigItem([
@@ -57,12 +64,12 @@
5764
'Connection failed for %%(%s)s@%%(%s)s:%%(%s)d. ' +
5865
'Re-enter connection information.'),
5966

60-
SingleConfigItem(DIR, 'Enter the directory to install slider into on ' +
67+
SingleConfigItem(DIR, 'Enter the directory to install slider into on '
6168
'the slider master:', '/opt/slider', None),
6269

6370
MultiConfigItem([
64-
SingleConfigItem(SLIDER_USER, 'Enter a user name for conducting ' +
65-
'slider operations on the slider master ', 'yarn',
71+
SingleConfigItem(SLIDER_USER, 'Enter a user name for running slider '
72+
'on the slider master ', 'yarn',
6673
validate_username)],
6774
validate_can_sudo,
6875
(SLIDER_USER, ADMIN_USER, HOST, SSH_PORT),
@@ -75,26 +82,54 @@
7582
'/usr/lib/jvm/java', None),
7683
SingleConfigItem(HADOOP_CONF, 'Enter the location of the Hadoop ' +
7784
'configuration on the slider master:',
78-
'/etc/hadoop/conf', None)]
85+
'/etc/hadoop/conf', None),
86+
SingleConfigItem(APPNAME, 'Enter a name for the presto slider application',
87+
'PRESTO', None)]
7988

8089

8190
class SliderConfig(BaseConfig):
91+
'''
92+
presto-admin needs to update the slider config other than through the
93+
interactive config process because it needs to keep track of the name
94+
of the presto-yarn-package we install.
95+
96+
As a result, SliderConfig acts a little funny; it acts like enough of a
97+
dict to allow env.conf[NAME] lookups and modifications, and it also exposes
98+
the ability to store the config after it's been modified.
99+
'''
82100

83101
def __init__(self):
84102
super(SliderConfig, self).__init__(SLIDER_CONFIG_PATH, _SLIDER_CONFIG)
103+
self.config = {}
104+
105+
def __getitem__(self, key):
106+
return self.config[key]
85107

108+
def __setitem__(self, key, value):
109+
self.config[key] = value
110+
111+
def __delitem__(self, key):
112+
del self.config[key]
113+
114+
@overrides
86115
def is_config_loaded(self):
87116
return SLIDER_CONFIG_LOADED in env and env[SLIDER_CONFIG_LOADED]
88117

118+
@overrides
89119
def set_config_loaded(self):
90120
env[SLIDER_CONFIG_LOADED] = True
91121

122+
@overrides
92123
def set_env_from_conf(self, conf):
124+
self.config.update(conf)
93125
env.user = conf[ADMIN_USER]
94126
env.port = conf[SSH_PORT]
95127
env.roledefs[SLIDER_MASTER] = [conf[HOST]]
96128
env.roledefs['all'] = env.roledefs[SLIDER_MASTER]
97129

98-
env.conf = conf
130+
env.conf = self
99131

100132
env.hosts = env.roledefs['all'][:]
133+
134+
def store_conf(self):
135+
super(SliderConfig, self).write_conf(self.config)

0 commit comments

Comments
 (0)