Local CentOS mirror

Following on from last weeks post, this post is quickly going to go through setting up a local CentOS YUM repository. Although just pulling packages from a public mirror is easier, it can sometimes be useful to have a local mirror if you're working offline or with a limited connection.

Extracting packages or mounting

The CentOS 7.2 everything iso contains just under 7GB of packages. The two directories you need are Packages and repodata. If you are on a Linux based system you should be able to mount the ISO with a command similar to the following:

mount -o ro,loop CentOS-7-x86_64-Everything-1511.iso /mnt/

Alternatively you can use an archive manager like 7-zip to extract the directories.

Truncated filenames

The CentOS ISO uses a Joliet file system. Part of the spec includes the following:

The File or Directory Identifiers may be up to 128 bytes (64 unicode characters) in length.

The ISO does include TRANS.TBL files with the full filenames, however 7-zip currently doesn't use them to translate the filenames (bug #1055 and bug #1412).

You can quickly check if this is an issue by having a look in the repodata directory:

$ ls
0e54cd65abd3621a0baf9a963eafb1a0ffd53603226f02aadce59635329bc937
308b19b243c882f0278206ea4ffc4e120df78c0218867917916fd437e4d0ea49
3eda3fefdbaf4777fcab430c80bc438293c512f22fd706b12c6567d535b2142a
436345f4b666f0a461d479ccfabc2c22823d4f2173c2653e5250fea62f0afe98
653b04e156ef4b2e3d35a01b04a148c046827373ccd79ec02091feef89170f77
bc7ac852ce641a34511f0743bdb0c7a8504cb14b8654498508d60f5ca3593ca5
c6411f1cc8a000ed2b651b49134631d279abba1ec1f78e5dcca79a52d8c1eada
cb645bc44fea73070c995fd830d96d624a24c6356d0932ad39c077ad01c54103
repomd.xml
TRANS.TBL

To fix this the truncated files need to be renamed to match the filenames listed in TRANS.TBL. I've written a quick python script to do this. Running the script should rename any truncated files:

$ python fix_truncated_files.py repodata/ Packages/
Missing file: 0e54cd65abd3621a0baf9a963eafb1a0ffd53603226f02aadce59635329bc937-primary.xml.gz
Renaming: repodata/0e54cd65abd3621a0baf9a963eafb1a0ffd53603226f02aadce59635329bc937 -> repodata/0e54cd65abd3621a0baf9a963eafb1a0ffd53603226f02aadce59635329bc937-primary.xml.gz
Missing file: 308b19b243c882f0278206ea4ffc4e120df78c0218867917916fd437e4d0ea49-filelists.sqlite.bz2
Renaming: repodata/308b19b243c882f0278206ea4ffc4e120df78c0218867917916fd437e4d0ea49 -> repodata/308b19b243c882f0278206ea4ffc4e120df78c0218867917916fd437e4d0ea49-filelists.sqlite.bz2
...

Serving repo files

YUM repositories can be accessed over several protocols; for this post I'm going to use http. Switch to the directory containing repodata and Packages then run python -m http.server. This will spin up a web server:

$ python -m http.server
Serving HTTP on 0.0.0.0 port 8000 ...

Note: if you are using python 2.x run python -m SimpleHTTPServer instead.

Client configuration

The last thing to do is configure a CentOS client to use the local mirror. Create a config file called /etc/yum.repos.d/CentOS-Base-Local.repo with the following contents:

[base-local]
name=CentOS-$releasever - Base (Local)
baseurl=http://192.168.56.1:8000/
gpgcheck=1
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-CentOS-7

Running yum repolist base-local should give you output similar to the following:

repo id              repo name                         status

base-local           CentOS-7 - Base (Local)           9,007

Once you're happy your local mirror is working you can disable the standard base repository by running yum-config-manager --disable base. Alternatively you can add enabled=0 to /etc/yum.repos.d/CentOS-Base.repo in the [base] section.