|
1 | 1 | Debugging Generic IOC Builds
|
2 | 2 | ============================
|
3 | 3 |
|
4 |
| -.. Warning:: |
5 |
| - |
6 |
| - This tutorial is out of date and will be updated soon. |
7 |
| - |
8 | 4 | This tutorial is a continuation of `generic_ioc`. Here we will look into
|
9 |
| -debugging failed builds and fix the issue we saw in the previous tutorial. |
| 5 | +debugging failed builds of Generic IOCs. |
10 | 6 |
|
11 |
| -This also comes under the category of type 2. change from the list |
12 |
| -at `ioc_change_types`. |
| 7 | +For the most part the recommended workflow is to always be working inside |
| 8 | +of a developer container. We always use a Generic IOC as the base for our |
| 9 | +developer containers. But what if the build of the Generic IOC fails, then |
| 10 | +you don't have a container to work in and need some other way to debug the |
| 11 | +build. |
13 | 12 |
|
14 |
| -There are two ways to debug a failed build: |
| 13 | +There are two ways to debug such a failed build: |
15 | 14 |
|
16 | 15 | - Keep changing the Dockerfile and rebuilding the container until the build
|
17 | 16 | succeeds. This is the simplest approach and is often sufficient since our
|
18 | 17 | Dockerfile design maximizes the use of the build cache.
|
19 | 18 |
|
20 | 19 | - Investigate the build failure by running a shell inside the
|
21 |
| - partially-built container and |
22 |
| - using make. This is a good idea if you have to make fundamental changes |
23 |
| - such as installing a new system package. System package install happens |
24 |
| - at the start of the Dockerfile and would trigger a full rebuild when |
25 |
| - changed. |
| 20 | + partially-built container and retrying the failed command. This is particularly |
| 21 | + useful if you are fixing something early in the Dockerfile that causes a |
| 22 | + failure much later in the build. This type of failure is tedious to debug |
| 23 | + using the first approach above. |
26 | 24 |
|
27 |
| -You already have the knowledge to apply the first approach. In this tutorial |
28 |
| -we will look debugging the build from *inside* the container. |
| 25 | +In this tutorial we will look debugging the build from *inside* the container. |
29 | 26 |
|
30 |
| -Investigate the Build Failure |
31 |
| ------------------------------ |
| 27 | +Break the Build |
| 28 | +--------------- |
32 | 29 |
|
33 |
| -When a container build fails the container image is created up to the point |
34 |
| -where the last successful Dockerfile command was run. This means that we can |
35 |
| -investigate the build failure by running a shell in the container. ``ec`` |
36 |
| -provides us with the following convenience command to do this: |
| 30 | +Let us break the build of our ioc-lakeshore340 project in the last |
| 31 | +tutorial. Open the the file |
| 32 | +``ioc-lakeshore340/ibek-support/StreamDevice/install.sh``. |
| 33 | +Comment out the apt-install line like this: |
37 | 34 |
|
38 | 35 | .. code-block:: bash
|
39 | 36 |
|
40 |
| - ec dev debug-last |
| 37 | + # ibek support apt-install --only=dev libpcre3-dev |
41 | 38 |
|
42 |
| -Now we have a prompt inside the part-built container and can retry the failed |
43 |
| -command. |
| 39 | +Now rebuild the container - do this command from a new terminal *outside* of |
| 40 | +the devcontainer (make sure you have ``ec`` installed): |
44 | 41 |
|
45 | 42 | .. code-block:: bash
|
46 | 43 |
|
47 |
| - cd /workspaces/epics/support/adurl |
48 |
| - make |
| 44 | + cd ioc-lakeshore340 # where you cloned it |
| 45 | + ec dev build |
49 | 46 |
|
50 |
| -You should see the same error again. |
| 47 | +First of all, notice the build cache. The build rapidly skips |
| 48 | +over all the steps until it gets to the StreamDevice support module. The, |
| 49 | +cache fails only when you get to ``COPY ibek-support/StreamDevice/ StreamDevice/`` |
| 50 | +because a file in the source folder has changed. |
51 | 51 |
|
52 |
| -A really good way to investigate this kind of error is with ``apt-file`` |
53 |
| -which is a command line tool for searching Debian packages. apt-file is |
54 |
| -already installed in our devcontainer. So get another terminal open |
55 |
| -with the ``[E7]`` prompt and run the following commands: |
| 52 | +You should see the build fail with the following error: |
56 | 53 |
|
57 | 54 | .. code-block:: bash
|
58 | 55 |
|
59 |
| - apt-file search Magick++.h |
| 56 | + ../RegexpConverter.cc:27:10: fatal error: pcre.h: No such file or directory |
| 57 | + 27 | #include "pcre.h" |
| 58 | + | ^~~~~~~~ |
| 59 | + compilation terminated. |
60 | 60 |
|
61 |
| - graphicsmagick-libmagick-dev-compat: /usr/include/Magick++.h |
62 |
| - libgraphicsmagick++1-dev: /usr/include/GraphicsMagick/Magick++.h |
63 |
| - libmagick++-6-headers: /usr/include/ImageMagick-6/Magick++.h |
| 61 | +Investigate the Build Failure |
| 62 | +----------------------------- |
64 | 63 |
|
65 |
| -The middle result looks most promising so we will install it (back *inside* |
66 |
| -the Generic IOC container now): |
| 64 | +When a container build fails the container image is created up to the point |
| 65 | +where the last successful Dockerfile command was run. This means that we can |
| 66 | +investigate the build failure by running a shell in the container. ``ec`` |
| 67 | +provides us with the following convenience command to do this: |
67 | 68 |
|
68 | 69 | .. code-block:: bash
|
69 | 70 |
|
70 |
| - apt-get install -y libgraphicsmagick++1-dev |
71 |
| -
|
72 |
| -The reason using apt-file outside of the Generic IOC works is because |
73 |
| -the Generic IOC and the devcontainer are built upon the same version of |
74 |
| -Ubuntu and have the same packages available. |
75 |
| - |
76 |
| -If we try the build again now it will still fail. We need to tell the |
77 |
| -AreaDetector build system where to find the new header file. This |
78 |
| -is documented here `CONFIG_SITE.local`_. The documentation says that we |
79 |
| -need to set the variable ``GRAPHICSMAGICK_INCLUDE`` in |
80 |
| -``CONFIG_SITE.linux-x86_64.Common``. |
81 |
| -We can see from the ``apt-file`` output that the header file is in |
82 |
| -``/usr/include/GraphicsMagick`` which is not a default include path. |
83 |
| -Therefore we need to edit this file inside our Generic IOC container: |
84 |
| -``/workspaces/epics/support/adurl/configure/CONFIG_SITE.linux-x86_64.Common`` |
85 |
| - |
86 |
| -.. _CONFIG_SITE.local: https://areadetector.github.io/areaDetector/install_guide.html#edit-config-site-local-and-optionally-config-site-local-epics-host-arch |
87 |
| - |
88 |
| - |
89 |
| -Making Changes Inside the Container |
90 |
| ------------------------------------ |
91 |
| - |
92 |
| -You will find that the container includes busybox tools and there is a |
93 |
| -rudimentary version of ``vi`` installed. You could also install any editor |
94 |
| -you like from the Ubuntu repositories. |
95 |
| - |
96 |
| -HOWEVER, there is a much easier way ... |
97 |
| - |
98 |
| -When you launch containers with ``ec`` commands the ``/workspaces`` folder is |
99 |
| -synchronized to a local folder ioc-XXX/workspaces and that is mounted into the |
100 |
| -container. This means that you can edit files in the container using VSCode. |
101 |
| -The mounted repos folder also ensures that any changes you make inside the |
102 |
| -container are saved between invocations of the container. |
103 |
| - |
104 |
| -See the image below to see how to navigate to |
105 |
| -``CONFIG_SITE.linux-x86_64.Common`` |
106 |
| -in the ``adurl`` support module inside the ioc-adurl container. |
107 |
| - |
108 |
| -.. figure:: ../images/repos_folder.png |
109 |
| - |
110 |
| - VSCode file explorer showing the mounted repos folder |
111 |
| - |
112 |
| -Using VSCode file explorer as pictured above, navigate to the file |
113 |
| -``CONFIG_SITE.linux-x86_64.Common`` and update the GRAPHICSMAGICK section to |
114 |
| -look like this: |
| 71 | + ec dev debug-last |
115 | 72 |
|
116 |
| -.. code-block:: makefile |
| 73 | +Now we have a prompt inside the part-built container and can retry the failed |
| 74 | +command. |
117 | 75 |
|
118 |
| - WITH_GRAPHICSMAGICK = YES |
119 |
| - GRAPHICSMAGICK_EXTERNAL = YES |
120 |
| - GRAPHICSMAGICK_INCLUDE = /usr/include/GraphicsMagick |
| 76 | +.. code-block:: bash |
121 | 77 |
|
122 |
| -Now go back to the terminal and run ``make`` again. This time it should |
123 |
| -succeed. |
| 78 | + cd /workspaces/ioc-lakeshore340/ibek-support |
| 79 | + StreamDevice/install.sh 2.8.24 |
124 | 80 |
|
125 |
| -Applying Changes Made Inside the Container |
126 |
| ------------------------------------------- |
| 81 | +You should see the same error again. |
127 | 82 |
|
128 |
| -When you use the 'inside the container' approach to get the build working |
129 |
| -you still need to apply the changes you made 'outside' so that invoking |
130 |
| -container build will also succeed. |
| 83 | +This is a pretty common type of error |
| 84 | +when building a new support module. It implies that there is some dependency |
| 85 | +missing. There is a good chance this is a system dependency, in which case |
| 86 | +we want to search the Ubuntu repositories for the missing package. |
131 | 87 |
|
132 |
| -:TIP: do NOT apply the below, the next heading supplies a better solution |
133 |
| - for this specific case. |
| 88 | +A really good way to investigate this kind of error is with ``apt-file`` |
| 89 | +which is a command line tool for searching Debian packages. ``apt-file`` is |
| 90 | +not currently installed in the devcontainer. So you have two choices: |
134 | 91 |
|
135 |
| -There are a few kinds of changes that need different approaches as follows: |
| 92 | +- Install it in the devcontainer - this is temporary and will be lost when |
| 93 | + the container is rebuilt. Ideal if you don't have install rights on your |
| 94 | + workstation. |
136 | 95 |
|
137 |
| -:apt install: |
| 96 | +- Install it on your workstation - ideal if you have rights as you only need |
| 97 | + to install it once. |
138 | 98 |
|
139 |
| - We did an apt install of ``libgraphicsmagick++1-dev``. Additional system |
140 |
| - package installs like this need to be added to the ``apt-get install`` |
141 |
| - command at the top of the Dockerfile. |
| 99 | +TODO: consider adding apt-file to the base container developer target. |
142 | 100 |
|
143 |
| -:CONFIG_SITE: |
| 101 | +Whether inside the container or in your workstation terminal, install |
| 102 | +``apt-file`` like this: |
144 | 103 |
|
145 |
| - We edited ``CONFIG_SITE.linux-x86_64.Common``. This file is not part of |
146 |
| - the ADURL support module but was supplied by us from ibek-defs. |
| 104 | +.. code-block:: bash |
147 | 105 |
|
148 |
| -:Patching: |
| 106 | + # drop the sudo from the start of the command if using podman |
| 107 | + sudo apt update |
| 108 | + sudo apt install apt-file |
149 | 109 |
|
150 |
| - This should be avoided, but occasionally it may be necessary to patch other |
151 |
| - files in the support modules. This is just a variation of the CONFIG_SITE |
152 |
| - case above. You can place whatever script code you like in the |
153 |
| - ``ioc-XXX/patch`` folder. |
| 110 | +Now we can search for the missing file: |
154 | 111 |
|
155 |
| -:Support Module: |
| 112 | +.. code-block:: bash |
156 | 113 |
|
157 |
| - Potentially we could have made changes to the ADUrl support module itself |
158 |
| - because we found a bug or wanted to add a feature. In this case we would |
159 |
| - push those changes back up to GitHub and get a release made so we |
160 |
| - could use the new version in our Dockerfile, This would in turn mean A |
161 |
| - change to the version number in the ``modules.py install ADURL`` |
162 |
| - command. NOTE: the developer container we are using already holds clones |
163 |
| - of all the support modules so we could make changes in place and push them |
164 |
| - back. |
| 114 | + apt-file search pcre.h |
165 | 115 |
|
166 |
| -An Easier Fix Using ADSupport |
167 |
| ------------------------------ |
| 116 | +There are a few results, but the most promising is: |
168 | 117 |
|
169 |
| -Although we managed to fix the build by installing Graphics Magick, into the |
170 |
| -container there is an easier solution that is specific to areaDetector. The |
171 |
| -ADSupport module is capable of building most of the system dependencies that |
172 |
| -areaDetector needs. This has proved to be very useful in making containers |
173 |
| -because the curation of all of the compatible versions of these dependencies |
174 |
| -has already been done. |
| 118 | + libpcre3-dev: /usr/include/pcre.h |
175 | 119 |
|
176 |
| -So the error we saw was due to us telling ADUrl to look for an 'internal' |
177 |
| -version of Graphics Magick built by ADSupport. However, we did not tell |
178 |
| -ADSupport to build Graphics Magick. |
| 120 | +Pretty much every time you are missing a header file you will find it in a |
| 121 | +system package with a name ending in ``-dev``. |
179 | 122 |
|
180 |
| -So the simple fix to this is to add the following line to the |
181 |
| -``ioc-adurl/ibek-defs/adsupport/adsupport.sh`` file: |
| 123 | +Now we can install the missing package in the container and retry the build: |
182 | 124 |
|
183 |
| -.. code-block:: makefile |
| 125 | +.. code-block:: bash |
184 | 126 |
|
185 |
| - WITH_GRAPHICSMAGICK = YES |
186 |
| - GRAPHICSMAGICK_EXTERNAL = NO |
| 127 | + apt-get install -y libpcre3-dev |
| 128 | + StreamDevice/install.sh 2.8.24 |
187 | 129 |
|
188 |
| -Then rebuild the container: |
| 130 | +You should find the build succeeds. But this is not the whole story. There |
| 131 | +is another line in ``install.h`` that I added to make this work: |
189 | 132 |
|
190 | 133 | .. code-block:: bash
|
191 | 134 |
|
192 |
| - ec dev build |
| 135 | + ibek support add-config-macro ${NAME} PCRE_LIB /usr/lib/x86_64-linux-gnu |
193 | 136 |
|
194 |
| -Note that the build skips quickly over the support modules until it gets |
195 |
| -to ADSupport. This is the build cache saving time. |
196 |
| -However this build will STILL FAIL, it turns out that building Graphics Magick |
197 |
| -does need one system library install. |
| 137 | +This added a macro to ``CONFIG_SITE.linux-x86_64.Common`` that tells the |
| 138 | +Makefiles to add an extra include path to the compiler command line. working |
| 139 | +out how to do this is a matter of taking a look in the Makefiles. But the |
| 140 | +nice thing is that you can experiment with things inside the container and |
| 141 | +get them working without having to keep rebuilding the container. |
198 | 142 |
|
199 |
| -The final fix is to add ``libxext-dev`` to the ``apt-get install`` command in |
200 |
| -our Dockerfile. So that it looks like this: |
| 143 | +Note that ``ibek support add-config-macro`` is idempotent, so you can run it |
| 144 | +multiple times without getting repeated entries in the CONFIG. All ``ibek`` |
| 145 | +commands behave this way as far as possible. |
201 | 146 |
|
202 |
| -.. code-block:: bash |
| 147 | +Once you are happy with your manual changes you can make them permanent by |
| 148 | +adding to the install.sh or Dockerfile, then try a full rebuild. |
203 | 149 |
|
204 |
| - RUN apt-get update && apt-get upgrade -y && \ |
205 |
| - apt-get install -y --no-install-recommends \ |
206 |
| - libboost-all-dev \ |
207 |
| - libxext-dev |
208 |
| -
|
209 |
| -This is an example of a change that also requires a system package |
210 |
| -install for the runtime version of the container. Locate the second |
211 |
| -``apt-get install`` command in the Dockerfile and add ``libxext6`` so |
212 |
| -that it looks like this: |
213 |
| - |
214 |
| -.. code-block:: bash |
| 150 | +Making Changes Inside the Container |
| 151 | +----------------------------------- |
215 | 152 |
|
216 |
| - RUN apt-get update && apt-get upgrade -y && \ |
217 |
| - apt-get install -y --no-install-recommends \ |
218 |
| - libxext6 \ |
219 |
| - && rm -rf /var/lib/apt/lists/* |
| 153 | +You will find that the container includes busybox tools, vim and ifconfig. |
| 154 | +These should provide enough tools to investigate and fix most build problems. |
| 155 | +You are also |
| 156 | +free to use apt-get to install any other tools you need as demonstrated above. |
| 157 | +(type busybox to see the list of available tools). |
220 | 158 |
|
221 |
| -You can remove the RTEMS specific runtime packages that came with ioc-template. |
222 |
| -Note that the ``rm -rf /var/lib/apt/lists/`` removes the apt cache and keeps |
223 |
| -the runtime image size down. |
224 | 159 |
|
225 |
| -This build should now succeed. Unfortunately it has to rebuild the entire |
226 |
| -container from scratch because we changed the first command in the Dockerfile. |
| 160 | +Other ``ec dev`` Commands |
| 161 | +------------------------- |
227 | 162 |
|
228 |
| -Wrapping Up |
229 |
| ------------ |
| 163 | +The ``ec dev`` namespace provides a number of other commands for working outside |
| 164 | +of developer containers. These were primarily developed before the use |
| 165 | +of developer containers matured. If you prefer not to use developer containers |
| 166 | +for any reason then take a look at the help as follows: |
230 | 167 |
|
231 |
| -You now have a new Generic IOC that can be used to test the ADUrl plugin. |
| 168 | +.. code-block:: bash |
232 | 169 |
|
233 |
| -The next tutorial will discuss how to test this IOC, including publishing |
234 |
| -the image to a container registry so that it can run in Kubernetes. |
| 170 | + ec dev --help |
235 | 171 |
|
| 172 | +You should be able to perform most of the same tasks that the tutorials teach. |
236 | 173 |
|
237 |
| -.. Once running:- |
238 |
| -.. caput -S $USER-EA-TST-02:CAM:URL1 |
| 174 | +Don't forget that you can always use ``ec -v dev ...`` to get output showing |
| 175 | +the underlying docker/podman and git commands ``ec`` is using. |
0 commit comments