Suppose we want to install Ansible offline.
Creating a Virtualenv ¶
We will create a virtual environment to download all dependencies without accidentally including unnecessary ones. First, let’s install virtualenv
.
1
2
| python3 -m pip install --upgrade --user virtualenv
python3 -m virtualenv venv
|
Now we can activate it.
Now, for the duration of the terminal session, we are in an isolated Python virtual environment.
Preparing Required Packages ¶
By installing only what is needed in a clean environment, we will also pull in all dependencies. Additionally, make sure to include setuptools
and pip
.
1
| python3 -m pip install --upgrade pip setuptools ansible
|
Now we can create a list of what we have.
1
| python3 -m pip freeze > requirements.txt
|
You can simply add pip
and setuptools
to requirements.txt
without specifying versions (if they aren’t already in the list).
Example requirements.txt
1
2
3
4
5
6
7
8
9
10
11
12
| ansible==3.4.0
ansible-base==2.10.11
cryptography==2.8
jinja2==2.11.3
netaddr==0.7.19
pbr==5.4.4
jmespath==0.9.5
ruamel.yaml==0.16.10
ruamel.yaml.clib==0.2.2
MarkupSafe==1.1.1
pip
setuptools
|
Having the list of packages with dependencies, we can download them even without venv
.
1
| python3 -m pip download --dest my-pip-packages -r requirements.txt
|
For convenience, let’s pack everything into an archive.
1
| tar -cpvzf pips.tgz my-pip-packages requirements.txt
|
Installing in an Offline Environment ¶
Python should already be installed in advance.
Unpack your archive and install everything you brought. Pip and setuptools should be installed separately at the beginning, followed by everything else. If the command is not run as a superuser, you need to either:
- Add
sudo
at the beginning - Add the
--user
argument to pip to install packages only for the user running the command
1
2
3
| tar -xpzvf pips.tgz
python3 -m pip install --upgrade --no-index --find-links python-packages pip setuptools
python3 -m pip install --upgrade --no-index --find-links my-pip-packages -r requirements.txt
|
Now you can run Ansible!
1
2
3
4
5
6
7
| root@289f34a67cbd:/host# ansible --version
ansible 2.10.11
config file = None
configured module search path = ['/root/.ansible/plugins/modules', '/usr/share/ansible/plugins/modules']
ansible python module location = /usr/local/lib/python3.6/dist-packages/ansible
executable location = /usr/local/bin/ansible
python version = 3.6.9 (default, Jan 26 2021, 15:33:00) [GCC 8.4.0]
|
Locales ¶
There have been cases where in a severely stripped-down environment, like Docker Ubuntu 18.04, the package installation fails with the following error.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
| ERROR: Exception:
Traceback (most recent call last):
File "/usr/local/lib/python3.6/dist-packages/pip/_internal/cli/base_command.py", line 173, in _main
status = self.run(options, args)
File "/usr/local/lib/python3.6/dist-packages/pip/_internal/cli/req_command.py", line 203, in wrapper
return func(self, options, args)
File "/usr/local/lib/python3.6/dist-packages/pip/_internal/commands/install.py", line 316, in run
reqs, check_supported_wheels=not options.target_dir
...
File "/usr/local/lib/python3.6/dist-packages/pip/_internal/operations/prepare.py", line 249, in unpack_url
unpack_file(file.path, location, file.content_type)
File "/usr/local/lib/python3.6/dist-packages/pip/_internal/utils/unpacking.py", line 256, in unpack_file
untar_file(filename, location)
File "/usr/local/lib/python3.6/dist-packages/pip/_internal/utils/unpacking.py", line 226, in untar_file
with open(path, "wb") as destfp:
UnicodeEncodeError: 'ascii' codec can't encode character '\xe9' in position 117: ordinal not in range(128)
|
This can be resolved by setting environment variables before installing packages.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
| export LANGUAGE=""
export LANG="C.UTF-8"
export LC_CTYPE="C.UTF-8"
export LC_NUMERIC="C.UTF-8"
export LC_TIME="C.UTF-8"
export LC_COLLATE="C.UTF-8"
export LC_MONETARY="C.UTF-8"
export LC_MESSAGES="C.UTF-8"
export LC_PAPER="C.UTF-8"
export LC_NAME="C.UTF-8"
export LC_ADDRESS="C.UTF-8"
export LC_TELEPHONE="C.UTF-8"
export LC_MEASUREMENT="C.UTF-8"
export LC_IDENTIFICATION="C.UTF-8"
export LC_ALL="C.UTF-8"
|