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