How to fake cpu architecture in docker container?
Asked Answered
C

3

10

When I create 32 bit CentOS 5 docker image I would like cpu architecture to be reported as i386/i686 there (installer which tested in this container check architecture and installs 64 bit binaries instead of 32 bit). I set yum variables and created uname wrapper, so yum and checks in bash scripts are working:

bash-3.2# uname -a
Linux c538cf9bf508 3.13.0-24-generic #47-Ubuntu SMP Fri May 2 23:30:00 UTC 2014 i686 i686 i386 GNU/Linux
bash-3.2# uname -p -m -i
i686 i686 i386
bash-3.2# cat /etc/yum/vars/arch && cat /etc/yum/vars/basearch
i686
i386

But python still reports 64 bit

bash-3.2# python
Python 2.4.3 (#1, Jan  9 2013, 06:49:54) 
[GCC 4.1.2 20080704 (Red Hat 4.1.2-54)] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import os, platform
>>> platform.machine()
'x86_64'
>>> os.uname()
('Linux', 'c538cf9bf508', '3.13.0-24-generic', '#47-Ubuntu SMP Fri May 2 23:30:00 UTC 2014', 'x86_64')

Is there a way to fake cpu architecture everywhere?

Charisecharisma answered 21/10, 2014 at 15:52 Comment(0)
R
6

I hope there's a more elegant way to do this, but here's what I do: preface any command you want to run with linux32. For example:

$ docker run -t -i toopher/centos-i386:centos6 /bin/bash
[root@b027ad7830ac /]# uname -a
Linux b027ad7830ac 3.16.4-tinycore64 #1 SMP Thu Oct 23 16:14:24 UTC 2014 x86_64 x86_64 x86_64 GNU/Linux
[root@b027ad7830ac /]# linux32 uname -a
Linux b027ad7830ac 3.16.4-tinycore64 #1 SMP Thu Oct 23 16:14:24 UTC 2014 i686 i686 i386 GNU/Linux
[root@b027ad7830ac /]# linux32 python
Python 2.6.6 (r266:84292, Jan 22 2014, 09:37:14) 
[GCC 4.4.7 20120313 (Red Hat 4.4.7-4)] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import os, platform
>>> platform.machine()
'i686'
>>> os.uname()
('Linux', 'b027ad7830ac', '3.16.4-tinycore64', '#1 SMP Thu Oct 23 16:14:24 UTC 2014', 'i686')

Alternatively you can use linux32 in the invocation of docker run:

$ docker run -t -i toopher/centos-i386:centos6 /usr/bin/linux32 /bin/bash
[root@0f289d955fe1 /]# uname -a
Linux 0f289d955fe1 3.16.4-tinycore64 #1 SMP Thu Oct 23 16:14:24 UTC 2014 i686 i686 i386 GNU/Linux
[root@0f289d955fe1 /]# python
Python 2.6.6 (r266:84292, Jan 22 2014, 09:37:14) 
[GCC 4.4.7 20120313 (Red Hat 4.4.7-4)] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import os, platform
>>> platform.machine()
'i686'
>>> os.uname()
('Linux', '0f289d955fe1', '3.16.4-tinycore64', '#1 SMP Thu Oct 23 16:14:24 UTC 2014', 'i686')

Or even better, use a docker image (or build your own) that configures linux32 as it's ENTRYPOINT, such as:

FROM toopher/centos-i386:centos6
ENTRYPOINT ["linux32"]
Roberts answered 4/11, 2014 at 6:30 Comment(3)
I was trying to use it before, but found only 64bit package, now I found it in package setarch and it is working fine, thanks. I'm setting it as entrypoint and it should resolve my problem.Charisecharisma
Great point - I've updated the answer to include the ENTRYPOINT suggestion.Roberts
Just a note: I have pull-requested to toopher/centos-i386:centos6, so it now works fine out of the box: github.com/toopher/toopher-docker/pull/1Hupp
P
3

Evan's answer does work but you still need to prefix almost every RUN line in your Dockerfile with linux32. To avoid this I added the following near the top of my Dockerfile:

RUN rm /bin/sh && \
  echo -e '#!/bin/bash\n/usr/bin/linux32 -- /bin/bash "$@"' > /bin/sh && \
  chmod +x /bin/sh

/bin/sh is normally a symbolic link to /bin/bash. This replaces the symbolic link with the following script:

#!/bin/bash
/usr/bin/linux32 -- /bin/bash "$@"

Which makes every invocation of RUN in your Dockerfile run under linux32. Unless you use the RUN ["command"...] format which bypasses calling /bin/sh. In which case, you will have to add the linux32 prefix manually.

Parcae answered 20/10, 2015 at 23:5 Comment(1)
I believe the cleaner way to accomplish this would be to set the SHELL directive near the top of the your Dockerfile, eg: SHELL ["/usr/bin/linux32", "/bin/sh", "-c"]Aseptic
H
1

For CentOS, you only need to modify the following files:

+RUN echo "i686" > /etc/yum/vars/arch && \
+    echo "i386" > /etc/yum/vars/basearch

(just like I did in the pull-request to toopher/centos-i386:centos6)

$ docker run -it --rm toopher/centos-i386:centos6 sh
sh-4.1# python
Python 2.6.6 (r266:84292, Jan 22 2014, 09:37:14)
[GCC 4.4.7 20120313 (Red Hat 4.4.7-4)] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import os
>>> os.uname()
('Linux', 'dc8d1dc46702', '3.16.0-4-amd64', '#1 SMP Debian 3.16.7-ckt11-1+deb8u6 (2015-11-09)', 'i686')
Hupp answered 1/12, 2015 at 6:14 Comment(1)
This is awesome! Thanks.Hearten

© 2022 - 2024 — McMap. All rights reserved.