pakfire_PYTHON = \
src/pakfire/__init__.py \
src/pakfire/__version__.py \
- src/pakfire/arch.py \
src/pakfire/base.py \
src/pakfire/builder.py \
src/pakfire/cgroup.py \
libpakfire.la
libpakfire_la_SOURCES = \
+ src/libpakfire/arch.c \
src/libpakfire/archive.c \
src/libpakfire/errno.c \
src/libpakfire/execute.c \
src/libpakfire/util.c
pkginclude_HEADERS += \
+ src/libpakfire/include/pakfire/arch.h \
src/libpakfire/include/pakfire/archive.h \
src/libpakfire/include/pakfire/constants.h \
src/libpakfire/include/pakfire/errno.h \
#include <sys/personality.h>
#include <solv/solver.h>
+
+#include <pakfire/arch.h>
#include <pakfire/package.h>
+#include <pakfire/util.h>
#include "archive.h"
#include "capabilities.h"
#include "transaction.h"
#include "util.h"
+static PyObject* _pakfire_native_arch() {
+ const char* arch = pakfire_arch_native();
+ if (!arch)
+ Py_RETURN_NONE;
+
+ return PyUnicode_FromString(arch);
+}
+
+static PyObject* _pakfire_arch_supported_by_host(PyObject* self, PyObject* args) {
+ const char* name = NULL;
+
+ if (!PyArg_ParseTuple(args, "s", &name))
+ return NULL;
+
+ if (pakfire_arch_supported_by_host(name))
+ Py_RETURN_TRUE;
+
+ Py_RETURN_FALSE;
+}
+
static PyMethodDef pakfireModuleMethods[] = {
{"performance_index", (PyCFunction)performance_index, METH_VARARGS, NULL},
{"version_compare", (PyCFunction)version_compare, METH_VARARGS, NULL},
{"personality", (PyCFunction)_personality, METH_VARARGS, NULL},
{"sync", (PyCFunction)_sync, METH_NOARGS, NULL},
{"unshare", (PyCFunction)_unshare, METH_VARARGS, NULL},
+ {"native_arch", (PyCFunction)_pakfire_native_arch, METH_NOARGS, NULL },
+ {"arch_supported_by_host", (PyCFunction)_pakfire_arch_supported_by_host, METH_VARARGS, NULL },
{ NULL, NULL, 0, NULL }
};
const char* path = NULL;
const char* arch = NULL;
- if (!PyArg_ParseTuple(args, "s|s", &path, &arch))
+ if (!PyArg_ParseTuple(args, "s|z", &path, &arch))
return -1;
// Create a new Pakfire instance
--- /dev/null
+/*#############################################################################
+# #
+# Pakfire - The IPFire package management system #
+# Copyright (C) 2021 Pakfire development team #
+# #
+# This program is free software: you can redistribute it and/or modify #
+# it under the terms of the GNU General Public License as published by #
+# the Free Software Foundation, either version 3 of the License, or #
+# (at your option) any later version. #
+# #
+# This program is distributed in the hope that it will be useful, #
+# but WITHOUT ANY WARRANTY; without even the implied warranty of #
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the #
+# GNU General Public License for more details. #
+# #
+# You should have received a copy of the GNU General Public License #
+# along with this program. If not, see <http://www.gnu.org/licenses/>. #
+# #
+#############################################################################*/
+
+#include <ctype.h>
+#include <stddef.h>
+#include <stdio.h>
+#include <string.h>
+#include <sys/utsname.h>
+
+#include <pakfire/arch.h>
+#include <pakfire/constants.h>
+#include <pakfire/private.h>
+#include <pakfire/util.h>
+
+struct pakfire_arch {
+ const char* name;
+ const char* platform;
+ const char* compatible[5];
+};
+
+static const struct pakfire_arch PAKFIRE_ARCHES[] = {
+ // x86
+ {
+ .name = "x86_64",
+ .platform = "x86",
+ .compatible = { "i686", NULL },
+ },
+ {
+ .name = "i686",
+ .platform = "x86",
+ },
+
+ // ARM
+ {
+ .name = "aarch64",
+ .platform = "arm",
+ },
+ {
+ .name = "armv7hl",
+ .platform = "arm",
+ .compatible = { "armv7l", "armv6l", "armv5tejl", "armv5tel", NULL },
+ },
+ {
+ .name = "armv7l",
+ .platform = "arm",
+ .compatible = { "armv6l", "armv5tejl", "armv5tel", NULL },
+ },
+ {
+ .name = "armv6l",
+ .platform = "arm",
+ .compatible = { "armv5tejl", "armv5tel", NULL },
+ },
+ {
+ .name = "armv5tejl",
+ .platform = "arm",
+ .compatible = { "armv5tel", NULL },
+ },
+ {
+ .name = "armv5tel",
+ .platform = "arm",
+ },
+ NULL,
+};
+
+static const struct pakfire_arch* pakfire_arch_find(const char* name) {
+ for (const struct pakfire_arch* arch = PAKFIRE_ARCHES; arch; arch++) {
+ if (strcmp(arch->name, name) == 0)
+ return arch;
+ }
+
+ return NULL;
+}
+
+PAKFIRE_EXPORT int pakfire_arch_supported(const char* name) {
+ const struct pakfire_arch* arch = pakfire_arch_find(name);
+
+ if (arch)
+ return 1;
+
+ return 0;
+}
+
+PAKFIRE_EXPORT const char* pakfire_arch_platform(const char* name) {
+ const struct pakfire_arch* arch = pakfire_arch_find(name);
+
+ if (arch && arch->platform)
+ return arch->platform;
+
+ return NULL;
+}
+
+PAKFIRE_EXPORT char* pakfire_arch_machine(const char* arch, const char* vendor) {
+ if (!vendor)
+ vendor = "unknown";
+
+ // Format string
+ char buffer[STRING_SIZE];
+ snprintf(buffer, STRING_SIZE - 1, "%s-%s-linux-gnu", arch, vendor);
+
+ // Make everything lowercase
+ for (unsigned int i = 0; i < strlen(buffer); i++)
+ buffer[i] = tolower(buffer[i]);
+
+ return pakfire_strdup(buffer);
+}
+
+static const char* __pakfire_arch_native = NULL;
+
+PAKFIRE_EXPORT const char* pakfire_arch_native() {
+ struct utsname buf;
+
+ if (!__pakfire_arch_native) {
+ if (uname(&buf) < 0)
+ return NULL;
+
+ __pakfire_arch_native = pakfire_strdup(buf.machine);
+ }
+
+ return __pakfire_arch_native;
+}
+
+PAKFIRE_EXPORT int pakfire_arch_is_compatible(const char* name, const char* compatible_arch) {
+ const struct pakfire_arch* arch = pakfire_arch_find(name);
+
+ if (!arch)
+ return 0;
+
+ for (unsigned int i = 0; arch->compatible[i]; i++) {
+ if (strcmp(arch->compatible[i], compatible_arch) == 0)
+ return 1;
+ }
+
+ return 0;
+}
+
+PAKFIRE_EXPORT int pakfire_arch_supported_by_host(const char* name) {
+ const char* native_arch = pakfire_arch_native();
+
+ // Check if those two architectures are compatible
+ return pakfire_arch_is_compatible(native_arch, name);
+}
--- /dev/null
+/*#############################################################################
+# #
+# Pakfire - The IPFire package management system #
+# Copyright (C) 2021 Pakfire development team #
+# #
+# This program is free software: you can redistribute it and/or modify #
+# it under the terms of the GNU General Public License as published by #
+# the Free Software Foundation, either version 3 of the License, or #
+# (at your option) any later version. #
+# #
+# This program is distributed in the hope that it will be useful, #
+# but WITHOUT ANY WARRANTY; without even the implied warranty of #
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the #
+# GNU General Public License for more details. #
+# #
+# You should have received a copy of the GNU General Public License #
+# along with this program. If not, see <http://www.gnu.org/licenses/>. #
+# #
+#############################################################################*/
+
+#ifndef PAKFIRE_ARCH_H
+#define PAKFIRE_ARCH_H
+
+int pakfire_arch_supported(const char* name);
+const char* pakfire_arch_platform(const char* name);
+char* pakfire_arch_machine(const char* arch, const char* vendor);
+const char* pakfire_arch_native();
+int pakfire_arch_is_compatible(const char* name, const char* compatible_arch);
+int pakfire_arch_supported_by_host(const char* name);
+
+#endif /* PAKFIRE_ARCH_H */
pakfire_version_compare;
pakfire_whatprovides;
+ # arch
+ pakfire_arch_is_compatible;
+ pakfire_arch_machine;
+ pakfire_arch_native;
+ pakfire_arch_platform;
+ pakfire_arch_supported;
+ pakfire_arch_supported_by_host;
+
# archive
pakfire_archive_count_signatures;
pakfire_archive_create;
#include <solv/poolarch.h>
#include <solv/queue.h>
+#include <pakfire/arch.h>
#include <pakfire/constants.h>
#include <pakfire/logging.h>
#include <pakfire/package.h>
}
PAKFIRE_EXPORT Pakfire pakfire_create(const char* path, const char* arch) {
+ // Default to the native architecture
+ if (!arch)
+ arch = pakfire_arch_native();
+
+ // Check if the architecture is supported
+ if (!pakfire_arch_supported(arch))
+ return NULL;
+
Pakfire pakfire = pakfire_calloc(1, sizeof(*pakfire));
if (pakfire) {
pakfire->nrefs = 1;
pakfire->path = pakfire_strdup(path);
- if (!arch)
- arch = system_machine();
+
+ // Set architecture
pakfire->arch = pakfire_strdup(arch);
// Setup logging
-#!/usr/bin/python3
-###############################################################################
-# #
-# Pakfire - The IPFire package management system #
-# Copyright (C) 2016 Pakfire development team #
-# #
-# This program is free software: you can redistribute it and/or modify #
-# it under the terms of the GNU General Public License as published by #
-# the Free Software Foundation, either version 3 of the License, or #
-# (at your option) any later version. #
-# #
-# This program is distributed in the hope that it will be useful, #
-# but WITHOUT ANY WARRANTY; without even the implied warranty of #
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the #
-# GNU General Public License for more details. #
-# #
-# You should have received a copy of the GNU General Public License #
-# along with this program. If not, see <http://www.gnu.org/licenses/>. #
-# #
-###############################################################################
-import logging
-
-log = logging.getLogger("pakfire.arch")
-log.propagate = 1
-
-class Arch(object):
- def __init__(self, name):
- assert name
-
- self.name = name
-
- def __str__(self):
- return self.name
-
- def __repr__(self):
- return "<%s %s>" % (self.__class__.__name__, self.name)
-
- def __eq__(self, other):
- return self.name == other.name
-
- @property
- def platform(self):
- """
- Returns the "class" this architecture belongs to.
- """
- if self.name.startswith("arm") or self.name == "aarch64":
- return "arm"
-
- if self.name in ("i686", "x86_64"):
- return "x86"
-
- return "unknown"
-
- def get_machine(self, vendor=None):
- if vendor is None:
- vendor = "unknown"
-
- # Make vendor lowercase
- vendor = vendor.lower()
- assert vendor
-
- s = "%s-%s-linux-gnu" % (self.name, vendor)
-
- if self.name.startswith("arm"):
- s += "eabi"
-
- return s
-
- def get_buildtarget(self, vendor=None):
- machine = self.get_machine(vendor)
-
- # Cut off last segment of machine.
- return machine.replace("-gnu", "")
-
- @property
- def compatible_arches(self):
- """
- Returns a list of all architectures that are
- compatible (i.e. can be emulated)
- """
- x = {
- # Host arch : Can build these arches.
- # x86
- "x86_64" : ["x86_64", "i686",],
- "i686" : ["i686",],
-
- # ARM
- "armv5tel" : ["armv5tel",],
- "armv5tejl" : ["armv5tel",],
- "armv6l" : ["armv5tel",],
- "armv7l" : ["armv7hl", "armv5tel",],
- "armv7hl" : ["armv7hl", "armv5tel",],
-
- "aarch64" : ["aarch64",],
- }
-
- try:
- return (Arch(a) for a in x[self.name])
- except KeyError:
- return []
-
- def is_compatible_with(self, arch):
- """
- Returns True if the given architecture is compatible
- with this architecture.
- """
- return arch in self.compatible_arches
-
- @property
- def personality(self):
- """
- Return the personality of the target system.
-
- If host and target system are of the same architecture, we return
- None to skip the setting of the personality in the build chroot.
- """
- arch2personality = {
- "x86_64" : "linux64",
- "i686" : "linux32",
- "i586" : "linux32",
- "i486" : "linux32",
- }
-
- try:
- personality = arch2personality[self.name]
- except KeyError:
- personality = None
-
- return personality
mode = None
def __init__(self, path="/", config=None, arch=None, distro=None, cache_path=None, offline=False):
- _pakfire.Pakfire.__init__(self, path, "%s" % (arch or system.native_arch))
+ _pakfire.Pakfire.__init__(self, path, arch)
# Initialise logging system
self.log = self._setup_logger()
import uuid
from . import _pakfire
-from . import arch
from . import base
from . import cgroup
from . import config
self._lock = None
# Architecture to build for
- self.arch = arch or system.arch
+ self.arch = arch or _pakfire.native_arch()
# Check if this host can build the requested architecture.
- if not system.host_supports_arch(self.arch):
+ if not _pakfire.arch_supported_by_host(self.arch):
raise BuildError(_("Cannot build for %s on this host") % self.arch)
# Initialize a cgroup (if supported)
self.setup()
- @property
- def arch(self):
- return self.pakfire.arch
-
@property
def environ(self):
env = MINIMAL_ENVIRONMENT.copy()
# Fake UTS_MACHINE, when we cannot use the personality syscall and
# if the host architecture is not equal to the target architecture.
- if not self.arch.personality and \
- not system.native_arch == self.arch.name:
+ if not _pakfire.native_arch() == self.pakfire.arch:
env.update({
"LD_PRELOAD" : "/usr/lib/libpakfire_preload.so",
- "UTS_MACHINE" : self.arch.name,
+ "UTS_MACHINE" : self.pakfire.arch,
})
return env
import tempfile
import time
-from . import arch
from . import base
from . import builder
from . import client
return parser.parse_args()
def builder(self, ns):
- a = arch.Arch(ns.arch or system.native_arch)
-
- b = builder.Builder(arch=a)
-
- return b
+ return builder.Builder(arch=ns.arch)
def handle_build(self, ns):
package, = ns.package
from .system import system
+from . import _pakfire
from . import base
from . import config
from . import http
# CPU info
"cpu_model" : system.cpu_model,
"cpu_count" : system.cpu_count,
- "cpu_arch" : system.native_arch,
+ "cpu_arch" : _pakfire.native_arch(),
"cpu_bogomips" : system.cpu_bogomips,
# Memory + swap
# Pakfire + OS
"pakfire_version" : PAKFIRE_VERSION,
"os_name" : system.distro.pretty_name,
-
- # Supported arches
- "supported_arches" : ",".join(system.supported_arches),
}
self.hub._request("/builders/info", method="POST", data=data)
import socket
import tempfile
-from . import arch
from . import distro
from . import shell
the system this software is running on.
"""
def __init__(self):
- # Load the system's native architecture
- self.arch = arch.Arch(self.native_arch)
-
# Load the system's distribution
self.distro = distro.Distribution()
return hn
- @property
- def native_arch(self):
- """
- Return the native architecture of the host we
- are running on.
- """
- return os.uname()[4]
-
- @property
- def supported_arches(self):
- """
- Check what architectures can be built on this host.
- """
- return self.arch.compatible_arches
-
- def host_supports_arch(self, arch):
- """
- Check if this host can build for the target architecture "arch".
- """
- return self.arch.is_compatible_with(arch)
-
@property
def cpu_count(self):
"""
if __name__ == "__main__":
print("Hostname", system.hostname)
print("Arch", system.arch)
- print("Supported arches", system.supported_arches)
print("CPU Model", system.cpu_model)
print("CPU count", system.cpu_count)