portmgr 1.8.0.dev0__tar.gz → 1.8.0.dev1__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {portmgr-1.8.0.dev0 → portmgr-1.8.0.dev1}/PKG-INFO +1 -3
- {portmgr-1.8.0.dev0 → portmgr-1.8.0.dev1}/pyproject.toml +1 -1
- portmgr-1.8.0.dev1/src/portmgr/__init__.py +2 -0
- {portmgr-1.8.0.dev0 → portmgr-1.8.0.dev1/src}/portmgr.egg-info/PKG-INFO +1 -3
- portmgr-1.8.0.dev1/src/portmgr.egg-info/SOURCES.txt +10 -0
- portmgr-1.8.0.dev0/portmgr/__init__.py +0 -2
- portmgr-1.8.0.dev0/portmgr/__main__.py +0 -15
- portmgr-1.8.0.dev0/portmgr/commands/__init__.py +0 -0
- portmgr-1.8.0.dev0/portmgr/commands/attach.py +0 -51
- portmgr-1.8.0.dev0/portmgr/commands/build.py +0 -25
- portmgr-1.8.0.dev0/portmgr/commands/down.py +0 -27
- portmgr-1.8.0.dev0/portmgr/commands/logs.py +0 -19
- portmgr-1.8.0.dev0/portmgr/commands/ps.py +0 -19
- portmgr-1.8.0.dev0/portmgr/commands/pull.py +0 -19
- portmgr-1.8.0.dev0/portmgr/commands/push.py +0 -76
- portmgr-1.8.0.dev0/portmgr/commands/scan.py +0 -43
- portmgr-1.8.0.dev0/portmgr/commands/stats.py +0 -52
- portmgr-1.8.0.dev0/portmgr/commands/stop.py +0 -26
- portmgr-1.8.0.dev0/portmgr/commands/top.py +0 -18
- portmgr-1.8.0.dev0/portmgr/commands/up.py +0 -26
- portmgr-1.8.0.dev0/portmgr/portmgr.py +0 -170
- portmgr-1.8.0.dev0/portmgr/wrapper.py +0 -67
- portmgr-1.8.0.dev0/portmgr.egg-info/SOURCES.txt +0 -28
- portmgr-1.8.0.dev0/portmgr.egg-info/not-zip-safe +0 -1
- portmgr-1.8.0.dev0/setup.py +0 -26
- {portmgr-1.8.0.dev0 → portmgr-1.8.0.dev1}/LICENSE +0 -0
- {portmgr-1.8.0.dev0 → portmgr-1.8.0.dev1}/README.md +0 -0
- {portmgr-1.8.0.dev0 → portmgr-1.8.0.dev1}/setup.cfg +0 -0
- {portmgr-1.8.0.dev0 → portmgr-1.8.0.dev1/src}/portmgr.egg-info/dependency_links.txt +0 -0
- {portmgr-1.8.0.dev0 → portmgr-1.8.0.dev1/src}/portmgr.egg-info/entry_points.txt +0 -0
- {portmgr-1.8.0.dev0 → portmgr-1.8.0.dev1/src}/portmgr.egg-info/requires.txt +0 -0
- {portmgr-1.8.0.dev0 → portmgr-1.8.0.dev1/src}/portmgr.egg-info/top_level.txt +0 -0
|
@@ -1,8 +1,7 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: portmgr
|
|
3
|
-
Version: 1.8.0.
|
|
3
|
+
Version: 1.8.0.dev1
|
|
4
4
|
Summary: Simple command interface to manage multiple Docker container
|
|
5
|
-
Home-page: https://github.com/Craeckie/portmgr
|
|
6
5
|
License-Expression: MIT
|
|
7
6
|
Project-URL: Website, https://github.com/Craeckie/portmgr
|
|
8
7
|
Project-URL: Repository, https://github.com/Craeckie/portmgr.git
|
|
@@ -13,7 +12,6 @@ Requires-Dist: humanfriendly~=10.0
|
|
|
13
12
|
Requires-Dist: jsonschema~=3.2.0
|
|
14
13
|
Requires-Dist: pyyaml~=6.0.2
|
|
15
14
|
Requires-Dist: tabulate~=0.8.9
|
|
16
|
-
Dynamic: home-page
|
|
17
15
|
Dynamic: license-file
|
|
18
16
|
|
|
19
17
|
# portmgr
|
|
@@ -1,8 +1,7 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: portmgr
|
|
3
|
-
Version: 1.8.0.
|
|
3
|
+
Version: 1.8.0.dev1
|
|
4
4
|
Summary: Simple command interface to manage multiple Docker container
|
|
5
|
-
Home-page: https://github.com/Craeckie/portmgr
|
|
6
5
|
License-Expression: MIT
|
|
7
6
|
Project-URL: Website, https://github.com/Craeckie/portmgr
|
|
8
7
|
Project-URL: Repository, https://github.com/Craeckie/portmgr.git
|
|
@@ -13,7 +12,6 @@ Requires-Dist: humanfriendly~=10.0
|
|
|
13
12
|
Requires-Dist: jsonschema~=3.2.0
|
|
14
13
|
Requires-Dist: pyyaml~=6.0.2
|
|
15
14
|
Requires-Dist: tabulate~=0.8.9
|
|
16
|
-
Dynamic: home-page
|
|
17
15
|
Dynamic: license-file
|
|
18
16
|
|
|
19
17
|
# portmgr
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
LICENSE
|
|
2
|
+
README.md
|
|
3
|
+
pyproject.toml
|
|
4
|
+
src/portmgr/__init__.py
|
|
5
|
+
src/portmgr.egg-info/PKG-INFO
|
|
6
|
+
src/portmgr.egg-info/SOURCES.txt
|
|
7
|
+
src/portmgr.egg-info/dependency_links.txt
|
|
8
|
+
src/portmgr.egg-info/entry_points.txt
|
|
9
|
+
src/portmgr.egg-info/requires.txt
|
|
10
|
+
src/portmgr.egg-info/top_level.txt
|
|
@@ -1,15 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env python3
|
|
2
|
-
from __future__ import unicode_literals
|
|
3
|
-
|
|
4
|
-
import sys
|
|
5
|
-
|
|
6
|
-
if __package__ is None and not hasattr(sys, 'frozen'):
|
|
7
|
-
# direct call of __main__.py
|
|
8
|
-
import os.path
|
|
9
|
-
path = os.path.realpath(os.path.abspath(__file__))
|
|
10
|
-
sys.path.insert(0, os.path.dirname(os.path.dirname(path)))
|
|
11
|
-
|
|
12
|
-
import portmgr
|
|
13
|
-
|
|
14
|
-
if __name__ == '__main__':
|
|
15
|
-
portmgr.main()
|
|
File without changes
|
|
@@ -1,51 +0,0 @@
|
|
|
1
|
-
from portmgr import command_list, bcolors
|
|
2
|
-
import subprocess
|
|
3
|
-
|
|
4
|
-
from portmgr.wrapper import getServicesRunning
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
def func(action):
|
|
8
|
-
directory = action['directory']
|
|
9
|
-
relative = action['relative']
|
|
10
|
-
|
|
11
|
-
names = getServicesRunning()
|
|
12
|
-
|
|
13
|
-
index = 0
|
|
14
|
-
cont_count = len(names)
|
|
15
|
-
if cont_count == 0:
|
|
16
|
-
print("No containers found!")
|
|
17
|
-
return 1
|
|
18
|
-
elif cont_count > 1:
|
|
19
|
-
i = 0
|
|
20
|
-
for cont in names:
|
|
21
|
-
print("(" + str(i) + ") " + cont)
|
|
22
|
-
i += 1
|
|
23
|
-
|
|
24
|
-
while True:
|
|
25
|
-
choice = input("Choose container: ")
|
|
26
|
-
if choice:
|
|
27
|
-
try:
|
|
28
|
-
index = int(choice)
|
|
29
|
-
if index >= 0 and index < cont_count:
|
|
30
|
-
break
|
|
31
|
-
except ValueError:
|
|
32
|
-
print("Please enter a number!")
|
|
33
|
-
pass
|
|
34
|
-
print("Please enter a number between 0 and " + cont_count - 1 + "!")
|
|
35
|
-
|
|
36
|
-
container_id = names[index]
|
|
37
|
-
print("Attaching to " + container_id)
|
|
38
|
-
subprocess.call(["docker", "exec", "-it", container_id, "sh"])
|
|
39
|
-
|
|
40
|
-
# res = subprocess.call(["docker-compose", "logs", "--follow", "--tail=200"])
|
|
41
|
-
|
|
42
|
-
# if res != 0:
|
|
43
|
-
# print("Error showing logs for " + relative + "!\n")
|
|
44
|
-
|
|
45
|
-
return 0
|
|
46
|
-
|
|
47
|
-
command_list['a'] = {
|
|
48
|
-
'hlp': 'Attach to process',
|
|
49
|
-
'ord': 'nrm',
|
|
50
|
-
'fnc': func
|
|
51
|
-
}
|
|
@@ -1,25 +0,0 @@
|
|
|
1
|
-
from portmgr import command_list, bcolors, runCompose
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
def func(action):
|
|
5
|
-
directory = action['directory']
|
|
6
|
-
relative = action['relative']
|
|
7
|
-
|
|
8
|
-
res = runCompose(
|
|
9
|
-
['build', '--pull'],
|
|
10
|
-
env={
|
|
11
|
-
'COMPOSE_DOCKER_CLI_BUILD': '1',
|
|
12
|
-
'DOCKER_BUILDKIT': '1'
|
|
13
|
-
},
|
|
14
|
-
)
|
|
15
|
-
|
|
16
|
-
if res != 0:
|
|
17
|
-
print("Error building " + relative + "!")
|
|
18
|
-
|
|
19
|
-
return res
|
|
20
|
-
|
|
21
|
-
command_list['b'] = {
|
|
22
|
-
'hlp': 'Build local image',
|
|
23
|
-
'ord': 'nrm',
|
|
24
|
-
'fnc': func
|
|
25
|
-
}
|
|
@@ -1,27 +0,0 @@
|
|
|
1
|
-
from portmgr import command_list, bcolors, runCompose
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
def func(action):
|
|
5
|
-
directory = action['directory']
|
|
6
|
-
relative = action['relative']
|
|
7
|
-
|
|
8
|
-
res = runCompose(["down"])
|
|
9
|
-
# p = subprocess.Popen(["docker-compose", "down"], stdout=subprocess.PIPE, stderr=subprocess.PIPE)
|
|
10
|
-
|
|
11
|
-
# out, err = p.communicate()
|
|
12
|
-
|
|
13
|
-
# if out != "":
|
|
14
|
-
# print(out.decode("UTF-8"))
|
|
15
|
-
|
|
16
|
-
if not res == 0:
|
|
17
|
-
print("Error removing " + relative + "!")
|
|
18
|
-
|
|
19
|
-
# print(bcolors.FAIL + err.decode("UTF-8") + bcolors.ENDC)
|
|
20
|
-
|
|
21
|
-
return 0
|
|
22
|
-
|
|
23
|
-
command_list['d'] = {
|
|
24
|
-
'hlp': 'Stop and remove container',
|
|
25
|
-
'ord': 'rev',
|
|
26
|
-
'fnc': func
|
|
27
|
-
}
|
|
@@ -1,19 +0,0 @@
|
|
|
1
|
-
from portmgr import command_list, bcolors, runCompose
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
def func(action):
|
|
5
|
-
directory = action['directory']
|
|
6
|
-
relative = action['relative']
|
|
7
|
-
|
|
8
|
-
res = runCompose(["logs", "--follow", "--tail=200"])
|
|
9
|
-
|
|
10
|
-
if res != 0:
|
|
11
|
-
print("Error showing logs for " + relative + "!\n")
|
|
12
|
-
|
|
13
|
-
return 0
|
|
14
|
-
|
|
15
|
-
command_list['l'] = {
|
|
16
|
-
'hlp': 'Show logs',
|
|
17
|
-
'ord': 'nrm',
|
|
18
|
-
'fnc': func
|
|
19
|
-
}
|
|
@@ -1,19 +0,0 @@
|
|
|
1
|
-
from portmgr import command_list, bcolors, runCompose
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
def func(action):
|
|
5
|
-
directory = action['directory']
|
|
6
|
-
relative = action['relative']
|
|
7
|
-
|
|
8
|
-
res = runCompose(["ps"])
|
|
9
|
-
|
|
10
|
-
if res != 0:
|
|
11
|
-
print("Error listing containers for " + relative + "!\n")
|
|
12
|
-
|
|
13
|
-
return 0
|
|
14
|
-
|
|
15
|
-
command_list['c'] = {
|
|
16
|
-
'hlp': 'List containers',
|
|
17
|
-
'ord': 'nrm',
|
|
18
|
-
'fnc': func
|
|
19
|
-
}
|
|
@@ -1,19 +0,0 @@
|
|
|
1
|
-
from portmgr import command_list, bcolors, runCompose
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
def func(action):
|
|
5
|
-
directory = action['directory']
|
|
6
|
-
relative = action['relative']
|
|
7
|
-
|
|
8
|
-
res = runCompose(["pull"])
|
|
9
|
-
|
|
10
|
-
if res != 0:
|
|
11
|
-
print("Error pulling " + relative + "!")
|
|
12
|
-
|
|
13
|
-
return 0
|
|
14
|
-
|
|
15
|
-
command_list['p'] = {
|
|
16
|
-
'hlp': 'Pull image from repository',
|
|
17
|
-
'ord': 'nrm',
|
|
18
|
-
'fnc': func
|
|
19
|
-
}
|
|
@@ -1,76 +0,0 @@
|
|
|
1
|
-
from portmgr import command_list, bcolors, runCompose, runBuildx
|
|
2
|
-
import subprocess
|
|
3
|
-
import os
|
|
4
|
-
|
|
5
|
-
from portmgr.wrapper import getServices
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
def func(action):
|
|
9
|
-
directory = action['directory']
|
|
10
|
-
relative = action['relative']
|
|
11
|
-
|
|
12
|
-
services = getServices(includeOnlyBuildable=True)
|
|
13
|
-
|
|
14
|
-
print('Services to build: ' + ', '.join(services))
|
|
15
|
-
|
|
16
|
-
res = 0
|
|
17
|
-
for service in services.keys():
|
|
18
|
-
print(f"\nBuilding {service}")
|
|
19
|
-
|
|
20
|
-
new_res = 2
|
|
21
|
-
if multi_platform := os.environ.get("PORTMGR_MULTI_PLATFORM", "").lower():
|
|
22
|
-
try:
|
|
23
|
-
new_res = runBuildx(
|
|
24
|
-
['bake',
|
|
25
|
-
'--pull',
|
|
26
|
-
'--push',
|
|
27
|
-
'--set', f'*.platform={multi_platform}',
|
|
28
|
-
service
|
|
29
|
-
], timeout=1200 #kill after 20mins
|
|
30
|
-
)
|
|
31
|
-
if new_res != 0:
|
|
32
|
-
res = new_res
|
|
33
|
-
print(f"Error building {service}!")
|
|
34
|
-
except TimeoutExpired:
|
|
35
|
-
print(f"Error building {service}! Build timed out.")
|
|
36
|
-
else:
|
|
37
|
-
try:
|
|
38
|
-
new_res = runCompose(
|
|
39
|
-
['build',
|
|
40
|
-
'--pull',
|
|
41
|
-
'--force-rm',
|
|
42
|
-
'--compress',
|
|
43
|
-
service
|
|
44
|
-
], timeout=1200
|
|
45
|
-
)
|
|
46
|
-
if new_res != 0:
|
|
47
|
-
res = new_res
|
|
48
|
-
print(f"Error building {service}!")
|
|
49
|
-
else:
|
|
50
|
-
new_res = runCompose(
|
|
51
|
-
['push',
|
|
52
|
-
'--ignore-push-failures',
|
|
53
|
-
service
|
|
54
|
-
]
|
|
55
|
-
)
|
|
56
|
-
print(f"Error pushing {service}!")
|
|
57
|
-
except TimeoutExpired:
|
|
58
|
-
print(f"Error building {service}! Build timed out.")
|
|
59
|
-
if new_res != 1:
|
|
60
|
-
res = new_res
|
|
61
|
-
if os.environ.get("PORTMGR_CLEAN_AFTER_PUSH", "").lower() == "true":
|
|
62
|
-
subprocess.call(['docker', 'system', 'prune', '--all', '--force'])
|
|
63
|
-
subprocess.call(['docker', 'buildx', 'prune', '--all', '--force'])
|
|
64
|
-
|
|
65
|
-
if res != 0:
|
|
66
|
-
print("Error building&pushing " + relative + "!")
|
|
67
|
-
return res
|
|
68
|
-
|
|
69
|
-
return res
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
command_list['r'] = {
|
|
73
|
-
'hlp': 'build, push to registry & remove image',
|
|
74
|
-
'ord': 'nrm',
|
|
75
|
-
'fnc': func
|
|
76
|
-
}
|
|
@@ -1,43 +0,0 @@
|
|
|
1
|
-
from portmgr import command_list
|
|
2
|
-
import subprocess
|
|
3
|
-
|
|
4
|
-
from portmgr.wrapper import getImages
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
def func(action):
|
|
8
|
-
directory = action['directory']
|
|
9
|
-
relative = action['relative']
|
|
10
|
-
|
|
11
|
-
images = getImages()
|
|
12
|
-
|
|
13
|
-
res = 0
|
|
14
|
-
|
|
15
|
-
for image in images:
|
|
16
|
-
image_name = image["Name"]
|
|
17
|
-
print(f'Scanning {image_name} of {image["ContainerName"]}')
|
|
18
|
-
scan_res = subprocess.run(['trivy', '-q', 'image', '-s', 'CRITICAL', '--exit-code', '1', image_name], stdout=subprocess.PIPE, stderr=subprocess.STDOUT, text=True)
|
|
19
|
-
if scan_res.returncode != 0:
|
|
20
|
-
print('Found vulnerabilites:')
|
|
21
|
-
print(scan_res.stdout)
|
|
22
|
-
res = scan_res.returncode
|
|
23
|
-
|
|
24
|
-
#print("Name: %s" % container.name)
|
|
25
|
-
#names.append(container.name)
|
|
26
|
-
#config_str = subprocess.check_output(["docker", "inspect", "-f", '{{json .}}', container.id], stdout=subprocess.PIPE)
|
|
27
|
-
#json.loads(config_str)
|
|
28
|
-
#print("IP: %s" % ip)
|
|
29
|
-
#print(container.inspect)
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
#ID = subprocess.run(["docker-compose", "ps", '-q'], stdout=subprocess.PIPE).stdout
|
|
33
|
-
|
|
34
|
-
#if res != 0:
|
|
35
|
-
# print("Error listing containers for " + relative + "!\n")
|
|
36
|
-
|
|
37
|
-
return res
|
|
38
|
-
|
|
39
|
-
command_list['v'] = {
|
|
40
|
-
'hlp': 'Scan container images for vulnerabilities',
|
|
41
|
-
'ord': 'nrm',
|
|
42
|
-
'fnc': func
|
|
43
|
-
}
|
|
@@ -1,52 +0,0 @@
|
|
|
1
|
-
from functools import cmp_to_key
|
|
2
|
-
|
|
3
|
-
from portmgr import command_list
|
|
4
|
-
|
|
5
|
-
from tabulate import tabulate
|
|
6
|
-
from humanfriendly import format_size, parse_size
|
|
7
|
-
|
|
8
|
-
from portmgr.wrapper import getStats
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
def func(action):
|
|
12
|
-
directory = action['directory']
|
|
13
|
-
relative = action['relative']
|
|
14
|
-
|
|
15
|
-
stats_list = getStats()
|
|
16
|
-
|
|
17
|
-
values = []
|
|
18
|
-
has_network_stats = False
|
|
19
|
-
for stats in stats_list:
|
|
20
|
-
name = stats['Name'] if 'Name' in stats else stats['Container']
|
|
21
|
-
#memory = stats["memory_stats"]
|
|
22
|
-
#usage = format_size(memory['usage'])
|
|
23
|
-
#limit = format_size(memory['limit'])
|
|
24
|
-
memory_string = stats["MemUsage"]
|
|
25
|
-
usage, limit = [p.strip() for p in memory_string.split('/')]
|
|
26
|
-
if 'NetIO' in stats:
|
|
27
|
-
network = stats["NetIO"]
|
|
28
|
-
received, sent = [p.strip() for p in memory_string.split('/')]
|
|
29
|
-
#received = format_size(sum(stats['rx_bytes'] for iface, stats in network.items()))
|
|
30
|
-
#sent = format_size(sum(stats['tx_bytes'] for iface, stats in network.items()))
|
|
31
|
-
columns = (stats['Name'], usage, limit, received, sent)
|
|
32
|
-
has_network_stats = True
|
|
33
|
-
else:
|
|
34
|
-
columns = (stats['Name'], usage, limit)
|
|
35
|
-
values.append(columns)
|
|
36
|
-
if values:
|
|
37
|
-
# sort by memory usage
|
|
38
|
-
values = sorted(values, key=cmp_to_key(lambda s1, s2: parse_size(s2[1]) - parse_size(s1[1])))
|
|
39
|
-
print(tabulate(values,
|
|
40
|
-
headers=['Service', 'Mem Usage', 'Mem Limit', 'Net Recv', 'Net Sent'],
|
|
41
|
-
colalign=['left', 'right', 'right', 'right', 'right'] if has_network_stats
|
|
42
|
-
else ['left', 'right', 'right']))
|
|
43
|
-
print('')
|
|
44
|
-
|
|
45
|
-
return 0
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
command_list['o'] = {
|
|
49
|
-
'hlp': 'Show container stats',
|
|
50
|
-
'ord': 'nrm',
|
|
51
|
-
'fnc': func
|
|
52
|
-
}
|
|
@@ -1,26 +0,0 @@
|
|
|
1
|
-
from portmgr import command_list, bcolors, runCompose
|
|
2
|
-
|
|
3
|
-
def func(action):
|
|
4
|
-
directory = action['directory']
|
|
5
|
-
relative = action['relative']
|
|
6
|
-
|
|
7
|
-
res = runCompose(["stop"])
|
|
8
|
-
# p = subprocess.Popen(["docker-compose", "stop"], stdout=subprocess.PIPE, stderr=subprocess.PIPE)
|
|
9
|
-
|
|
10
|
-
#out, err = p.communicate()
|
|
11
|
-
|
|
12
|
-
#if out != "":
|
|
13
|
-
# print(out.decode("UTF-8"))
|
|
14
|
-
|
|
15
|
-
if res != 0:
|
|
16
|
-
print("Error stopping " + relative + "!")
|
|
17
|
-
|
|
18
|
-
# print(bcolors.FAIL + err.decode("UTF-8") + bcolors.ENDC)
|
|
19
|
-
|
|
20
|
-
return 0
|
|
21
|
-
|
|
22
|
-
command_list['s'] = {
|
|
23
|
-
'hlp': 'Stop container',
|
|
24
|
-
'ord': 'rev',
|
|
25
|
-
'fnc': func
|
|
26
|
-
}
|
|
@@ -1,18 +0,0 @@
|
|
|
1
|
-
from portmgr import command_list, runCompose
|
|
2
|
-
|
|
3
|
-
def func(action):
|
|
4
|
-
relative = action['relative']
|
|
5
|
-
|
|
6
|
-
res = runCompose(["top"])
|
|
7
|
-
|
|
8
|
-
if res != 0:
|
|
9
|
-
print("Error listing processes of containers in " + relative + "!\n")
|
|
10
|
-
|
|
11
|
-
return 0
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
command_list['t'] = {
|
|
15
|
-
'hlp': 'List processes in containers',
|
|
16
|
-
'ord': 'nrm',
|
|
17
|
-
'fnc': func
|
|
18
|
-
}
|
|
@@ -1,26 +0,0 @@
|
|
|
1
|
-
from portmgr import command_list, bcolors, runCompose
|
|
2
|
-
|
|
3
|
-
def func(action):
|
|
4
|
-
directory = action['directory']
|
|
5
|
-
relative = action['relative']
|
|
6
|
-
|
|
7
|
-
res = runCompose(["up", "-d"])
|
|
8
|
-
# p = subprocess.Popen(["docker-compose", "up", "-d"], stdout=subprocess.PIPE, stderr=subprocess.PIPE)
|
|
9
|
-
|
|
10
|
-
# out, err = p.communicate()
|
|
11
|
-
|
|
12
|
-
# if out != "":
|
|
13
|
-
# print(out.decode("UTF-8"))
|
|
14
|
-
|
|
15
|
-
if res != 0:
|
|
16
|
-
print("Error creating " + relative + "!")
|
|
17
|
-
|
|
18
|
-
# print(bcolors.FAIL + err.decode("UTF-8") + bcolors.ENDC)
|
|
19
|
-
|
|
20
|
-
return 0
|
|
21
|
-
|
|
22
|
-
command_list['u'] = {
|
|
23
|
-
'hlp': 'Create container',
|
|
24
|
-
'ord': 'nrm',
|
|
25
|
-
'fnc': func
|
|
26
|
-
}
|
|
@@ -1,170 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/python3
|
|
2
|
-
import os, sys
|
|
3
|
-
import argparse
|
|
4
|
-
import importlib
|
|
5
|
-
import re
|
|
6
|
-
|
|
7
|
-
import yaml
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
class MyParser(argparse.ArgumentParser):
|
|
11
|
-
def error(self, message):
|
|
12
|
-
sys.stderr.write('Error: %s\n' % message)
|
|
13
|
-
self.print_help()
|
|
14
|
-
sys.exit(2)
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
sub_names = [x.strip() for x in re.split('[ ,;]+', os.environ.get('PORTMGR_SUB_NAME', 'dckrsub.yml'))]
|
|
18
|
-
compose_names = [x.strip() for x in
|
|
19
|
-
os.environ.get('PORTMGR_COMPOSE_NAME', 'docker-compose.yml, docker-compose.yaml').split(',')]
|
|
20
|
-
|
|
21
|
-
# sub_scheme_name = 'dckrsub.schema.yml'
|
|
22
|
-
|
|
23
|
-
src_path = os.path.dirname(os.path.abspath(__file__))
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
# conf_scheme_path = os.path.join(src_path, sub_scheme_name)
|
|
27
|
-
# sub_scheme_path = os.path.join(src_path, sub_scheme_name)
|
|
28
|
-
|
|
29
|
-
# conf_scheme = dckrjsn.read_json(conf_scheme_path)
|
|
30
|
-
# sub_scheme = dckrjsn.read_json(sub_scheme_path)
|
|
31
|
-
|
|
32
|
-
class bcolors:
|
|
33
|
-
HEADER = '\033[95m'
|
|
34
|
-
OKBLUE = '\033[94m'
|
|
35
|
-
OKGREEN = '\033[92m'
|
|
36
|
-
WARNING = '\033[93m'
|
|
37
|
-
FAIL = '\033[91m'
|
|
38
|
-
ENDC = '\033[0m'
|
|
39
|
-
BOLD = '\033[1m'
|
|
40
|
-
UNDERLINE = '\033[4m'
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
command_list = {}
|
|
44
|
-
action_list = []
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
def addCommand(cur_directory):
|
|
48
|
-
if not any(action['directory'] == cur_directory for action in action_list):
|
|
49
|
-
relative_dir = os.path.relpath(cur_directory, base_directory)
|
|
50
|
-
if relative_dir == '.':
|
|
51
|
-
relative_dir = os.path.basename(os.path.normpath(cur_directory))
|
|
52
|
-
action_list.append({
|
|
53
|
-
'directory': cur_directory,
|
|
54
|
-
'relative': relative_dir
|
|
55
|
-
})
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
def read_yaml(path):
|
|
59
|
-
with open(path, 'r') as stream:
|
|
60
|
-
try:
|
|
61
|
-
return yaml.load(stream, Loader=yaml.SafeLoader)
|
|
62
|
-
except yaml.YAMLError as exc:
|
|
63
|
-
print(exc)
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
def traverse(cur_directory):
|
|
67
|
-
# print("Traversing in " + cur_directory)
|
|
68
|
-
for sub_name in sub_names:
|
|
69
|
-
sub_path = os.path.join(cur_directory, sub_name)
|
|
70
|
-
compose_paths = [os.path.join(cur_directory, name) for name in compose_names]
|
|
71
|
-
|
|
72
|
-
# print("Checking file at " + sub_path)
|
|
73
|
-
if os.path.isfile(sub_path): # has sub folders
|
|
74
|
-
# print("Has sub folders!")
|
|
75
|
-
# sub_folders = dckrjsn.read_json(sub_path, sch = sub_scheme)
|
|
76
|
-
sub_folders = read_yaml(sub_path)
|
|
77
|
-
for sub_folder in sub_folders:
|
|
78
|
-
# print("Checking out " + sub_folder)
|
|
79
|
-
next_directory = os.path.join(cur_directory, sub_folder)
|
|
80
|
-
traverse(next_directory)
|
|
81
|
-
elif any(os.path.isfile(path) for path in compose_paths): # has a docker-compose file
|
|
82
|
-
addCommand(cur_directory)
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
def main():
|
|
86
|
-
# global cli
|
|
87
|
-
global base_directory
|
|
88
|
-
|
|
89
|
-
# cli = docker.Client('unix://var/run/docker.sock')
|
|
90
|
-
|
|
91
|
-
# Include external source files for commands
|
|
92
|
-
# These fill the m_cmd list
|
|
93
|
-
for file in os.listdir(os.path.join(src_path, 'commands')):
|
|
94
|
-
ext_file = os.path.splitext(file)
|
|
95
|
-
|
|
96
|
-
if ext_file[1] == '.py' and not ext_file[0] == '__init__':
|
|
97
|
-
importlib.import_module('portmgr.commands.' + ext_file[0])
|
|
98
|
-
|
|
99
|
-
parser = MyParser()
|
|
100
|
-
parser.add_argument('-D',
|
|
101
|
-
dest='base_directory',
|
|
102
|
-
action='store',
|
|
103
|
-
default='',
|
|
104
|
-
help='Set working directory')
|
|
105
|
-
# parser.add_argument('-R',
|
|
106
|
-
# dest='recursive',
|
|
107
|
-
# action='store_true',
|
|
108
|
-
# help='Use dckrsub.json files to recursively apply operations')
|
|
109
|
-
|
|
110
|
-
for cmd in command_list.items():
|
|
111
|
-
parser.add_argument('-' + cmd[0],
|
|
112
|
-
dest='a_cmd',
|
|
113
|
-
action='append_const',
|
|
114
|
-
const=cmd[0],
|
|
115
|
-
help=cmd[1]['hlp'])
|
|
116
|
-
|
|
117
|
-
argv = sys.argv[1:]
|
|
118
|
-
if len(argv) == 1 and not argv[0].startswith('-'):
|
|
119
|
-
argv[0] = '-' + argv[0]
|
|
120
|
-
args = parser.parse_args(argv)
|
|
121
|
-
|
|
122
|
-
if len(sys.argv) == 1:
|
|
123
|
-
parser.print_help()
|
|
124
|
-
sys.exit(1)
|
|
125
|
-
|
|
126
|
-
base_directory = os.path.join(os.getcwd(), args.base_directory)
|
|
127
|
-
|
|
128
|
-
# if args.recursive:
|
|
129
|
-
traverse(base_directory)
|
|
130
|
-
# else:
|
|
131
|
-
# addCommand(base_directory)
|
|
132
|
-
|
|
133
|
-
last_cmd = ''
|
|
134
|
-
for cmd in args.a_cmd: # loop over all passed arguments (t, r, u)
|
|
135
|
-
cur_cmd = command_list[cmd]
|
|
136
|
-
cmd_function = cur_cmd['fnc']
|
|
137
|
-
cmd_order = cur_cmd['ord'];
|
|
138
|
-
|
|
139
|
-
# if last_cmd == 'r' and cur_cmd == 'u':
|
|
140
|
-
# print("Waiting 3 seconds.. ")
|
|
141
|
-
# sleep(3)
|
|
142
|
-
|
|
143
|
-
if cmd_order == 'nrm':
|
|
144
|
-
action_list_sorted = action_list
|
|
145
|
-
elif cmd_order == 'rev':
|
|
146
|
-
action_list_sorted = reversed(action_list)
|
|
147
|
-
else:
|
|
148
|
-
exit(1)
|
|
149
|
-
|
|
150
|
-
failed_list = []
|
|
151
|
-
|
|
152
|
-
for action in action_list_sorted:
|
|
153
|
-
origWD = os.getcwd()
|
|
154
|
-
newWD = action['directory']
|
|
155
|
-
os.chdir(newWD)
|
|
156
|
-
print('-> ' + action["relative"])
|
|
157
|
-
if cmd_function(action) != 0: # execute the function through reflection
|
|
158
|
-
failed_list.append(action)
|
|
159
|
-
os.chdir(origWD)
|
|
160
|
-
if failed_list:
|
|
161
|
-
print('Failed containers:')
|
|
162
|
-
for action in failed_list:
|
|
163
|
-
print('- ' + action['relative'])
|
|
164
|
-
print("")
|
|
165
|
-
|
|
166
|
-
exit(0)
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
if __name__ == '__main__':
|
|
170
|
-
main()
|
|
@@ -1,67 +0,0 @@
|
|
|
1
|
-
import json
|
|
2
|
-
import os
|
|
3
|
-
from subprocess import run, check_output
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
def getServices(includeOnlyBuildable=False):
|
|
7
|
-
data = check_output(['docker', 'compose', 'config', '--format', 'json'])
|
|
8
|
-
config = json.loads(data)
|
|
9
|
-
services = config['services']
|
|
10
|
-
if includeOnlyBuildable:
|
|
11
|
-
services = {name: values for name, values in services.items() if 'build' in values.keys()}
|
|
12
|
-
return services
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
def getServicesRunning():
|
|
16
|
-
data = check_output(['docker', 'compose', 'ps', '--format', 'json'])
|
|
17
|
-
try:
|
|
18
|
-
lines = data.decode().splitlines()
|
|
19
|
-
if len(lines) > 1:
|
|
20
|
-
container_list = []
|
|
21
|
-
for l in lines:
|
|
22
|
-
#print(f'l: {l}')
|
|
23
|
-
container_list.append(json.loads(l.strip()))
|
|
24
|
-
else:
|
|
25
|
-
container_list = json.loads(data)
|
|
26
|
-
except Exception as e:
|
|
27
|
-
print(e)
|
|
28
|
-
print(data.decode())
|
|
29
|
-
if isinstance(container_list, dict):
|
|
30
|
-
container_names = [container_list['Name']]
|
|
31
|
-
else:
|
|
32
|
-
container_names = [s['Name'] for s in container_list]
|
|
33
|
-
return container_names
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
def getImages():
|
|
37
|
-
data = check_output(['docker', 'compose', 'images', '--format', 'json'])
|
|
38
|
-
image_list = json.loads(data)
|
|
39
|
-
images = [
|
|
40
|
-
{'ID': image['ID'],
|
|
41
|
-
'Name': image['Repository'],
|
|
42
|
-
'ContainerName': image['ContainerName'],
|
|
43
|
-
'Tag': image['Tag']}
|
|
44
|
-
for image in image_list
|
|
45
|
-
]
|
|
46
|
-
return images
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
def getStats():
|
|
50
|
-
containers = getServicesRunning()
|
|
51
|
-
data = check_output(['docker', 'stats', '--format', 'json', '--no-stream'] + containers, text=True).strip()
|
|
52
|
-
data_lines = data.split('\n')
|
|
53
|
-
stats = [json.loads(line) for line in data_lines]
|
|
54
|
-
return stats
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
def runCompose(args, **kwargs):
|
|
58
|
-
command = ['docker', 'compose']
|
|
59
|
-
if os.environ.get("PORTMGR_IN_SCRIPT", "").lower() == "true":
|
|
60
|
-
command += ["--ansi", "never"]
|
|
61
|
-
command += list(args)
|
|
62
|
-
return run(command, **kwargs).returncode
|
|
63
|
-
|
|
64
|
-
def runBuildx(args, **kwargs):
|
|
65
|
-
command = ['docker', 'buildx']
|
|
66
|
-
command += list(args)
|
|
67
|
-
return run(command, **kwargs).returncode
|
|
@@ -1,28 +0,0 @@
|
|
|
1
|
-
LICENSE
|
|
2
|
-
README.md
|
|
3
|
-
pyproject.toml
|
|
4
|
-
setup.py
|
|
5
|
-
portmgr/__init__.py
|
|
6
|
-
portmgr/__main__.py
|
|
7
|
-
portmgr/portmgr.py
|
|
8
|
-
portmgr/wrapper.py
|
|
9
|
-
portmgr.egg-info/PKG-INFO
|
|
10
|
-
portmgr.egg-info/SOURCES.txt
|
|
11
|
-
portmgr.egg-info/dependency_links.txt
|
|
12
|
-
portmgr.egg-info/entry_points.txt
|
|
13
|
-
portmgr.egg-info/not-zip-safe
|
|
14
|
-
portmgr.egg-info/requires.txt
|
|
15
|
-
portmgr.egg-info/top_level.txt
|
|
16
|
-
portmgr/commands/__init__.py
|
|
17
|
-
portmgr/commands/attach.py
|
|
18
|
-
portmgr/commands/build.py
|
|
19
|
-
portmgr/commands/down.py
|
|
20
|
-
portmgr/commands/logs.py
|
|
21
|
-
portmgr/commands/ps.py
|
|
22
|
-
portmgr/commands/pull.py
|
|
23
|
-
portmgr/commands/push.py
|
|
24
|
-
portmgr/commands/scan.py
|
|
25
|
-
portmgr/commands/stats.py
|
|
26
|
-
portmgr/commands/stop.py
|
|
27
|
-
portmgr/commands/top.py
|
|
28
|
-
portmgr/commands/up.py
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
|
portmgr-1.8.0.dev0/setup.py
DELETED
|
@@ -1,26 +0,0 @@
|
|
|
1
|
-
from setuptools import setup, find_packages
|
|
2
|
-
|
|
3
|
-
setup(
|
|
4
|
-
name='portmgr',
|
|
5
|
-
version='1.8.0dev0',
|
|
6
|
-
url="https://github.com/Craeckie/portmgr",
|
|
7
|
-
description="Simple command interface to manage multiple Docker container",
|
|
8
|
-
packages=find_packages(), #['portmgr'],
|
|
9
|
-
license='Creative Commons Attribution-Noncommercial-Share Alike license',
|
|
10
|
-
long_description=open('README.md').read(),
|
|
11
|
-
long_description_content_type="text/markdown",
|
|
12
|
-
zip_safe=False,
|
|
13
|
-
|
|
14
|
-
install_requires=[
|
|
15
|
-
'jsonschema',
|
|
16
|
-
'tabulate',
|
|
17
|
-
'PyYAML',
|
|
18
|
-
'jsonschema',
|
|
19
|
-
'humanfriendly'
|
|
20
|
-
],
|
|
21
|
-
entry_points = {
|
|
22
|
-
'console_scripts': [
|
|
23
|
-
'portmgr = portmgr:main'
|
|
24
|
-
]
|
|
25
|
-
}
|
|
26
|
-
)
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|