webapp_sandbox_panel.html 13.2 KB
Newer Older
1
{% extends "base.html" %}
2
{% load htmlattrs static converters %}
3
4
5
6

{% block title %}Webapp Creation for application {{ webapp.name }}{% endblock %}

{% block breadcrumb %}
7
<li class="breadcrumb-item"><a href="{% url 'main:webapp_list' %}">Applications</a></li>
BERJON Matthieu's avatar
BERJON Matthieu committed
8
<li class="breadcrumb-item"><a href="{% url 'main:webapp_detail' webapp.docker_name %}">{{ webapp.name | fancy_webapp_name | title}}</a></li>
9
10
11
12
13
14
15
16
17
18
19
<li class="breadcrumb-item active" aria-current="page">Sandbox</li>
{% endblock %}

{% block content %}
<div class="container">
  <div class="allgo-page">
    <div class="row">
      <div class="col">
        <div class="tab-content">
          <ul class="nav nav-tabs">
            <li class="nav-item"><a class="nav-link active" data-toggle="tab" href="#ssh"><i class="fas fa-terminal"></i> SSH</a></li>
20
	    {% comment    Disabled until #227 is implemented %}
21
            <li class="nav-item"><a class="nav-link" data-toggle="tab" href="#docker"><i class="fab fa-docker"></i> Docker</a></li>
22
	    {% endcomment %}
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
          </ul>
          <div class="tab-pane active" id="ssh">

            {###########  IDLE  ###########}
            {% if webapp.sandbox_state == webapp.IDLE %}
            <h5 class="mt-3">You do not have any active sandbox</h5>
            <p>In order to create and publish a new version of your application, you can either:
            <ul>
              <li>start a sandbox, connect to it via ssh, then install the
                application manually</li>
              <li>create a docker image and push it to allgo (see the Docker pane)</li>
            </ul>
            </p>

            <h5 class="mt-3">Start a sandbox</h5>

            {% if versions %}
            <h6 class="mt-3">From an existing version of your application</h6>
            <div class="form-inline">
              <form method="post">
                {% csrf_token %}
                <input type="hidden" name="action" value="start"/>
                <select name="webapp_version_id" id="webapp-version-id" class="form-control">
                  {% for version in versions %}
                  <option value="{{ version.id }}">{{ version.number }}</option>
                  {% endfor %}
                </select>
                <button type="submit" class="btn btn-primary">Start</button>
              </form>
            </div>
            {% endif %}

            <h6>From scratch</h6>
            <div class="form-inline">
              <form method="post">
                {% csrf_token %}
                <input type="hidden" name="action" value="start"/>
                <select name="docker_os_id" id="docker-os" class="form-control">
                  {% for docker_os in  docker_os_list %}
                  <option value="{{ docker_os.id }}">{{ docker_os.name }}:{{ docker_os.version }}</option>
                  {% endfor %}
                </select>
                <button type="submit" class="btn btn-primary">Start</button>
              </form>
            </div>

            {###########  RUNNING  ###########}
            {% elif webapp.sandbox_state == webapp.RUNNING %}

            <h5 class="mt-3">Your sandbox is running</h5>

            <p class="mt-3">
            In order to install your application, you can connect in SSH using
            the command below or click to the Docker panel if you prefer to use this method
            or are using continuous development. 

79
80
81
82
83
84
85
            <h5>1. Connect via SSH</h5>

            {% if not user.allgouser.sshkey %}
            <p><span class="text-danger"><i class="fas fa-exclamation-circle text-danger"></i> important:</span>
            you must <a href="{% url 'main:user_ssh_add' %}">add your public SSH key</a> to your account before using this command
            </p>
            {% endif %}
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111

            <pre class="language-bash mb-3"><code class="language-*">{{ ssh_command }}</code></pre>

            <h5>2. Install the application</h5>
            
            <p>The entrypoint configured for your webapp is:
            <tt>{{ webapp.entrypoint }}</tt>. This is the command that is
            executed when a job is run.</p>

            <h5>3. Test your webapp</h5>

            <p>You can use the <a href="{% url 'main:webapp_detail' webapp.docker_name %}"
                                  target="_blank">job creation form</a> to run a job.</p>


            <h5>4. Close your sandbox</h5>

            <p>Once you are done, you can either:
              <ul>
                <li><b>commit</b> your work, this will save the content of your
                  sandbox and make it a new version of your app</li>
                <li><b>rollback</b>, this will throw away all changes done in the
                  sandbox since it was started.</li>
              </ul>
            </p>

112
113
            <hr/>
            <h6>Commit panel</h6>
114
115
116
            <form method="post">
              {% csrf_token %}
              <input type="hidden" name="action" value="commit"/>
117
118
119
120
121
122
123
124
125
126
              <div class="form-row">
                <div class="col-md-6 col-lg-4">
                    <div class="form-check form-check-inline">
                      <input class="form-check-input" type="radio" name="version-action" value="replace-version">
                      <label class="form-check-label" for="example-radio">Replace version</label>
                    </div>
                    <div class="form-check form-check-inline">
                      <input class="form-check-input" type="radio" name="version-action" value="new-version">
                      <label class="form-check-label" for="example-radio">New version</label>
                    </div>
BERJON Matthieu's avatar
BERJON Matthieu committed
127
                </div>
128
129
130
131
                <div class="col-md-6 col-lg-6">
                  <div class="form-group">
                    <select class="form-control d-none" name="version-select">
                      {% for version in versions %}
132
                      <option data-description="{{version.description}}">{{ version.number }}</option>
133
134
135
136
                      {% endfor %}
                    </select>
                    <input type="text" class="form-control d-none" name="version-new" placeholder="new version number">
                  </div>
BERJON Matthieu's avatar
BERJON Matthieu committed
137
                </div>
138
              </div>
BERJON Matthieu's avatar
BERJON Matthieu committed
139

140
141
142
              <div class="form-row">
                <div class="col-lg-10">
                  <div class="form-group">
143
144
                    <label>Description</label>
                    <input type="text" name="description" class="form-control">
145
                  </div>
BERJON Matthieu's avatar
BERJON Matthieu committed
146
147
                </div>
              </div>
148
              <div class="form-group">
149
150
                <button type="submit" class="btn btn-primary">
                  <i class="fas fa-download"></i> Commit</button>
151
152
153
              </div>
            </form>

154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
            <p> If you whish to drop your changes, your can perform a rollback.
            <strong>CAUTION: this will discard all the work made since the sandbox was
              started</strong></p>

            <button type="button" class="btn btn-danger" data-toggle="modal" data-target="#rollback_modal">
              <i class="fas fa-times-circle"></i> Rollback
            </button>

            {#  rollback modal dialog  #}
            <div class="modal" id="rollback_modal" tabindex="-1" role="dialog">
              <div class="modal-dialog" role="document">
                <div class="modal-content">
                  <div class="modal-header">
                    <h5 class="modal-title"><i class="fas fa-exclamation-triangle"></i> rollback confirmation</h5>
                    <button type="button" class="close" data-dismiss="modal" aria-label="Close">
                      <span aria-hidden="true">&times;</span>
                    </button>
                  </div>
                  <div class="modal-body">
                    <p>This action will <strong>permanently discard all
                      changes</strong> made since the sandbox of application
                    <strong>“{{ webapp.name }}”</strong> was started.</p>
                    <p>Are you sure you want to proceed?</p>
                  </div>
                  <form method="post">
                    <div class="modal-footer">
                      <button type="button" class="btn btn-default" data-dismiss="modal">Cancel</button>
                      {% csrf_token %}
                      <input type="hidden" name="action" value="rollback"/>
                      <button type="submit" class="btn btn-danger">
                        <i class="fas fa-times-circle"></i> Confirm rollback
                      </button>
                    </div>
                  </form>
                </div>
189
              </div>
190
            </div>
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269

            {###########  STARTING  ###########}
            {% elif webapp.sandbox_state == webapp.STARTING %}
            <div class="text-center">
              <p><i class="fas fa-spinner fa-pulse fa-5x"></i><span class="text-hide">Waiting for the sandbox creation</span></p>
              <p>Please wait, your sandbox is in preparation.</p>
            </div>

            {###########  STOPPING  ###########}
            {% elif webapp.sandbox_state == webapp.STOPPING %}
            <div class="text-center">
              <p><i class="fas fa-spinner fa-pulse fa-5x"></i><span class="text-hide">Waiting for the sandbox termination</span></p>
              <p>Please wait, your sandbox is stopping.</p>
            </div>

            {###########  START_ERROR  ###########}
            {% elif webapp.sandbox_state == webapp.START_ERROR %}

            <h5 class="mt-3">Sandbox start error</h5>

            <p>Your sandbox failed to start</p>
            <form method="post">
              {% csrf_token %}
              <input type="hidden" name="action" value="retry"/>
              <button type="submit" class="btn btn-primary">Retry</button>
            </form>
            <form method="post">
              {% csrf_token %}
              <input type="hidden" name="action" value="abort"/>
              <button type="submit" class="btn btn-danger">Abort</button>
            </form>

            {###########  STOP_ERROR  ###########}
            {% elif webapp.sandbox_state == webapp.STOP_ERROR %}
            <h5 class="mt-3">Sandbox stop error</h5>

            <p>Your sandbox failed to stop</p>

            {# NOTE:  we do not show an 'Abort' button because this action  #}
            {#        is not implemented (because i am not sure that it is  #}
            {#        a good idea to throw away the version being committed #}
            <form method="post">
              {% csrf_token %}
              <input type="hidden" name="action" value="retry"/>
              <button type="submit" class="btn btn-primary">Retry</button>
            </form>

            {% endif %}

            <p><i class="fas fa-question-circle"></i> Need help? <a href="#" title="A||go user documentation">report to the documentation</a>.</p>
          </div>

          <div class="tab-pane" id="docker">
            <p class="mt-3">You can as well directly push your docker image.</p>

            <pre class="language-bash"><code class="language-*">docker login --username {{ user.get_username }} {{ request.get_host }}/{{ webapp.docker_name }}
docker build -t {{ webapp.docker_name }} .
docker push {{ request.get_host }}/{{ webapp.docker_name }}:&lt;version&gt;</code></pre>
          </div>
        </div>
      </div>
    </div>
  </div>
</div>
{% endblock %}

{% block messages %}
{{ block.super }}
{% include 'partials/_form_messages.html' %}
{% endblock %}


{% block javascript %}
{{ block.super }}
{% if webapp.sandbox_state == webapp.STARTING or webapp.sandbox_state == webapp.STOPPING %}
<script src="{% static 'js/json_seq_events.js' %}"></script>
<script>
json_seq_event_listener("/aio/apps/{{ webapp.docker_name }}/events",
    function(msg) {
270
271
272
273
      if (msg == undefined) {
              console.log("events channel closed (EOF from server)");
              return;
      }
274
275
276
277
278
279
280
281
282
283
284
285
      if (msg.sandbox_state) {
        // refresh the page when sandbox is ready
        if (!["STARTING", "STOPPING"].includes(msg.sandbox_state)) {
          location.reload()
        }
      }
    },
    function(status, msg) {
      console.log("error:", status, msg);
    }); 

</script>
BERJON Matthieu's avatar
BERJON Matthieu committed
286

287
{% endif %}
BERJON Matthieu's avatar
BERJON Matthieu committed
288
289

<script>
290
(function() {
291
  function reset_description(replace) {
292
    if (replace) {
293
294
      $("input[name='description']").val(
          $("[name='version-select'] > :selected").attr("data-description"))
295
    } else {
296
      $("input[name='description']").val("")
297
298
299
300
301
302
303
304
305
    }
  }
  function switch_version_display(replace) {
    if (replace) {
      $("[name='version-select']").removeClass("d-none")
      $("[name='version-new']").addClass("d-none")
    } else {
      $("[name='version-new']").removeClass("d-none")
      $("[name='version-select']").addClass("d-none")
BERJON Matthieu's avatar
BERJON Matthieu committed
306
    }
307
    reset_description(replace);
308
  }
BERJON Matthieu's avatar
BERJON Matthieu committed
309

310
311
  $("[name='version-action']").change(function(ev) {
    switch_version_display(ev.target.value == "replace-version");
BERJON Matthieu's avatar
BERJON Matthieu committed
312
  });
313
  $("[name='version-select']").change(function(){
314
    reset_description(true);
315
316
317
318
319
320
321
322
323
324
325
326
  })

  {% if webapp.sandbox_version %}
    $("[value='replace-version']").prop("checked", true)
    $("[name='version-select']").val("{{webapp.sandbox_version.number}}");
    switch_version_display(true);
  {% else %}
    $("[value='new-version']").prop("checked", true)
    switch_version_display(false);
  {% endif %}

}());
BERJON Matthieu's avatar
BERJON Matthieu committed
327
</script>
328
{% endblock %}