-
Notifications
You must be signed in to change notification settings - Fork 14
/
Copy pathsaltdocker.py
138 lines (115 loc) · 4.59 KB
/
saltdocker.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
# -*- coding: utf-8 -*-
import asyncio
import datetime
import distutils.version
import json
import os
import signal
import tempfile
import aiohttp
import click
import jinja2
MINVER = distutils.version.LooseVersion('2018.3.0')
PATH = os.path.dirname(os.path.abspath(__file__))
with open(f'{PATH}/Dockerfile.j2') as dockerfile:
DOCKERTEMPLATE = jinja2.Template(dockerfile.read())
class SaltVersion(object):
loop = asyncio.get_event_loop()
versions = []
_date = datetime.datetime.utcnow().strftime("%Y%m%d%H%M")
def __init__(self, version):
self.version = version
@property
def shortversion(self):
return '.'.join(map(str, self.version.version[:2]))
@classmethod
def date(self, setting=False):
if os.path.isfile('.lastbuild') and setting == False:
with open('.lastbuild') as lastbuild:
SaltVersion._date = json.load(lastbuild)['lastbuild']
return SaltVersion._date
async def build(self, force=False, latest=False):
try:
tmpfile = tempfile.mkstemp()
with open(tmpfile[1], 'w') as dfile:
print(DOCKERTEMPLATE.render(salt_version=self.version), file=dfile)
cwd = os.getcwd()
if cwd != PATH:
os.chdir(PATH)
args = ['docker', 'build', '--file', tmpfile[1]]
if force is True:
args.append('--no-cache')
if latest is True:
args.extend([
'--tag', 'saltstack/salt:latest',
])
args.extend([
'--tag', f'saltstack/salt:{self.shortversion}',
'--tag', f'saltstack/salt:{self.version}',
'--tag', f'saltstack/salt:{self.version}-{self.date()}',
PATH
])
proc = await asyncio.create_subprocess_exec(*args, loop=self.loop)
await proc.communicate()
finally:
os.chdir(cwd)
os.unlink(tmpfile[1])
async def push(self, latest=False, dryrun=True):
for tag in [
f'saltstack/salt:{self.shortversion}',
f'saltstack/salt:{self.version}',
f'saltstack/salt:{self.version}-{self.date()}',
'saltstack/salt:latest'
]:
print(tag)
if dryrun is True:
continue
if tag == 'latest' and latest is not True:
continue
proc = await asyncio.create_subprocess_exec('docker', 'push', tag)
await proc.communicate()
@classmethod
def _check_version(cls, version):
if version < MINVER or 'rc' in version.version:
return False
if [
v for v in cls.data['releases']
if distutils.version.LooseVersion(v).version[:-1] == version.version[:-1] and
distutils.version.LooseVersion(v) > version
]:
return False
return True
@classmethod
async def build_salt_images(cls, push=False, dryrun=True):
async with aiohttp.ClientSession() as session:
async with session.get('https://pypi.org/pypi/salt/json') as response:
cls.data = await response.json()
versions = sorted(filter(cls._check_version, map(distutils.version.LooseVersion, cls.data['releases'])))
if push is False:
for idx, version in enumerate(versions):
if idx == 0:
await cls(version).build(force=True)
else:
latest = version == versions[-1]
cls.versions.append(cls.loop.create_task(cls(version).build(latest=latest)))
else:
for idx, version in enumerate(versions):
latest = version == versions[-1]
cls.versions.append(cls.loop.create_task(cls(version).push(latest=latest, dryrun=dryrun)))
await asyncio.gather(*cls.versions, loop=cls.loop)
@click.command()
@click.option("--push", is_flag=True, help="Push to hub.docker.io")
@click.option("--dryrun", is_flag=True, help="Push to hub.docker.io")
def main(push, dryrun):
loop = asyncio.get_event_loop()
for signame in {'SIGINT', 'SIGTERM'}:
loop.add_signal_handler(getattr(signal, signame), loop.stop)
try:
if push is False:
with open('.lastbuild', 'w') as lastbuild:
json.dump({'lastbuild': SaltVersion.date(setting=True)}, lastbuild)
loop.run_until_complete(SaltVersion.build_salt_images(push=push, dryrun=dryrun))
finally:
loop.close()
if __name__ == '__main__':
main()