Repository: deis/deis

Issue:
deleting an app doesn't delete the git repo
so it's still possible to push to that repo, and then you get an error when the slugbuilder-hook calls the push-hook saying "App matching query does not exist"



Discussion:
We need to re-test this with the newly merged **containerize** branch. (Note to self.)

@gabrtv: this is still a problem in containerize (master). We need to explore catching etcd delete events and removing directories accordingly.

We could transparently resolve this issue in #533. No git, no problem.

For clarity, this is what I see on my end when pushing an app:

```
><> cd ..
><> deis destroy --app=owlish-huntress

 !    WARNING: Potentially Destructive Action
 !    This command will destroy the application: owlish-huntress
 !    To proceed, type "owlish-huntress" or re-run this command with --confirm=owlish-huntress

> owlish-huntress
Destroying owlish-huntress... done in 0s
><> l
deis                      deis-cookbook             example-dockerfile-python
><> cd example-dockerfile-python/
><> git push deis master
-----> Building Docker image
Uploading context 5.632 kB
Uploading context
Step 0 : FROM ubuntu:12.04
 ---> 9cd978db300e
Step 1 : MAINTAINER OpDemand <info@opdemand.com>
 ---> Using cache
 ---> da93d76703b7
Step 2 : ENV PORT 8000
 ---> Using cache
 ---> b6046ec54bb3
Step 3 : ADD . /app
 ---> 107063149fee
Step 4 : WORKDIR /app
 ---> Running in 50855663ef23
 ---> 98a16df9e7ac
Step 5 : CMD python -m SimpleHTTPServer $PORT
 ---> Running in a5409cc9782b
 ---> b5b7ca45071a
Successfully built b5b7ca45071a
-----> Pushing image to private registry

       Launching... Build hook error: 404 {"detail": "Not found"}
error: failed to push some refs to 'ssh://git@bacongobbler.com:2222/owlish-huntress.git'
```

This bug is also a blocker for creating apps with the same name. For example, if I go ahead and create an app called foo, then destroy it and re-create the app and name it foo again, it will return with `Everything up-to-date` since the same SHA is being pushed to the repository.

Yes, that's exactly what @smothiki was running into yesterday with the integration tests.

temporary fix for this is to manually delete the git from the deis-builder container, through the nse.
Any idea of where exactly in the code is the destroy app section? We may try to fix this in our own clone.

Thanks

@ntmggr I'm currently working on a fix for this. I should have it finished by the end of the week.

@ntmggr it might be here i am guessing? https://github.com/deis/deis/blob/master/controller/api/models.py#L140

It's a little more complicated than that... The controller and the builder are in two separate containers, so they have to be managed seperately. I'm looking at fixing this with a script that's being templated out by confd to clean up applications that do not exist in the controller.


Resolving patch:
diff --git a/controller/api/models.py b/controller/api/models.py
--- a/controller/api/models.py
+++ b/controller/api/models.py
@@ -626,6 +626,17 @@ def _etcd_purge_user(**kwargs):
         pass
 
 
+def _etcd_create_app(**kwargs):
+    appname = kwargs['instance']
+    if kwargs['created']:
+        _etcd_client.write('/deis/services/{}'.format(appname), None, dir=True)
+
+
+def _etcd_purge_app(**kwargs):
+    appname = kwargs['instance']
+    _etcd_client.delete('/deis/services/{}'.format(appname), dir=True, recursive=True)
+
+
 def _etcd_publish_domains(**kwargs):
     app = kwargs['instance'].app
     app_domains = app.domain_set.all()
@@ -664,3 +675,5 @@ def _save_transition(**kwargs):
     post_delete.connect(_etcd_purge_user, sender=User, dispatch_uid='api.models')
     post_save.connect(_etcd_publish_domains, sender=Domain, dispatch_uid='api.models')
     post_delete.connect(_etcd_publish_domains, sender=Domain, dispatch_uid='api.models')
+    post_save.connect(_etcd_create_app, sender=App, dispatch_uid='api.models')
+    post_delete.connect(_etcd_purge_app, sender=App, dispatch_uid='api.models')


Test patch:
diff --git a/builder/tests/builder_test.go b/builder/tests/builder_test.go
--- a/builder/tests/builder_test.go
+++ b/builder/tests/builder_test.go
@@ -49,6 +49,7 @@ func TestBuilder(t *testing.T) {
 		"/deis/database",
 		"/deis/registry",
 		"/deis/domains",
+		"/deis/services",
 	}
 	testID := utils.NewUuid()
 	err := dockercliutils.BuildImage(t, "../", "deis/builder:"+testID)