kopia lustrzana https://github.com/jupyterhub/repo2docker
Add basic builder code
- Takes in config via traitlets - Pushes image after it is built - Can run different detectors easily as well - Single straight up application that runs from start to end, no concurrency (woot!)pull/2/head
rodzic
8ddf7704ce
commit
aa7eb895c1
|
@ -0,0 +1,89 @@
|
|||
import json
|
||||
import os
|
||||
|
||||
|
||||
from traitlets.config import Application, LoggingConfigurable, Unicode, Dict, List
|
||||
from traitlets import Type
|
||||
import docker
|
||||
|
||||
import subprocess
|
||||
|
||||
|
||||
from .detectors import BuildPack, PythonBuildPack
|
||||
|
||||
class Builder(Application):
|
||||
config_file = Unicode(
|
||||
'builder_config.py',
|
||||
config=True
|
||||
)
|
||||
|
||||
build_name = Unicode(
|
||||
None,
|
||||
allow_none=True,
|
||||
config=True
|
||||
)
|
||||
|
||||
source_url = Unicode(
|
||||
None,
|
||||
allow_none=True,
|
||||
config=True
|
||||
)
|
||||
|
||||
output_image_spec = Unicode(
|
||||
None,
|
||||
allow_none=True,
|
||||
config=True
|
||||
)
|
||||
|
||||
git_workdir = Unicode(
|
||||
"/tmp/git",
|
||||
config=True
|
||||
)
|
||||
|
||||
buildpacks = List(
|
||||
None,
|
||||
[PythonBuildPack],
|
||||
config=True
|
||||
)
|
||||
|
||||
aliases = Dict({
|
||||
'source': 'Builder.source_url',
|
||||
'output': 'Builder.output_image_spec',
|
||||
'f': 'Builder.config_file',
|
||||
'n': 'Builder.build_name'
|
||||
})
|
||||
|
||||
|
||||
def fetch(self, url, ref, output_path):
|
||||
subprocess.check_call([
|
||||
"git", "clone", "--depth", "1",
|
||||
url, output_path
|
||||
])
|
||||
|
||||
|
||||
def initialize(self, *args, **kwargs):
|
||||
super().initialize(*args, **kwargs)
|
||||
|
||||
self.load_config_file(self.config_file)
|
||||
|
||||
def run(self):
|
||||
output_path = os.path.join(self.git_workdir, self.build_name)
|
||||
self.fetch(
|
||||
self.source_url,
|
||||
'master',
|
||||
output_path
|
||||
)
|
||||
for bp_class in self.buildpacks:
|
||||
bp = bp_class()
|
||||
if bp.detect(output_path):
|
||||
bp.build(output_path, self.output_image_spec)
|
||||
|
||||
client = docker.from_env(version='1.24')
|
||||
for line in client.images.push(self.output_image_spec, stream=True):
|
||||
progress = json.loads(line.decode('utf-8'))
|
||||
print(progress['status'])
|
||||
|
||||
if __name__ == '__main__':
|
||||
f = Builder()
|
||||
f.initialize()
|
||||
f.run()
|
|
@ -0,0 +1,51 @@
|
|||
import os
|
||||
import subprocess
|
||||
|
||||
from traitlets import Unicode, Dict
|
||||
from traitlets.config import LoggingConfigurable
|
||||
|
||||
|
||||
class BuildPack(LoggingConfigurable):
|
||||
def detect(self, workdir):
|
||||
"""
|
||||
Return True if app in workdir can be built with this buildpack
|
||||
"""
|
||||
pass
|
||||
|
||||
def build(self, workdir, output_image_spec):
|
||||
"""
|
||||
Run a command that will take workdir and produce an image ready to be pushed
|
||||
"""
|
||||
pass
|
||||
|
||||
|
||||
|
||||
class PythonBuildPack(BuildPack):
|
||||
runtime_builder_map = Dict({
|
||||
'python-2.7': 'jupyterhub/singleuser-builder-venv-2.7:v0.1.2',
|
||||
'python-3.5': 'jupyterhub/singleuser-builder-venv-3.5:v0.1.2',
|
||||
})
|
||||
|
||||
runtime = Unicode(
|
||||
'python-3.5',
|
||||
config=True
|
||||
)
|
||||
|
||||
def detect(self, workdir):
|
||||
if os.path.exists(os.path.join(workdir, 'requirements.txt')):
|
||||
try:
|
||||
with open(os.path.join(workdir, 'runtime.txt')) as f:
|
||||
self.runtime = f.read().strip()
|
||||
except FileNotFoundError:
|
||||
pass
|
||||
return True
|
||||
|
||||
def build(self, workdir, output_image_spec):
|
||||
cmd = [
|
||||
's2i',
|
||||
'build',
|
||||
workdir,
|
||||
self.runtime_builder_map[self.runtime],
|
||||
output_image_spec
|
||||
]
|
||||
subprocess.check_call(cmd)
|
Ładowanie…
Reference in New Issue