lxc / go-lxc

Go bindings for liblxc
https://linuxcontainers.org/lxc
Other
430 stars 76 forks source link

Version checking checks compile time version rather than runtime #135

Open notnoop opened 5 years ago

notnoop commented 5 years ago

Many of version checking related functions (e.g. lxc.VersionNumber, lxc.VersionAtLeast, VERSION_AT_LEAST ` refer to the lxc versions present at compile time in build host rather than the runtime lxc version linked at process start time.

The issue is that they reference preprocessor definition integer constants (e.g. LXC_VERSION_MAJOR, and compiler inlines them with compile time dependency value.

Looks like it was this was addressed partially in https://github.com/lxc/go-lxc/pull/112 .

Reproduction

Run the following scripts below. The script generates a binary that reports lxc versions and is compiled against 2.0. When running it against 3.0.1, I get the following output (the bottom of the script output):

+ echo ======= RUNNING WITH LXC 3.0
+ echo
+ dpkg -l
+ grep lxc
ii  liblxc-common           3.0.4-0ubuntu1              amd64        Linux Containers userspace tools (common tools)
ii  liblxc1                 3.0.4-0ubuntu1              amd64        Linux Containers userspace tools (library)
ii  lxcfs                   3.0.4-2                     amd64        FUSE based filesystem for LXC
+ /tmp/lxc-temp/lxc-version
STRING VERSION:  3.0.4
NUMBER VERSION  2 0
AT LEAST 2.1.0:  false

Script:

#!/bin/bash

set -ex

mkdir -p /tmp/lxc-temp/

# a basic golang app that reports version through different functions
cat <<'EOF' > /tmp/lxc-temp/main.go
package main

import (
"fmt"

lxc "gopkg.in/lxc/go-lxc.v2"
)

func main() {
verStr := lxc.Version()
fmt.Println("STRING VERSION: ", verStr)

major, minor := lxc.VersionNumber()
fmt.Println("NUMBER VERSION ", major, minor)

fmt.Println("AT LEAST 2.1.0: ", lxc.VersionAtLeast(2, 1, 0))
}
EOF

# compile golang binary with LXC 2.0
# uses old ubuntu to lxc 2.0 and old golang 1.10 but results are the same with latest golang 1.13
cat <<'EOF' | docker run -i --rm -v /tmp/lxc-temp:/tmp/lxc-temp ubuntu:16.04 /bin/bash
set -ex
echo this may take a long time
apt-get update >/dev/null

apt-get install -y golang-1.10 build-essential curl git lxc-dev/xenial-updates >/dev/null
ln -s /usr/lib/go-1.10/bin/go /usr/bin/go

mkdir /go
export GOPATH=/go
go get -u -v gopkg.in/lxc/go-lxc.v2
go build -o /tmp/lxc-temp/lxc-version /tmp/lxc-temp/main.go

echo ======= RUNNING WITH LXC 2.0
echo
dpkg -l |grep lxc
/tmp/lxc-temp/lxc-version
EOF

# now run it in latest ubuntu with latest lxc
cat <<'EOF' | docker run -i --rm -v /tmp/lxc-temp:/tmp/lxc-temp ubuntu:19.10 /bin/bash
set -ex
apt-get update >/dev/null
apt-get install -y liblxc1 >/dev/null

echo ======= RUNNING WITH LXC 3.0
echo
dpkg -l |grep lxc
/tmp/lxc-temp/lxc-version
EOF