Merge lp:~stylesen/lava-scheduler/multinode-original-definition-addition into lp:lava-scheduler/multinode
- multinode-original-definition-addition
- Merge into multinode
Proposed by
Senthil Kumaran S
Status: | Merged |
---|---|
Approved by: | Neil Williams |
Approved revision: | 273 |
Merged at revision: | 273 |
Proposed branch: | lp:~stylesen/lava-scheduler/multinode-original-definition-addition |
Merge into: | lp:lava-scheduler/multinode |
Prerequisite: | lp:~stylesen/lava-scheduler/multinode |
Diff against target: |
280 lines (+219/-0) 6 files modified
lava_scheduler_app/migrations/0031_auto__add_field_testjob_multinode_definition.py (+162/-0) lava_scheduler_app/models.py (+6/-0) lava_scheduler_app/templates/lava_scheduler_app/job_sidebar.html (+5/-0) lava_scheduler_app/templates/lava_scheduler_app/multinode_job_definition.html (+21/-0) lava_scheduler_app/urls.py (+6/-0) lava_scheduler_app/views.py (+19/-0) |
To merge this branch: | bzr merge lp:~stylesen/lava-scheduler/multinode-original-definition-addition |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Neil Williams | Approve | ||
Review via email: mp+180136@code.launchpad.net |
Commit message
Description of the change
Add original multinode job definition json to the job in dashboard apart from the split definition specific to that job.
See https:/
To post a comment you must log in.
Preview Diff
[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1 | === added file 'lava_scheduler_app/migrations/0031_auto__add_field_testjob_multinode_definition.py' |
2 | --- lava_scheduler_app/migrations/0031_auto__add_field_testjob_multinode_definition.py 1970-01-01 00:00:00 +0000 |
3 | +++ lava_scheduler_app/migrations/0031_auto__add_field_testjob_multinode_definition.py 2013-08-14 13:44:42 +0000 |
4 | @@ -0,0 +1,162 @@ |
5 | +# -*- coding: utf-8 -*- |
6 | +import datetime |
7 | +from south.db import db |
8 | +from south.v2 import SchemaMigration |
9 | +from django.db import models |
10 | + |
11 | + |
12 | +class Migration(SchemaMigration): |
13 | + |
14 | + def forwards(self, orm): |
15 | + # Adding field 'TestJob.multinode_definition' |
16 | + db.add_column('lava_scheduler_app_testjob', 'multinode_definition', |
17 | + self.gf('django.db.models.fields.TextField')(default='', blank=True), |
18 | + keep_default=False) |
19 | + |
20 | + |
21 | + def backwards(self, orm): |
22 | + # Deleting field 'TestJob.multinode_definition' |
23 | + db.delete_column('lava_scheduler_app_testjob', 'multinode_definition') |
24 | + |
25 | + |
26 | + models = { |
27 | + 'auth.group': { |
28 | + 'Meta': {'object_name': 'Group'}, |
29 | + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), |
30 | + 'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '80'}), |
31 | + 'permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'}) |
32 | + }, |
33 | + 'auth.permission': { |
34 | + 'Meta': {'ordering': "('content_type__app_label', 'content_type__model', 'codename')", 'unique_together': "(('content_type', 'codename'),)", 'object_name': 'Permission'}, |
35 | + 'codename': ('django.db.models.fields.CharField', [], {'max_length': '100'}), |
36 | + 'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['contenttypes.ContentType']"}), |
37 | + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), |
38 | + 'name': ('django.db.models.fields.CharField', [], {'max_length': '50'}) |
39 | + }, |
40 | + 'auth.user': { |
41 | + 'Meta': {'object_name': 'User'}, |
42 | + 'date_joined': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}), |
43 | + 'email': ('django.db.models.fields.EmailField', [], {'max_length': '75', 'blank': 'True'}), |
44 | + 'first_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}), |
45 | + 'groups': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Group']", 'symmetrical': 'False', 'blank': 'True'}), |
46 | + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), |
47 | + 'is_active': ('django.db.models.fields.BooleanField', [], {'default': 'True'}), |
48 | + 'is_staff': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), |
49 | + 'is_superuser': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), |
50 | + 'last_login': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}), |
51 | + 'last_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}), |
52 | + 'password': ('django.db.models.fields.CharField', [], {'max_length': '128'}), |
53 | + 'user_permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'}), |
54 | + 'username': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '30'}) |
55 | + }, |
56 | + 'contenttypes.contenttype': { |
57 | + 'Meta': {'ordering': "('name',)", 'unique_together': "(('app_label', 'model'),)", 'object_name': 'ContentType', 'db_table': "'django_content_type'"}, |
58 | + 'app_label': ('django.db.models.fields.CharField', [], {'max_length': '100'}), |
59 | + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), |
60 | + 'model': ('django.db.models.fields.CharField', [], {'max_length': '100'}), |
61 | + 'name': ('django.db.models.fields.CharField', [], {'max_length': '100'}) |
62 | + }, |
63 | + 'dashboard_app.bundle': { |
64 | + 'Meta': {'ordering': "['-uploaded_on']", 'object_name': 'Bundle'}, |
65 | + '_gz_content': ('django.db.models.fields.files.FileField', [], {'max_length': '100', 'null': 'True', 'db_column': "'gz_content'"}), |
66 | + '_raw_content': ('django.db.models.fields.files.FileField', [], {'max_length': '100', 'null': 'True', 'db_column': "'content'"}), |
67 | + 'bundle_stream': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'bundles'", 'to': "orm['dashboard_app.BundleStream']"}), |
68 | + 'content_filename': ('django.db.models.fields.CharField', [], {'max_length': '256'}), |
69 | + 'content_sha1': ('django.db.models.fields.CharField', [], {'max_length': '40', 'unique': 'True', 'null': 'True'}), |
70 | + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), |
71 | + 'is_deserialized': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), |
72 | + 'uploaded_by': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'uploaded_bundles'", 'null': 'True', 'to': "orm['auth.User']"}), |
73 | + 'uploaded_on': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.utcnow'}) |
74 | + }, |
75 | + 'dashboard_app.bundlestream': { |
76 | + 'Meta': {'object_name': 'BundleStream'}, |
77 | + 'group': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.Group']", 'null': 'True', 'blank': 'True'}), |
78 | + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), |
79 | + 'is_anonymous': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), |
80 | + 'is_public': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), |
81 | + 'name': ('django.db.models.fields.CharField', [], {'max_length': '64', 'blank': 'True'}), |
82 | + 'pathname': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '128'}), |
83 | + 'slug': ('django.db.models.fields.CharField', [], {'max_length': '64', 'blank': 'True'}), |
84 | + 'user': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.User']", 'null': 'True', 'blank': 'True'}) |
85 | + }, |
86 | + 'lava_scheduler_app.device': { |
87 | + 'Meta': {'object_name': 'Device'}, |
88 | + 'current_job': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'+'", 'null': 'True', 'on_delete': 'models.SET_NULL', 'to': "orm['lava_scheduler_app.TestJob']", 'blank': 'True', 'unique': 'True'}), |
89 | + 'device_type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['lava_scheduler_app.DeviceType']"}), |
90 | + 'device_version': ('django.db.models.fields.CharField', [], {'default': 'None', 'max_length': '200', 'null': 'True', 'blank': 'True'}), |
91 | + 'health_status': ('django.db.models.fields.IntegerField', [], {'default': '0'}), |
92 | + 'hostname': ('django.db.models.fields.CharField', [], {'max_length': '200', 'primary_key': 'True'}), |
93 | + 'last_health_report_job': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'+'", 'null': 'True', 'on_delete': 'models.SET_NULL', 'to': "orm['lava_scheduler_app.TestJob']", 'blank': 'True', 'unique': 'True'}), |
94 | + 'status': ('django.db.models.fields.IntegerField', [], {'default': '1'}), |
95 | + 'tags': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['lava_scheduler_app.Tag']", 'symmetrical': 'False', 'blank': 'True'}) |
96 | + }, |
97 | + 'lava_scheduler_app.devicestatetransition': { |
98 | + 'Meta': {'object_name': 'DeviceStateTransition'}, |
99 | + 'created_by': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.User']", 'null': 'True', 'on_delete': 'models.SET_NULL', 'blank': 'True'}), |
100 | + 'created_on': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}), |
101 | + 'device': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'transitions'", 'to': "orm['lava_scheduler_app.Device']"}), |
102 | + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), |
103 | + 'job': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['lava_scheduler_app.TestJob']", 'null': 'True', 'on_delete': 'models.SET_NULL', 'blank': 'True'}), |
104 | + 'message': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}), |
105 | + 'new_state': ('django.db.models.fields.IntegerField', [], {}), |
106 | + 'old_state': ('django.db.models.fields.IntegerField', [], {}) |
107 | + }, |
108 | + 'lava_scheduler_app.devicetype': { |
109 | + 'Meta': {'object_name': 'DeviceType'}, |
110 | + 'display': ('django.db.models.fields.BooleanField', [], {'default': 'True'}), |
111 | + 'health_check_job': ('django.db.models.fields.TextField', [], {'default': 'None', 'null': 'True', 'blank': 'True'}), |
112 | + 'name': ('django.db.models.fields.SlugField', [], {'max_length': '50', 'primary_key': 'True'}) |
113 | + }, |
114 | + 'lava_scheduler_app.jobfailuretag': { |
115 | + 'Meta': {'object_name': 'JobFailureTag'}, |
116 | + 'description': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}), |
117 | + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), |
118 | + 'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '256'}) |
119 | + }, |
120 | + 'lava_scheduler_app.tag': { |
121 | + 'Meta': {'object_name': 'Tag'}, |
122 | + 'description': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}), |
123 | + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), |
124 | + 'name': ('django.db.models.fields.SlugField', [], {'unique': 'True', 'max_length': '50'}) |
125 | + }, |
126 | + 'lava_scheduler_app.testjob': { |
127 | + 'Meta': {'object_name': 'TestJob'}, |
128 | + '_results_bundle': ('django.db.models.fields.related.OneToOneField', [], {'null': 'True', 'db_column': "'results_bundle_id'", 'on_delete': 'models.SET_NULL', 'to': "orm['dashboard_app.Bundle']", 'blank': 'True', 'unique': 'True'}), |
129 | + '_results_link': ('django.db.models.fields.CharField', [], {'default': 'None', 'max_length': '400', 'null': 'True', 'db_column': "'results_link'", 'blank': 'True'}), |
130 | + 'actual_device': ('django.db.models.fields.related.ForeignKey', [], {'default': 'None', 'related_name': "'+'", 'null': 'True', 'blank': 'True', 'to': "orm['lava_scheduler_app.Device']"}), |
131 | + 'definition': ('django.db.models.fields.TextField', [], {}), |
132 | + 'description': ('django.db.models.fields.CharField', [], {'default': 'None', 'max_length': '200', 'null': 'True', 'blank': 'True'}), |
133 | + 'end_time': ('django.db.models.fields.DateTimeField', [], {'null': 'True', 'blank': 'True'}), |
134 | + 'failure_comment': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}), |
135 | + 'failure_tags': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'related_name': "'failure_tags'", 'blank': 'True', 'to': "orm['lava_scheduler_app.JobFailureTag']"}), |
136 | + 'group': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.Group']", 'null': 'True', 'blank': 'True'}), |
137 | + 'health_check': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), |
138 | + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), |
139 | + 'is_public': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), |
140 | + 'log_file': ('django.db.models.fields.files.FileField', [], {'default': 'None', 'max_length': '100', 'null': 'True', 'blank': 'True'}), |
141 | + 'multinode_definition': ('django.db.models.fields.TextField', [], {'blank': 'True'}), |
142 | + 'priority': ('django.db.models.fields.IntegerField', [], {'default': '50'}), |
143 | + 'requested_device': ('django.db.models.fields.related.ForeignKey', [], {'default': 'None', 'related_name': "'+'", 'null': 'True', 'blank': 'True', 'to': "orm['lava_scheduler_app.Device']"}), |
144 | + 'requested_device_type': ('django.db.models.fields.related.ForeignKey', [], {'default': 'None', 'related_name': "'+'", 'null': 'True', 'blank': 'True', 'to': "orm['lava_scheduler_app.DeviceType']"}), |
145 | + 'start_time': ('django.db.models.fields.DateTimeField', [], {'null': 'True', 'blank': 'True'}), |
146 | + 'status': ('django.db.models.fields.IntegerField', [], {'default': '0'}), |
147 | + 'sub_id': ('django.db.models.fields.CharField', [], {'max_length': '200', 'blank': 'True'}), |
148 | + 'submit_time': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}), |
149 | + 'submit_token': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['linaro_django_xmlrpc.AuthToken']", 'null': 'True', 'on_delete': 'models.SET_NULL', 'blank': 'True'}), |
150 | + 'submitter': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'+'", 'to': "orm['auth.User']"}), |
151 | + 'tags': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['lava_scheduler_app.Tag']", 'symmetrical': 'False', 'blank': 'True'}), |
152 | + 'target_group': ('django.db.models.fields.CharField', [], {'default': 'None', 'max_length': '64', 'null': 'True', 'blank': 'True'}), |
153 | + 'user': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.User']", 'null': 'True', 'blank': 'True'}) |
154 | + }, |
155 | + 'linaro_django_xmlrpc.authtoken': { |
156 | + 'Meta': {'object_name': 'AuthToken'}, |
157 | + 'created_on': ('django.db.models.fields.DateTimeField', [], {'auto_now': 'True', 'blank': 'True'}), |
158 | + 'description': ('django.db.models.fields.TextField', [], {'default': "''", 'blank': 'True'}), |
159 | + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), |
160 | + 'last_used_on': ('django.db.models.fields.DateTimeField', [], {'null': 'True'}), |
161 | + 'secret': ('django.db.models.fields.CharField', [], {'default': "'g4fgt7t5qdghq3qo3t3h5dhbj6fes2zh8n6lkncc0u0rcqxy0kaez7aacw05nc0oxjc3060pj0f1fsunjpo1btk6urfpt8xfmgefcatgmh1e7kj0ams90ikni05sd5qk'", 'unique': 'True', 'max_length': '128'}), |
162 | + 'user': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'auth_tokens'", 'to': "orm['auth.User']"}) |
163 | + } |
164 | + } |
165 | + |
166 | + complete_apps = ['lava_scheduler_app'] |
167 | \ No newline at end of file |
168 | |
169 | === modified file 'lava_scheduler_app/models.py' |
170 | --- lava_scheduler_app/models.py 2013-08-01 17:49:55 +0000 |
171 | +++ lava_scheduler_app/models.py 2013-08-14 13:44:42 +0000 |
172 | @@ -372,6 +372,11 @@ |
173 | editable=False, |
174 | ) |
175 | |
176 | + multinode_definition = models.TextField( |
177 | + editable=False, |
178 | + blank=True |
179 | + ) |
180 | + |
181 | log_file = models.FileField( |
182 | upload_to='lava-logs', default=None, null=True, blank=True) |
183 | |
184 | @@ -542,6 +547,7 @@ |
185 | requested_device=target, description=job_name, |
186 | requested_device_type=device_type, |
187 | definition=simplejson.dumps(node_json[role][c]), |
188 | + multinode_definition=json_data, |
189 | health_check=health_check, user=user, group=group, |
190 | is_public=is_public, priority=priority, |
191 | target_group=target_group) |
192 | |
193 | === modified file 'lava_scheduler_app/templates/lava_scheduler_app/job_sidebar.html' |
194 | --- lava_scheduler_app/templates/lava_scheduler_app/job_sidebar.html 2013-01-15 17:44:36 +0000 |
195 | +++ lava_scheduler_app/templates/lava_scheduler_app/job_sidebar.html 2013-08-14 13:44:42 +0000 |
196 | @@ -76,6 +76,11 @@ |
197 | <li> |
198 | <a href="{% url lava.scheduler.job.definition job.pk %}">Definition</a> |
199 | </li> |
200 | + {% if job.target_group %} |
201 | + <li> |
202 | + <a href="{% url lava.scheduler.job.multinode_definition job.pk %}"> Multinode Definition</a> |
203 | + </li> |
204 | + {% endif %} |
205 | {% if job.results_link %} |
206 | <li> |
207 | <a href="{{ job.results_link }}">Results Bundle</a> |
208 | |
209 | === added file 'lava_scheduler_app/templates/lava_scheduler_app/multinode_job_definition.html' |
210 | --- lava_scheduler_app/templates/lava_scheduler_app/multinode_job_definition.html 1970-01-01 00:00:00 +0000 |
211 | +++ lava_scheduler_app/templates/lava_scheduler_app/multinode_job_definition.html 2013-08-14 13:44:42 +0000 |
212 | @@ -0,0 +1,21 @@ |
213 | +{% extends "lava_scheduler_app/job_sidebar.html" %} |
214 | + |
215 | +{% block extrahead %} |
216 | +{{ block.super }} |
217 | +<script type="text/javascript" src="{{ STATIC_URL }}lava_scheduler_app/js/shCore.js"></script> |
218 | +<script type="text/javascript" src="{{ STATIC_URL }}lava_scheduler_app/js/shBrushJScript.js"></script> |
219 | + |
220 | +<link href="{{ STATIC_URL }}lava_scheduler_app/css/shCore.css" rel="stylesheet" type="text/css" /> |
221 | +<link href="{{ STATIC_URL }}lava_scheduler_app/css/shThemeDefault.css" rel="stylesheet" type="text/css" /> |
222 | +{% endblock %} |
223 | + |
224 | +{% block content %} |
225 | +<h2>Multinode Job defintion file - {{ job.sub_id }} </h2> |
226 | +<a href="{% url lava.scheduler.job.multinode_definition.plain job.pk %}">Download as text file</a> |
227 | +<pre class="brush: js">{{ job.multinode_definition }}</pre> |
228 | + |
229 | +<script type="text/javascript"> |
230 | + SyntaxHighlighter.all() |
231 | +</script> |
232 | + |
233 | +{% endblock %} |
234 | |
235 | === modified file 'lava_scheduler_app/urls.py' |
236 | --- lava_scheduler_app/urls.py 2013-07-17 12:48:53 +0000 |
237 | +++ lava_scheduler_app/urls.py 2013-08-14 13:44:42 +0000 |
238 | @@ -81,6 +81,12 @@ |
239 | url(r'^job/(?P<pk>[0-9]+)/definition/plain$', |
240 | 'job_definition_plain', |
241 | name='lava.scheduler.job.definition.plain'), |
242 | + url(r'^job/(?P<pk>[0-9]+)/multinode_definition$', |
243 | + 'multinode_job_definition', |
244 | + name='lava.scheduler.job.multinode_definition'), |
245 | + url(r'^job/(?P<pk>[0-9]+)/multinode_definition/plain$', |
246 | + 'multinode_job_definition_plain', |
247 | + name='lava.scheduler.job.multinode_definition.plain'), |
248 | url(r'^job/(?P<pk>[0-9]+)/log_file$', |
249 | 'job_log_file', |
250 | name='lava.scheduler.job.log_file'), |
251 | |
252 | === modified file 'lava_scheduler_app/views.py' |
253 | --- lava_scheduler_app/views.py 2013-07-17 12:48:53 +0000 |
254 | +++ lava_scheduler_app/views.py 2013-08-14 13:44:42 +0000 |
255 | @@ -681,6 +681,25 @@ |
256 | return response |
257 | |
258 | |
259 | +def multinode_job_definition(request, pk): |
260 | + job = get_restricted_job(request.user, pk) |
261 | + log_file = job.output_file() |
262 | + return render_to_response( |
263 | + "lava_scheduler_app/multinode_job_definition.html", |
264 | + { |
265 | + 'job': job, |
266 | + 'job_file_present': bool(log_file), |
267 | + }, |
268 | + RequestContext(request)) |
269 | + |
270 | + |
271 | +def multinode_job_definition_plain(request, pk): |
272 | + job = get_restricted_job(request.user, pk) |
273 | + response = HttpResponse(job.multinode_definition, mimetype='text/plain') |
274 | + response['Content-Disposition'] = "attachment; filename=multinode_job_%d.json" % job.id |
275 | + return response |
276 | + |
277 | + |
278 | @BreadCrumb("Complete log", parent=job_detail, needs=['pk']) |
279 | def job_log_file(request, pk): |
280 | job = get_restricted_job(request.user, pk) |
Approved, thanks.