From dbffff05225f356fa011529a4dc8e895c09c2522 Mon Sep 17 00:00:00 2001
From: Matt Landis <matt@windmill.engineering>
Date: Mon, 2 May 2022 16:35:16 -0400
Subject: [PATCH 1/3] restart_process: modify image entrypoint to make
 compatible with k8s_custom_deploy

---
 restart_process/README.md                     |  6 +++--
 restart_process/Tiltfile                      | 24 +++++++++--------
 .../test/{Dockerfile => Dockerfile.failing}   |  0
 restart_process/test/Dockerfile.test          |  7 +++++
 restart_process/test/Tiltfile                 |  2 +-
 restart_process/test/custom_deploy.Tiltfile   | 26 +++++++++++++++++++
 restart_process/test/deployment.yaml          | 16 ++++++++++++
 restart_process/test/start.sh                 | 11 ++++++++
 restart_process/test/test-custom-deploy.sh    | 23 ++++++++++++++++
 .../{test-custom.sh => test-custom-fail.sh}   |  0
 .../{test-docker.sh => test-docker-fail.sh}   |  0
 restart_process/test/test.sh                  |  5 ++--
 12 files changed, 104 insertions(+), 16 deletions(-)
 rename restart_process/test/{Dockerfile => Dockerfile.failing} (100%)
 create mode 100644 restart_process/test/Dockerfile.test
 create mode 100644 restart_process/test/custom_deploy.Tiltfile
 create mode 100644 restart_process/test/deployment.yaml
 create mode 100755 restart_process/test/start.sh
 create mode 100755 restart_process/test/test-custom-deploy.sh
 rename restart_process/test/{test-custom.sh => test-custom-fail.sh} (100%)
 rename restart_process/test/{test-docker.sh => test-docker-fail.sh} (100%)

diff --git a/restart_process/README.md b/restart_process/README.md
index b47f82ef5..882bbdb9a 100644
--- a/restart_process/README.md
+++ b/restart_process/README.md
@@ -21,8 +21,10 @@ This extension does NOT support process restarts for:
 - Images built with `custom_build` using any of the `skips_local_docker`, `disable_push`, or `tag` parameters.
 - Images run in Docker Compose resources (use the [`restart_container()`](https://docs.tilt.dev/api.html#api.restart_container) builtin instead)
 - Images without a shell (e.g. `scratch`, `distroless`)
-- Container commands specified as `command` in Kubernetes YAML will be overridden by this extension.
-  - However, the `args` field is still available; [reach out](https://tilt.dev/contact) if you need help navigating the interplay between Tilt and these YAML values
+- For `ContainerSpec`s that specify a `command` in the Kubernetes YAML:
+  - If the YAML is known during Tiltfile execution (i.e., isn't using `k8s\_custom\_deploy` or similar), the command will be overridden by this extension.
+    - However, the `args` field is still available; [reach out](https://tilt.dev/contact) if you need help navigating the interplay between Tilt and these YAML values
+  - If the YAML comes via `k8s\_custom\_deploy` or similar and specifies a `command` in its `ContainerSpec`, then this extension will not work.
 - CRDs
 
 If this extension doesn't work for your use case, [see our docs for alternatives](https://docs.tilt.dev/live_update_reference.html#restarting-your-process).
diff --git a/restart_process/Tiltfile b/restart_process/Tiltfile
index f78161f14..cb4a9090c 100644
--- a/restart_process/Tiltfile
+++ b/restart_process/Tiltfile
@@ -26,17 +26,6 @@ def _helper(base_ref, ref, entrypoint, live_update, restart_file=RESTART_FILE, t
     if not trigger:
         trigger = []
 
-    # declare a new docker build that adds a static binary of tilt-restart-wrapper
-    # (which makes use of `entr` to watch files and restart processes) to the user's image
-    df = '''
-    FROM tiltdev/restart-helper:2021-11-03 as restart-helper
-
-    FROM {}
-    RUN ["touch", "{}"]
-    COPY --from=restart-helper /tilt-restart-wrapper /
-    COPY --from=restart-helper /entr /
-    '''.format(base_ref, restart_file)
-
     # Change the entrypoint to use `tilt-restart-wrapper`.
     # `tilt-restart-wrapper` makes use of `entr` (https://github.com/eradman/entr/) to
     # re-execute $entrypoint whenever $restart_file changes
@@ -50,6 +39,19 @@ def _helper(base_ref, ref, entrypoint, live_update, restart_file=RESTART_FILE, t
     else:
         fail("`entrypoint` must be a string or list of strings: got {}".format(type(entrypoint)))
 
+    # declare a new docker build that adds a static binary of tilt-restart-wrapper
+    # (which makes use of `entr` to watch files and restart processes) to the user's image
+    # we also set the image's entrypoint to give k8s_custom_deploy a chance of working: https://github.com/tilt-dev/tilt-extensions/issues/391
+    df = '''
+    FROM tiltdev/restart-helper:2021-11-03 as restart-helper
+
+    FROM {}
+    RUN ["touch", "{}"]
+    COPY --from=restart-helper /tilt-restart-wrapper /
+    COPY --from=restart-helper /entr /
+    ENTRYPOINT {}
+    '''.format(base_ref, restart_file, entrypoint_with_entr)
+
     # last live_update step should always be to modify $restart_file, which
     # triggers the process wrapper to rerun $entrypoint
     # NB: write `date` instead of just `touch`ing because `entr` doesn't respond
diff --git a/restart_process/test/Dockerfile b/restart_process/test/Dockerfile.failing
similarity index 100%
rename from restart_process/test/Dockerfile
rename to restart_process/test/Dockerfile.failing
diff --git a/restart_process/test/Dockerfile.test b/restart_process/test/Dockerfile.test
new file mode 100644
index 000000000..cfbeb9faf
--- /dev/null
+++ b/restart_process/test/Dockerfile.test
@@ -0,0 +1,7 @@
+FROM alpine
+
+RUN echo 0 > restart_count.txt
+
+ADD start.sh /
+
+ENTRYPOINT /start.sh
diff --git a/restart_process/test/Tiltfile b/restart_process/test/Tiltfile
index 5a943f930..9b0e1b9a7 100644
--- a/restart_process/test/Tiltfile
+++ b/restart_process/test/Tiltfile
@@ -1,5 +1,5 @@
 load('../Tiltfile', 'docker_build_with_restart')
 
 k8s_yaml('job.yaml')
-docker_build_with_restart('failing_job', '.', '/fail.sh',
+docker_build_with_restart('failing_job', '.', dockerfile='Dockerfile.failing', entrypoint='/fail.sh',
                           live_update=[sync('./fail.sh', '/fail.sh')])
diff --git a/restart_process/test/custom_deploy.Tiltfile b/restart_process/test/custom_deploy.Tiltfile
new file mode 100644
index 000000000..6d5b72629
--- /dev/null
+++ b/restart_process/test/custom_deploy.Tiltfile
@@ -0,0 +1,26 @@
+load('../Tiltfile', 'docker_build_with_restart')
+docker_build_with_restart('testimage', '.', dockerfile='Dockerfile.test', entrypoint='/start.sh', live_update=[sync('start.sh', '/start.sh')])
+k8s_custom_deploy(
+  'custom_deploy',
+  deps=['deployment.yaml'],
+  apply_cmd='sed -e"s|image: testimage|image: ${TILT_IMAGE_0}|" deployment.yaml | kubectl apply -f - -oyaml',
+  delete_cmd='kubectl delete -f deployment.yaml',
+  image_deps=['testimage'],
+)
+
+# trigger a live update and see if the process is restarted
+local_resource('test_update', '''
+touch start.sh
+# seconds
+TIMEOUT=5
+for ((i=0;i<=$TIMEOUT;++i)) do
+  tilt logs | grep -v test_update | grep -q "RESTART_COUNT: 1"
+  if [[ $? -eq 0 ]]; then
+    echo restart detected
+    exit 0
+  fi
+  echo no restart detected
+  sleep 1
+done
+exit 1
+''', resource_deps=['custom_deploy'])
diff --git a/restart_process/test/deployment.yaml b/restart_process/test/deployment.yaml
new file mode 100644
index 000000000..8be778ce4
--- /dev/null
+++ b/restart_process/test/deployment.yaml
@@ -0,0 +1,16 @@
+apiVersion: apps/v1
+kind: Deployment
+metadata:
+  name: testdeploy
+spec:
+  selector:
+    matchLabels:
+      app: testdeploy
+  template:
+    metadata:
+      labels:
+        app: testdeploy
+    spec:
+      containers:
+      - name: testcontainer
+        image: testimage
diff --git a/restart_process/test/start.sh b/restart_process/test/start.sh
new file mode 100755
index 000000000..39b964d05
--- /dev/null
+++ b/restart_process/test/start.sh
@@ -0,0 +1,11 @@
+#!/bin/sh
+set -euo pipefail
+RESTART_COUNT="$(cat restart_count.txt)"
+echo "RESTART_COUNT: $RESTART_COUNT"
+RESTART_COUNT=$((RESTART_COUNT+1))
+echo $RESTART_COUNT > restart_count.txt
+while true
+do
+  echo running
+  sleep 5
+done
diff --git a/restart_process/test/test-custom-deploy.sh b/restart_process/test/test-custom-deploy.sh
new file mode 100755
index 000000000..cd8c4b855
--- /dev/null
+++ b/restart_process/test/test-custom-deploy.sh
@@ -0,0 +1,23 @@
+#!/bin/bash
+
+# make sure that docker_build_with_restart works with k8s_custom_deploy
+# https://github.com/tilt-dev/tilt-extensions/issues/391
+
+cd "$(dirname "$0")" || exit
+
+set -x
+tilt down -f custom_deploy.Tiltfile
+
+tilt up -f custom_deploy.Tiltfile --stream > tilt.log &
+TILT_PID=$!
+
+sleep 1
+timeout 30 tail -f tilt.log  | grep -q "test_update │ restart detected"
+RESULT=$?
+cat tilt.log
+
+kill $TILT_PID
+tilt down
+rm tilt.log
+
+exit $RESULT
diff --git a/restart_process/test/test-custom.sh b/restart_process/test/test-custom-fail.sh
similarity index 100%
rename from restart_process/test/test-custom.sh
rename to restart_process/test/test-custom-fail.sh
diff --git a/restart_process/test/test-docker.sh b/restart_process/test/test-docker-fail.sh
similarity index 100%
rename from restart_process/test/test-docker.sh
rename to restart_process/test/test-docker-fail.sh
diff --git a/restart_process/test/test.sh b/restart_process/test/test.sh
index 2705502a1..e84236394 100755
--- a/restart_process/test/test.sh
+++ b/restart_process/test/test.sh
@@ -3,5 +3,6 @@
 set -ex
 
 cd "$(dirname "$0")"
-./test-docker.sh
-./test-custom.sh
+./test-docker-fail.sh
+./test-custom-fail.sh
+./test-custom-deploy.sh

From 13dfc5e92462762e88cfdb0576abab49b7271d0d Mon Sep 17 00:00:00 2001
From: Matt Landis <matt@windmill.engineering>
Date: Mon, 2 May 2022 17:55:52 -0400
Subject: [PATCH 2/3] fix failing test

---
 restart_process/test/custom.Tiltfile | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/restart_process/test/custom.Tiltfile b/restart_process/test/custom.Tiltfile
index 692a9bced..ea383e874 100644
--- a/restart_process/test/custom.Tiltfile
+++ b/restart_process/test/custom.Tiltfile
@@ -3,7 +3,7 @@ load('../Tiltfile', 'custom_build_with_restart')
 k8s_yaml('job.yaml')
 custom_build_with_restart(
   'failing_job',
-  command='docker build -t $EXPECTED_REF .',
+  command='docker build -t $EXPECTED_REF -f Dockerfile.failing .',
   deps=['fail.sh'],
   entrypoint='/fail.sh',
   live_update=[sync('./fail.sh', '/fail.sh')])

From c01fa52a65be3cdeb89d5c09f49aea845b0127fa Mon Sep 17 00:00:00 2001
From: Matt Landis <matt@windmill.engineering>
Date: Tue, 3 May 2022 16:09:41 -0400
Subject: [PATCH 3/3] move inline shell to shell script

---
 restart_process/test/custom_deploy.Tiltfile   | 16 +--------------
 .../test/trigger_custom_deploy_live_update.sh | 20 +++++++++++++++++++
 2 files changed, 21 insertions(+), 15 deletions(-)
 create mode 100755 restart_process/test/trigger_custom_deploy_live_update.sh

diff --git a/restart_process/test/custom_deploy.Tiltfile b/restart_process/test/custom_deploy.Tiltfile
index 6d5b72629..3545d6f21 100644
--- a/restart_process/test/custom_deploy.Tiltfile
+++ b/restart_process/test/custom_deploy.Tiltfile
@@ -9,18 +9,4 @@ k8s_custom_deploy(
 )
 
 # trigger a live update and see if the process is restarted
-local_resource('test_update', '''
-touch start.sh
-# seconds
-TIMEOUT=5
-for ((i=0;i<=$TIMEOUT;++i)) do
-  tilt logs | grep -v test_update | grep -q "RESTART_COUNT: 1"
-  if [[ $? -eq 0 ]]; then
-    echo restart detected
-    exit 0
-  fi
-  echo no restart detected
-  sleep 1
-done
-exit 1
-''', resource_deps=['custom_deploy'])
+local_resource('test_update', './trigger_custom_deploy_live_update.sh', resource_deps=['custom_deploy'])
diff --git a/restart_process/test/trigger_custom_deploy_live_update.sh b/restart_process/test/trigger_custom_deploy_live_update.sh
new file mode 100755
index 000000000..252f3f647
--- /dev/null
+++ b/restart_process/test/trigger_custom_deploy_live_update.sh
@@ -0,0 +1,20 @@
+#!/bin/bash
+
+set -u
+
+# triggers a live update and waits for the tilt logs to reflect the process was restarted
+# exits 0 if it's successfully restarted, or 1 if not
+
+touch start.sh
+# seconds
+TIMEOUT=5
+for ((i=0;i<=$TIMEOUT;++i)) do
+  tilt logs | grep -v test_update | grep -q "RESTART_COUNT: 1"
+  if [[ $? -eq 0 ]]; then
+    echo restart detected
+    exit 0
+  fi
+  echo no restart detected
+  sleep 1
+done
+exit 1