Skip to content

Instantly share code, notes, and snippets.

@rca
Created March 21, 2018 16:14
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save rca/fc560f63c3b5fa4ba6696aa902d25033 to your computer and use it in GitHub Desktop.
Save rca/fc560f63c3b5fa4ba6696aa902d25033 to your computer and use it in GitHub Desktop.
Script to list service ports and get next available port
#!/usr/bin/env python3.6
import argparse
import logging
import re
import shlex
import sh
PORT_RE = re.compile(r':(?P<port>\d+)->')
MIN_PORT = 1024
def get_next_port(used_ports):
next_port = MIN_PORT
while next_port < 65536:
if next_port not in used_ports:
break
return next_port
def get_services():
command = "docker service ls --format '{{ .Name }} {{ .Ports }}'"
command_split = shlex.split(command)
proc = sh.docker(*command_split[1:])
for line in proc.stdout.decode('utf8').splitlines():
line = line.strip()
if line == '':
continue
if ' ' not in line:
continue
yield line
def get_used_ports():
ports = []
for line in get_services():
line_split = line.split(' ', 1)
if len(line_split) < 2:
continue
_ports = line_split[-1]
for matches in PORT_RE.finditer(_ports):
ports.append(int(matches.group('port')))
return sorted(ports)
def main():
parser = argparse.ArgumentParser()
parser.add_argument('--loglevel', '-l', default='warn', help='set logging level; default warn')
parser.add_argument('--next', action='store_true', help='returns the next port')
args = parser.parse_args()
logging.basicConfig(level=getattr(logging, args.loglevel.upper()))
logger = logging.getLogger('main')
if args.next:
used_ports = get_used_ports()
next_port = get_next_port(used_ports)
logger.info(f'used_ports={used_ports}')
print(next_port)
else:
for line in get_services():
print(line)
if __name__ == '__main__':
main()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment