Skip to content

Commit cda7503

Browse files
committed
add a python global deployer
1 parent 9a33c10 commit cda7503

File tree

8 files changed

+259
-2
lines changed

8 files changed

+259
-2
lines changed

.gitignore

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
projects/
2+
__pycache__/
3+
.idea/

README.md

Lines changed: 34 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,34 @@
1-
# p-deployer
2-
Deploy P-Project repositories for development purposes.
1+
P-Project Deployer
2+
==================
3+
4+
The P-Project Deployer can be used to install the whole project using a single
5+
command.
6+
7+
Deploy (install or update)
8+
--------------------------
9+
10+
This command allows you to install or update the project in one command:
11+
12+
```sh
13+
./deploy.py
14+
```
15+
16+
You may pass an optional argument to clone using https method instead of ssh:
17+
18+
```sh
19+
./deploy.py https
20+
```
21+
22+
Run the applications
23+
--------------------
24+
25+
```sh
26+
./run.py
27+
```
28+
29+
Remove all the projects
30+
-----------------------
31+
32+
```sh
33+
./clear.py
34+
```

check.py

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
import yaml
2+
import os
3+
from subprocess import call
4+
from utils import banner
5+
6+
7+
def check_result(res):
8+
if res == 0:
9+
print(' ✓')
10+
else:
11+
print(' ✗')
12+
13+
return res
14+
15+
16+
def check_requirements(project_id):
17+
res = 0
18+
conf = yaml.load(open('config.yml', 'r'))
19+
path = conf['parameters']['projects_dir'] + '/' + project_id
20+
properties = yaml.load(open(path + '/.p-properties.yml', 'r'))
21+
22+
print(banner.info('Checking requirements for ' + conf['projects'][project_id]['name']))
23+
24+
dependencies = properties['dependencies']
25+
for bin_dependency in dependencies.get('bin', []):
26+
print('Checking if ' + bin_dependency + ' is installed...', end='')
27+
res = check_result(call(['which', bin_dependency], stdout=open(os.devnull, 'w'))) or res
28+
29+
for script_dependency in dependencies.get('script', []):
30+
print('Running script ' + script_dependency + '...', end='')
31+
res = check_result(call(script_dependency, shell=True, stdout=open(os.devnull, 'w'))) or res
32+
33+
if res:
34+
print(banner.error('Some requirements are missing!'))
35+
print('Check the script trace and run the update script to finish installation.')
36+
exit(res)
37+
else:
38+
print(banner.success('Your system meets requirements'))

clear.py

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
#!/usr/bin/env python
2+
3+
import yaml
4+
import shutil
5+
from utils import banner
6+
7+
config = yaml.load(open('./config.yml', 'r'))
8+
projects_dir = config['parameters']['projects_dir']
9+
10+
11+
def confirm_removal():
12+
print(banner.info('BEWARE! All projects will be deleted!'))
13+
14+
print('History will be lost, and all code in ' + projects_dir + ' folder will be deleted. '
15+
'There is no coming back. Continue? [y/N] ')
16+
17+
choice = input().lower()
18+
if choice != 'y':
19+
exit(1)
20+
21+
22+
def remove_projects():
23+
shutil.rmtree(projects_dir)
24+
25+
print(banner.success('All projects were deleted.'))
26+
27+
28+
if __name__ == '__main__':
29+
confirm_removal()
30+
remove_projects()

config.yml

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
parameters:
2+
projects_dir: ./projects
3+
4+
projects:
5+
p-api:
6+
name: P-API
7+
description: The P-Platform monolithic API
8+
repository:
9+
https: https://github.com/p-project/p-api.git
10+
ssh: [email protected]:p-project/p-api.git
11+
12+
p-seeder-engine:
13+
name: P-Seeder engine
14+
description: Bittorrent daemon controlled by HTTP requests
15+
repository:
16+
https: https://github.com/p-project/p-seeder-engine.git
17+
ssh: [email protected]:p-project/p-seeder-engine.git

deploy.py

Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
#!/usr/bin/env python
2+
3+
import yaml
4+
import sys
5+
import os
6+
from subprocess import call
7+
from utils import banner
8+
from check import check_requirements
9+
10+
conf = yaml.load(open("./config.yml", 'r'))
11+
12+
cloning_method = 'ssh'
13+
if len(sys.argv) > 1 and sys.argv[1] == 'https':
14+
cloning_method = 'https'
15+
16+
17+
def self_update():
18+
print(banner.info('Self-updating...'))
19+
20+
call(['git', 'checkout', 'master'])
21+
call(['git', 'pull'])
22+
23+
24+
def update_confirmation():
25+
print(banner.info('Are you sure you want to continue?'))
26+
print('I will stash potential uncommitted changes, checkout master and pull the last commit from origin. '
27+
'Continue? [y/N] ')
28+
29+
choice = input().lower()
30+
if choice != 'y':
31+
exit(1)
32+
33+
34+
def update(name, path):
35+
print(banner.info('Now updating ' + name))
36+
37+
update_confirmation()
38+
39+
call(['git', 'stash', 'save'], cwd=path)
40+
call(['git', 'checkout', 'master'], cwd=path)
41+
call(['git', 'pull'], cwd=path)
42+
43+
44+
def install(name, url, path):
45+
print(banner.info('Now installing ' + name))
46+
47+
print(banner.info('Using ' + cloning_method + ' cloning method'))
48+
print('You may change the cloning method by passing https or ssh as an argument.')
49+
50+
call(['git', 'clone', url, path])
51+
52+
53+
def deploy():
54+
for project_id in conf['projects']:
55+
project = conf['projects'][project_id]
56+
path = conf['parameters']['projects_dir'] + '/' + project_id
57+
58+
if os.path.exists(path):
59+
update(project['name'], path)
60+
else:
61+
install(project['name'], project['repository'][cloning_method], path)
62+
63+
check_requirements(project_id)
64+
65+
properties = yaml.load(open(path + '/.p-properties.yml', 'r'))
66+
for command in properties['install']:
67+
call(command, shell=True, cwd=path)
68+
69+
print(banner.success('Deployment is done!'))
70+
print('Please check execution traces as installation scripts errors are ignored.')
71+
72+
73+
if __name__ == '__main__':
74+
self_update()
75+
deploy()

run.py

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
#!/usr/bin/env python
2+
3+
import yaml
4+
import os
5+
import sys
6+
from subprocess import Popen
7+
from time import sleep
8+
from utils import banner
9+
10+
conf = yaml.load(open("./config.yml", 'r'))
11+
12+
13+
def start_all():
14+
print(banner.info('Starting all applications'))
15+
16+
processes = []
17+
for project_id in conf['projects']:
18+
project = conf['projects'][project_id]
19+
path = conf['parameters']['projects_dir'] + '/' + project_id
20+
21+
if not os.path.exists(path):
22+
print(banner.info('Ignoring ' + project['name'] + ' (not installed)'))
23+
continue
24+
25+
properties = yaml.load(open(path + '/.p-properties.yml', 'r'))
26+
27+
if 'run' not in properties:
28+
print(banner.info('Ignoring ' + project['name'] + ' (no running configuration)'))
29+
continue
30+
31+
for command in properties['run']:
32+
print(banner.info('Starting ' + project['name']))
33+
34+
processes.append(Popen(command, shell=True, cwd=path))
35+
sleep(2)
36+
37+
print(banner.success('All projects started!'))
38+
print('Press Ctrl-C to quit.')
39+
40+
for process in processes:
41+
try:
42+
process.wait()
43+
except KeyboardInterrupt:
44+
sys.exit(0)
45+
46+
47+
if __name__ == '__main__':
48+
start_all()

utils/banner.py

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
def banner(color, bullet, string):
2+
return '\n {color} {bullet} \033[0m\033[0;30;47m {string} \033[0m\n'.format(color=color, bullet=bullet, string=string)
3+
4+
5+
def info(string):
6+
return banner('\033[1;37;44m', '•', string)
7+
8+
9+
def success(string):
10+
return banner('\033[1;37;42m', '✓', string)
11+
12+
13+
def error(string):
14+
return banner('\033[1;37;41m', '✗', string)

0 commit comments

Comments
 (0)