diff --git a/ipynbsrv/api/urls.py b/ipynbsrv/api/urls.py index 9678966..4980342 100644 --- a/ipynbsrv/api/urls.py +++ b/ipynbsrv/api/urls.py @@ -36,7 +36,6 @@ url(r'^containers/(?P[0-9]+)/snapshots/?$', views.ContainerSnapshotsList.as_view(), name="container_snapshots"), url(r'^containers/(?P[0-9]+)/commit$', views.container_commit, name="container_commit"), url(r'^containers/(?P[0-9]+)/create_snapshot$', views.container_create_snapshot, name="container_create_snapshot"), - url(r'^containers/(?P[0-9]+)/restore_snapshot$', views.container_restore_snapshot, name="container_restore_snapshot"), url(r'^containers/(?P[0-9]+)/restart$', views.container_restart, name="container_restart"), url(r'^containers/(?P[0-9]+)/resume$', views.container_resume, name="container_resume"), url(r'^containers/(?P[0-9]+)/start$', views.container_start, name="container_start"), @@ -50,6 +49,7 @@ # /api/container/snapshots(/)... url(r'^containers/snapshots/?$', views.ContainerSnapshotList.as_view(), name="snapshot"), url(r'^containers/snapshots/(?P[0-9]+)$', views.ContainerSnapshotDetail.as_view(), name="snapshot_detail"), + url(r'^containers/snapshots/(?P[0-9]+)/restore$', views.container_snapshot_restore, name="container_snapshot_restore"), # /api/servers(/)... url(r'^servers/?$', views.ServerList.as_view(), name="servers"), diff --git a/ipynbsrv/api/views.py b/ipynbsrv/api/views.py index 1413761..b5110b6 100644 --- a/ipynbsrv/api/views.py +++ b/ipynbsrv/api/views.py @@ -589,37 +589,6 @@ def container_create_snapshot(request, pk): return Response({"error": "Container not found!", "pk": pk}) -@api_view(['POST']) -def container_restore_snapshot(request, pk): - """ - Restore a snapshot of the container. - Todo: show params on OPTIONS call. - :param pk pk of the container that needs to be cloned - """ - params = {} - - data = request.data - - if not data.get('id'): - return Response({"error": "please provide name for the clone: {\"name\" : \"some name \"}"}) - - params['id'] = data.get('id') - - container = get_container(pk) - - # validate permissions - validate_object_permission(ContainerDetailPermission, request, container) - - snapshots = ContainerSnapshot.objects.filter(id=params.get('id')) - if container and snapshots: - s = snapshots.first() - s.restore() - serializer = ContainerSerializer(container) - return Response(serializer.data, status=status.HTTP_201_CREATED) - else: - return Response({"error": "Container or Snapshot not found!", "pk": pk}) - - @api_view(['GET']) def container_clones(request, pk): container = get_container(pk) @@ -799,6 +768,26 @@ class ContainerSnapshotDetail(generics.RetrieveUpdateDestroyAPIView): queryset = ContainerSnapshot.objects.all() +@api_view(['POST']) +def container_snapshot_restore(request, pk): + """ + Restore a snapshot of the container. + Todo: show params on OPTIONS call. + :param pk pk of the container that needs to be cloned + """ + snapshots = ContainerSnapshot.objects.filter(id=pk) + if snapshots: + s = snapshots.first() + container = s.container + # validate permissions + validate_object_permission(ContainerDetailPermission, request, container) + s.restore() + serializer = ContainerSerializer(container) + return Response(serializer.data, status=status.HTTP_201_CREATED) + else: + return Response({"error": "Snapshot not found!", "pk": pk}) + + class ServerList(generics.ListCreateAPIView): """ Get a list of all the servers. diff --git a/ipynbsrv/core/models.py b/ipynbsrv/core/models.py index ade260d..dfd6d67 100644 --- a/ipynbsrv/core/models.py +++ b/ipynbsrv/core/models.py @@ -883,7 +883,8 @@ def restore(self): """ TODO: write doc. """ - pass + from ipynbsrv.core.signals.signals import container_snapshot_restored + container_snapshot_restored.send(sender=self, snapshot=self) def save(self, *args, **kwargs): """ diff --git a/ipynbsrv/core/signals/container_snapshots.py b/ipynbsrv/core/signals/container_snapshots.py index bc9bb50..3c9a329 100644 --- a/ipynbsrv/core/signals/container_snapshots.py +++ b/ipynbsrv/core/signals/container_snapshots.py @@ -47,7 +47,13 @@ def restore_on_server(sender, snapshot, **kwargs): """ Restore the restored snapshot on the container backend. """ - pass + if snapshot is not None: + backend = snapshot.container.server.get_container_backend() + try: + backend.restore_container_snapshot(snapshot.container.backend_pk, snapshot.backend_pk) + except ContainerBackendError as ex: + # XXX: restore? + raise ex @receiver(post_delete, sender=ContainerSnapshot) diff --git a/ipynbsrv/web/templates/web/container_snapshots/index.html b/ipynbsrv/web/templates/web/container_snapshots/index.html index 5df0e00..473e3a6 100644 --- a/ipynbsrv/web/templates/web/container_snapshots/index.html +++ b/ipynbsrv/web/templates/web/container_snapshots/index.html @@ -40,7 +40,6 @@

Container Snapshots

{% csrf_token %} - diff --git a/ipynbsrv/web/views/containers.py b/ipynbsrv/web/views/containers.py index d8054bd..606d3b8 100644 --- a/ipynbsrv/web/views/containers.py +++ b/ipynbsrv/web/views/containers.py @@ -374,24 +374,27 @@ def restore_snapshot(request): if request.method != "POST": messages.error(request, "Invalid request method.") return redirect('containers') - if 'id' not in request.POST or 'ct_id' not in request.POST: + if 'id' not in request.POST: messages.error(request, "Invalid POST request.") return redirect('containers') - ct_id = int(request.POST.get('ct_id')) params = {} - params['id'] = int(request.POST.get('id')) + id = int(request.POST.get('id')) client = get_httpclient_instance(request) - # create snapshot - try: - client.containers(ct_id).restore_snapshot.post(params) - messages.success(request, "Sucessfully restored snapshot `{}`.".format(params.get('name'))) - except Exception as e: - messages.error(request, api_error_message(e, params)) + snapshot = client.containers.snapshots(id).get() + if snapshot: + # restore snapshot + try: + client.containers.snapshots(id).restore.post() + messages.success(request, "Sucessfully restored snapshot `{}`.".format(snapshot.name) + except Exception as e: + messages.error(request, api_error_message(e, "")) + else: + messages.error(request, "Snapshot not found") - return redirect('container_snapshots', ct_id) + return redirect('container_snapshots', snapshot.container.id) @user_passes_test(login_allowed)