Skip to content

Commit 4003921

Browse files
author
Gabriel Monroy
committed
feat(client): add commands for managing memory/cpu limits
1 parent b01033b commit 4003921

1 file changed

Lines changed: 146 additions & 0 deletions

File tree

client/deis.py

Lines changed: 146 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
config manage environment variables that define app config
1919
domains manage and assign domain names to your applications
2020
builds manage builds created using `git push`
21+
limit manage resource limits for your application
2122
releases manage releases of an application
2223
2324
keys manage ssh keys used for `git push` deployments
@@ -1345,6 +1346,151 @@ def domains_list(self, args):
13451346
else:
13461347
raise ResponseError(response)
13471348

1349+
def limit(self, args):
1350+
"""
1351+
Valid commands for limit:
1352+
1353+
limit:list list resource limits for an app
1354+
limit:set set resource limits for an app
1355+
limit:unset unset resource limits for an app
1356+
1357+
Use `deis help [command]` to learn more.
1358+
"""
1359+
sys.argv[1] = 'limit:list'
1360+
args = docopt(self.limit_list.__doc__)
1361+
return self.limit_list(args)
1362+
1363+
def limit_list(self, args):
1364+
"""
1365+
Lists resource limits for an application.
1366+
1367+
Usage: deis limit:list [options]
1368+
1369+
Options:
1370+
-a --app=<app>
1371+
the uniquely identifiable name of the application.
1372+
"""
1373+
app = args.get('--app')
1374+
if not app:
1375+
app = self._session.app
1376+
response = self._dispatch('get', "/api/apps/{}/limit".format(app))
1377+
if response.status_code == requests.codes.ok: # @UndefinedVariable
1378+
self._print_limits(app, response.json())
1379+
else:
1380+
raise ResponseError(response)
1381+
1382+
def limit_set(self, args):
1383+
"""
1384+
Sets resource limits for an application
1385+
1386+
Usage: deis limit:set [--memory | --cpu] <type>=<limit>... [options]
1387+
1388+
Arguments:
1389+
-m, --memory limit memory [default: true]
1390+
-c, --cpu limit cpu shares
1391+
<type>
1392+
the process type as defined in your Procfile, such as 'web' or 'worker'.
1393+
Note that Dockerfile apps have a default 'cmd' process type.
1394+
<limit>
1395+
web=1G worker=256M (with --memory, units in G/M/K/B)
1396+
cmd=1024 clock=100 (with --cpu, units in cpu shares)
1397+
1398+
Options:
1399+
-a --app=<app>
1400+
the uniquely identifiable name for the application.
1401+
"""
1402+
app = args.get('--app')
1403+
if not app:
1404+
app = self._session.app
1405+
body = {}
1406+
# see if cpu shares are being specified, otherwise default to memory
1407+
if args.get('--cpu'):
1408+
target = 'cpu'
1409+
else:
1410+
target = 'memory'
1411+
body[target] = json.dumps(dictify(args['<type>=<limit>']))
1412+
sys.stdout.write('Applying limits... ')
1413+
sys.stdout.flush()
1414+
try:
1415+
progress = TextProgress()
1416+
progress.start()
1417+
response = self._dispatch('post', "/api/apps/{}/limit".format(app), json.dumps(body))
1418+
finally:
1419+
progress.cancel()
1420+
progress.join()
1421+
if response.status_code == requests.codes.created: # @UndefinedVariable
1422+
version = response.headers['x-deis-release']
1423+
print("done, v{}\n".format(version))
1424+
1425+
self._print_limits(app, response.json())
1426+
else:
1427+
raise ResponseError(response)
1428+
1429+
def limit_unset(self, args):
1430+
"""
1431+
Unsets resource limits for an application.
1432+
1433+
Usage: deis limit:unset [--memory | --cpu] <type>... [options]
1434+
1435+
Arguments:
1436+
-m, --memory limit memory [default: true]
1437+
-c, --cpu limit cpu shares
1438+
<type>
1439+
the process type as defined in your Procfile, such as 'web' or 'worker'.
1440+
Note that Dockerfile apps have a default 'cmd' process type.
1441+
1442+
Options:
1443+
-a --app=<app>
1444+
the uniquely identifiable name for the application.
1445+
"""
1446+
app = args.get('--app')
1447+
if not app:
1448+
app = self._session.app
1449+
values = {}
1450+
for k in args.get('<type>'):
1451+
values[k] = None
1452+
body = {}
1453+
# see if cpu shares are being specified, otherwise default to memory
1454+
if args.get('--cpu'):
1455+
target = 'cpu'
1456+
else:
1457+
target = 'memory'
1458+
body[target] = json.dumps(values)
1459+
sys.stdout.write('Applying limits... ')
1460+
sys.stdout.flush()
1461+
try:
1462+
progress = TextProgress()
1463+
progress.start()
1464+
response = self._dispatch('post', "/api/apps/{}/limit".format(app), json.dumps(body))
1465+
finally:
1466+
progress.cancel()
1467+
progress.join()
1468+
if response.status_code == requests.codes.created: # @UndefinedVariable
1469+
version = response.headers['x-deis-release']
1470+
print("done, v{}\n".format(version))
1471+
self._print_limits(app, response.json())
1472+
else:
1473+
raise ResponseError(response)
1474+
1475+
def _print_limits(self, app, limit):
1476+
print("=== {} Limits".format(app))
1477+
1478+
def write(d):
1479+
items = d.items()
1480+
if len(items) == 0:
1481+
print('Unlimited')
1482+
return
1483+
keys = sorted(d)
1484+
width = max(map(len, keys)) + 5
1485+
for k in keys:
1486+
v = d[k]
1487+
print(("{k:<" + str(width) + "} {v}").format(**locals()))
1488+
1489+
print("\n--- Memory")
1490+
write(json.loads(limit.get('memory', '{}')))
1491+
print("\n--- CPU")
1492+
write(json.loads(limit.get('cpu', '{}')))
1493+
13481494
def ps(self, args):
13491495
"""
13501496
Valid commands for processes:

0 commit comments

Comments
 (0)