diff --git a/README.md b/README.md index 4c77729..f3738bc 100644 --- a/README.md +++ b/README.md @@ -71,7 +71,7 @@ In order to deploy your own `everware` instance, you have to: everware-server -f etc/local_config.py --debug --no-ssl ``` -Everware can also be deployed in a Docker container. See [Everware in Docker container](docker.md) +Everware can also be deployed in a Docker container. See [Everware in Docker container](docs/docker.md) ## Development diff --git a/bower.json b/bower.json index bffffe5..4df8669 100644 --- a/bower.json +++ b/bower.json @@ -7,6 +7,7 @@ "jquery": "components/jquery#~2.0", "moment": "~2.7", "requirejs": "~2.1", - "material-design-lite": "^1.1.3" + "material-design-lite": "^1.1.3", + "clipboard": "^1.6.1" } } diff --git a/etc/base_config.py b/etc/base_config.py index a043bb1..eeb540e 100644 --- a/etc/base_config.py +++ b/etc/base_config.py @@ -14,6 +14,9 @@ c.Spawner.remove_containers = True c.Spawner.tls_assert_hostname = False c.Spawner.use_docker_client_env = True +# give users an opportunity to restore any images via docker or not. Default: True +# c.Spawner.share_user_images = False + # c.Authenticator.admin_users = {'anaderi', 'astiunov'} # The docker containers need access to the Hub API, so the default diff --git a/everware/home_handler.py b/everware/home_handler.py index 0907bac..f0cdc84 100755 --- a/everware/home_handler.py +++ b/everware/home_handler.py @@ -8,6 +8,7 @@ from . import __version__ from .github_agent import * from .metrica import MetricaIdsMixin +from datetime import datetime @gen.coroutine def is_repository_changed(user): @@ -30,6 +31,32 @@ def is_repository_changed(user): else: return False +@gen.coroutine +def commit_container(request, spawner, log): + image_tag = datetime.now().strftime('%Y-%m-%d_%H-%M-%S') + image_name = 'everware_image/' + spawner.escaped_name + '/' + spawner.escaped_repo_url + '_' + spawner.container_id + host_with_protocol = request.protocol + '://' + request.host + url_with_image = url_concat(host_with_protocol + '/hub/spawn', + dict(repourl='docker:' + image_name + ':' + image_tag)) + + log.info('Will commit %s' % url_with_image) + + commit = yield spawner.docker( + 'commit', + container=spawner.container_id, + repository=image_name, + tag=image_tag, + message='Commit from control panel', + author=spawner.escaped_name + ) + + output_data = dict() + if commit: + output_data['url_with_image'] = url_with_image + else: + output_data['message'] = 'Sorry, can not save container' + + return output_data class HomeHandler(BaseHandler): """Render the user's home page.""" @@ -43,7 +70,9 @@ def get(self): do_fork = self.get_argument('do_fork', False) do_push = self.get_argument('do_push', False) + do_commit_container = self.get_argument('do_commit_container', False) notify_message = self.get_argument('message', '') + notify_url_to_image = self.get_argument('url_with_image', '') if repourl: self.redirect(url_concat( url_path_join(self.hub.server.base_url, 'spawn'), all_arguments @@ -58,6 +87,11 @@ def get(self): branch_name = user.spawner.branch_name commit_sha = user.spawner.commit_sha repo_url = user.spawner.repo_url + + if user.running and do_commit_container: + output_data = yield commit_container(self.request, user.spawner, self.log) + self.redirect(url_concat('/hub/home', output_data)) + if user.running and getattr(user, 'login_service', '') == 'github': if do_fork: self.log.info('Will fork %s' % user.spawner.repo_url) @@ -104,6 +138,7 @@ def get(self): branch_name=branch_name, commit_sha=commit_sha, notify_message=notify_message, + notify_url_to_image=notify_url_to_image, version=__version__, g_analitics_id=g_id, ya_metrica_id=ya_id diff --git a/everware/spawner.py b/everware/spawner.py index f382409..0eb461f 100755 --- a/everware/spawner.py +++ b/everware/spawner.py @@ -14,7 +14,8 @@ from traitlets import ( Integer, Unicode, - Int + Int, + Bool ) from tornado import gen from tornado.httpclient import HTTPError @@ -251,12 +252,19 @@ def wait_up(self): yield self.notify_about_fail(message) raise e + share_user_images = Bool(default_value=True, config=True, help="If True, users will be able restore only own images") @gen.coroutine def build_image(self): """download the repo and build a docker image if needed""" if self.form_repo_url.startswith('docker:'): image_name = self.form_repo_url.replace('docker:', '') + + if image_name.startswith('everware_image') and not self.user.admin and self.share_user_images: + images_user = image_name.split('/')[1] + if self.escaped_name != images_user: + raise Exception('Access denied. Image %s is not yours.' % image_name) + image = yield self.get_image(image_name) if image is None: raise Exception('Image %s doesn\'t exist' % image_name) diff --git a/share/static/html/home.html b/share/static/html/home.html index 925ec3d..9c00091 100755 --- a/share/static/html/home.html +++ b/share/static/html/home.html @@ -21,6 +21,7 @@ {% else %}
You don't have a repository with the same name. Do you want to fork it?
{% endif %} +Also you can save container to easily restore your work later.
{% endif %} @@ -70,12 +71,23 @@ > {{notify_message}} + {% if notify_url_to_image %} +