772a05e5f05794c206c4cb5db32545acab3239eb
[arvados.git] / doc / user / topics / tutorial-job-debug.html.textile.liquid
1 ---
2 layout: default
3 navsection: userguide
4 title: "Debugging a Crunch script"
5 ...
6
7 To test changes to a script by running a job, the change must be pushed to your hosted repository, and the job might have to wait in the queue before it runs. This cycle can be an inefficient way to develop and debug scripts. This tutorial demonstrates an alternative: using @arv-crunch-job@ to run your job in your local VM.  This avoids the job queue and allows you to execute the script directly from your git working tree without committing or pushing.
8
9 {% include 'tutorial_expectations' %}
10
11 This tutorial uses *@you@* to denote your username.  Replace *@you@* with your user name in all the following examples.
12
13 h2. Create a new script
14
15 Change to your Git working directory and create a new script in @crunch_scripts/@.
16
17 <notextile>
18 <pre><code>~$ <span class="userinput">cd <b>you</b>/crunch_scripts</span>
19 ~/<b>you</b>/crunch_scripts$ <span class="userinput">cat &gt;hello-world.py &lt;&lt;EOF
20 #!/usr/bin/env python
21
22 print "hello world"
23 print "this script will fail, and that is expected!"
24 EOF</span>
25 ~/<b>you</b>/crunch_scripts$ <span class="userinput">chmod +x hello-world.py</span>
26 </code></pre>
27 </notextile>
28
29 h2. Using arv-crunch-job to run the job in your VM
30
31 Instead of a Git commit hash, we provide the path to the directory in the "script_version" parameter.  The script specified in "script" is expected to be in the @crunch_scripts/@ subdirectory of the directory specified "script_version".  Although we are running the script locally, the script still requires access to the Arvados API server and Keep storage service. The job will be recorded in the Arvados job history, and visible in Workbench.
32
33 <notextile>
34 <pre><code>~/<b>you</b>/crunch_scripts$ <span class="userinput">cat &gt;~/the_job &lt;&lt;EOF
35 {
36  "repository":"",
37  "script":"hello-world.py",
38  "script_version":"$HOME/$USER",
39  "script_parameters":{}
40 }
41 EOF</span>
42 </code></pre>
43 </notextile>
44
45 Your shell should fill in values for @$HOME@ and @$USER@ so that the saved JSON points "script_version" at the directory with your checkout.  Now you can run that job:
46
47 <notextile>
48 <pre><code>~/<b>you</b>/crunch_scripts</span>$ <span class="userinput">arv-crunch-job --job "$(cat ~/the_job)"</span>
49 2013-12-12_21:36:42 qr1hi-8i9sb-okzukfzkpbrnhst 29827  check slurm allocation
50 2013-12-12_21:36:42 qr1hi-8i9sb-okzukfzkpbrnhst 29827  node localhost - 1 slots
51 2013-12-12_21:36:42 qr1hi-8i9sb-okzukfzkpbrnhst 29827  start
52 2013-12-12_21:36:42 qr1hi-8i9sb-okzukfzkpbrnhst 29827  script hello-world.py
53 2013-12-12_21:36:42 qr1hi-8i9sb-okzukfzkpbrnhst 29827  script_version /home/<b>you</b>/<b>you</b>
54 2013-12-12_21:36:42 qr1hi-8i9sb-okzukfzkpbrnhst 29827  script_parameters {}
55 2013-12-12_21:36:42 qr1hi-8i9sb-okzukfzkpbrnhst 29827  runtime_constraints {"max_tasks_per_node":0}
56 2013-12-12_21:36:42 qr1hi-8i9sb-okzukfzkpbrnhst 29827  start level 0
57 2013-12-12_21:36:42 qr1hi-8i9sb-okzukfzkpbrnhst 29827  status: 0 done, 0 running, 1 todo
58 2013-12-12_21:36:42 qr1hi-8i9sb-okzukfzkpbrnhst 29827 0 job_task qr1hi-ot0gb-4zdajby8cjmlguh
59 2013-12-12_21:36:42 qr1hi-8i9sb-okzukfzkpbrnhst 29827 0 child 29834 started on localhost.1
60 2013-12-12_21:36:42 qr1hi-8i9sb-okzukfzkpbrnhst 29827  status: 0 done, 1 running, 0 todo
61 2013-12-12_21:36:42 qr1hi-8i9sb-okzukfzkpbrnhst 29827 0 stderr hello world
62 2013-12-12_21:36:42 qr1hi-8i9sb-okzukfzkpbrnhst 29827 0 stderr this script will fail, and that is expected!
63 2013-12-12_21:36:43 qr1hi-8i9sb-okzukfzkpbrnhst 29827 0 child 29834 on localhost.1 exit 0 signal 0 success=
64 2013-12-12_21:36:43 qr1hi-8i9sb-okzukfzkpbrnhst 29827 0 failure (#1, permanent) after 0 seconds
65 2013-12-12_21:36:43 qr1hi-8i9sb-okzukfzkpbrnhst 29827 0 output
66 2013-12-12_21:36:43 qr1hi-8i9sb-okzukfzkpbrnhst 29827  Every node has failed -- giving up on this round
67 2013-12-12_21:36:43 qr1hi-8i9sb-okzukfzkpbrnhst 29827  wait for last 0 children to finish
68 2013-12-12_21:36:43 qr1hi-8i9sb-okzukfzkpbrnhst 29827  status: 0 done, 0 running, 0 todo
69 2013-12-12_21:36:43 qr1hi-8i9sb-okzukfzkpbrnhst 29827  Freeze not implemented
70 2013-12-12_21:36:43 qr1hi-8i9sb-okzukfzkpbrnhst 29827  collate
71 2013-12-12_21:36:43 qr1hi-8i9sb-okzukfzkpbrnhst 29827  output d41d8cd98f00b204e9800998ecf8427e+0
72 2013-12-12_21:36:44 qr1hi-8i9sb-okzukfzkpbrnhst 29827  meta key is c00bfbd58e6f58ce3bebdd47f745a70f+1857
73 </code></pre>
74 </notextile>
75
76 These are the lines of interest:
77
78 bc. 2013-12-12_21:36:42 qr1hi-8i9sb-okzukfzkpbrnhst 29827 0 stderr hello world
79 2013-12-12_21:36:42 qr1hi-8i9sb-okzukfzkpbrnhst 29827 0 stderr this script will fail, and that is expected!
80
81 The script's output is captured in the log, which is useful for print statement debugging. However, although this script returned a status code of 0 (success), the job failed.  Why?  For a job to complete successfully scripts must explicitly add their output to Keep, and then tell Arvados about it.  Here is a second try:
82
83 <notextile>
84 <pre><code>~/<b>you</b>/crunch_scripts$ <span class="userinput">cat &gt;hello-world-fixed.py &lt;&lt;EOF
85 #!/usr/bin/env python
86
87 import arvados
88
89 # Create a new collection
90 out = arvados.CollectionWriter()
91
92 # Set the name of the file in the collection to write to
93 out.set_current_file_name('hello.txt')
94
95 # Actually output our text
96 out.write('hello world')
97
98 # Commit the collection to Keep
99 out_collection = out.finish()
100
101 # Tell Arvados which Keep object is our output
102 arvados.current_task().set_output(out_collection)
103
104 # Done!
105 EOF</span>
106 ~/<b>you</b>/crunch_scripts$ <span class="userinput">chmod +x hello-world-fixed.py</span>
107 ~/<b>you</b>/crunch_scripts$ <span class="userinput">cat &gt;~/the_job &lt;&lt;EOF
108 {
109  "repository":"",
110  "script":"hello-world-fixed.py",
111  "script_version":"$HOME/$USER",
112  "script_parameters":{}
113 }
114 EOF</span>
115 ~/<b>you</b>/crunch_scripts$ <span class="userinput">arv-crunch-job --job "$(cat ~/the_job)"</span>
116 2013-12-12_21:56:59 qr1hi-8i9sb-79260ykfew5trzl 31578  check slurm allocation
117 2013-12-12_21:56:59 qr1hi-8i9sb-79260ykfew5trzl 31578  node localhost - 1 slots
118 2013-12-12_21:57:00 qr1hi-8i9sb-79260ykfew5trzl 31578  start
119 2013-12-12_21:57:00 qr1hi-8i9sb-79260ykfew5trzl 31578  script hello-world-fixed.py
120 2013-12-12_21:57:00 qr1hi-8i9sb-79260ykfew5trzl 31578  script_version /home/<b>you</b>/<b>you</b>
121 2013-12-12_21:57:00 qr1hi-8i9sb-79260ykfew5trzl 31578  script_parameters {}
122 2013-12-12_21:57:00 qr1hi-8i9sb-79260ykfew5trzl 31578  runtime_constraints {"max_tasks_per_node":0}
123 2013-12-12_21:57:00 qr1hi-8i9sb-79260ykfew5trzl 31578  start level 0
124 2013-12-12_21:57:00 qr1hi-8i9sb-79260ykfew5trzl 31578  status: 0 done, 0 running, 1 todo
125 2013-12-12_21:57:00 qr1hi-8i9sb-79260ykfew5trzl 31578 0 job_task qr1hi-ot0gb-u8g594ct0wt7f3f
126 2013-12-12_21:57:00 qr1hi-8i9sb-79260ykfew5trzl 31578 0 child 31585 started on localhost.1
127 2013-12-12_21:57:00 qr1hi-8i9sb-79260ykfew5trzl 31578  status: 0 done, 1 running, 0 todo
128 2013-12-12_21:57:02 qr1hi-8i9sb-79260ykfew5trzl 31578 0 child 31585 on localhost.1 exit 0 signal 0 success=true
129 2013-12-12_21:57:02 qr1hi-8i9sb-79260ykfew5trzl 31578 0 success in 1 seconds
130 2013-12-12_21:57:02 qr1hi-8i9sb-79260ykfew5trzl 31578 0 output 576c44d762ba241b0a674aa43152b52a+53
131 2013-12-12_21:57:02 qr1hi-8i9sb-79260ykfew5trzl 31578  wait for last 0 children to finish
132 2013-12-12_21:57:02 qr1hi-8i9sb-79260ykfew5trzl 31578  status: 1 done, 0 running, 0 todo
133 2013-12-12_21:57:02 qr1hi-8i9sb-79260ykfew5trzl 31578  Freeze not implemented
134 2013-12-12_21:57:02 qr1hi-8i9sb-79260ykfew5trzl 31578  collate
135 2013-12-12_21:57:02 qr1hi-8i9sb-79260ykfew5trzl 31578  output 576c44d762ba241b0a674aa43152b52a+53
136 WARNING:root:API lookup failed for collection 576c44d762ba241b0a674aa43152b52a+53 (<class 'apiclient.errors.HttpError'>: <HttpError 404 when requesting https://qr1hi.arvadosapi.com/arvados/v1/collections/576c44d762ba241b0a674aa43152b52a%2B53?alt=json returned "Not Found">)
137 2013-12-12_21:57:03 qr1hi-8i9sb-79260ykfew5trzl 31578  finish
138 </code></pre>
139 </notextile>
140
141 (The WARNING issued near the end of the script may be safely ignored here; it is the Arvados SDK letting you know that it could not find a collection named @576c44d762ba241b0a674aa43152b52a+53@ and that it is going to try looking up a block by that name instead.)
142
143 The job succeeded, with output in Keep object @576c44d762ba241b0a674aa43152b52a+53@.  Let's look at our output:
144
145 <notextile>
146 <pre><code>~/<b>you</b>/crunch_scripts$ <span class="userinput">arv keep get 576c44d762ba241b0a674aa43152b52a+53/hello.txt</span>
147 hello world
148 </code></pre>
149 </notextile>
150
151 h3. Location of temporary files
152
153 Crunch job tasks are supplied with @TASK_WORK@ and @JOB_WORK@ environment variables, to be used as scratch space.  When running in local development mode using @arv-crunch-job@, Crunch sets these variables to point to directory called @crunch-job-{USERID}@ in @TMPDIR@ (or @/tmp@ if @TMPDIR@ is not set).
154
155 * Set @TMPDIR@ to @/scratch@ to make Crunch use a directory like @/scratch/crunch-job-{USERID}/@ for temporary space.
156
157 * Set @CRUNCH_TMP@ to @/scratch/foo@ to make Crunch use @/scratch/foo/@ for temporary space (omitting the default @crunch-job-{USERID}@ leaf name)
158
159 h3. Testing job scripts without SDKs and Keep access
160
161 Read and write data to @/tmp/@ instead of Keep. This only works with the Python SDK.
162
163 notextile. <pre><code>~$ <span class="userinput">export KEEP_LOCAL_STORE=/tmp</span></code></pre>
164