Skip to content

Commit

Permalink
Add dpkg support
Browse files Browse the repository at this point in the history
  • Loading branch information
raoulh committed Oct 18, 2023
1 parent 068a0b1 commit d5373a7
Show file tree
Hide file tree
Showing 9 changed files with 362 additions and 4 deletions.
6 changes: 6 additions & 0 deletions .vscode/settings.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
{
"files.associations": {
"*.tmpl": "go-template",
"string": "cpp"
}
}
18 changes: 14 additions & 4 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,17 @@ BINARY_NAME_TOOL=calaos-os
VERSION?=1.0.0

TOP_DIR := $(dir $(abspath $(firstword $(MAKEFILE_LIST))))
SUBDIRS := apt

SERVER_LDFLAGS := -L$(pwd)/bin -L. -L./bin -lcalaos-apt

GREEN := $(shell tput -Txterm setaf 2)
YELLOW := $(shell tput -Txterm setaf 3)
WHITE := $(shell tput -Txterm setaf 7)
CYAN := $(shell tput -Txterm setaf 6)
RESET := $(shell tput -Txterm sgr0)

.PHONY: all test build
.PHONY: all test build $(SUBDIRS)
.ONESHELL:

all: build
Expand All @@ -31,7 +34,7 @@ help: ## Show this help.
}' $(MAKEFILE_LIST)

## Build:
build: build-server build-tools ## Build the project and put the output binary in bin/
build: build-lib build-server build-tools ## Build the project and put the output binary in bin/
@mkdir -p bin

build-tools:
Expand All @@ -40,9 +43,16 @@ build-tools:
$(GOCMD) build -v -o $(TOP_DIR)/bin/$(BINARY_NAME_TOOL) .
@cd $(TOP_DIR)

build-server:
build-server: build-lib
@mkdir -p bin
CGO_LDFLAGS="$(SERVER_LDFLAGS)" $(GOCMD) build -v -o bin/$(BINARY_NAME) .

build-lib: $(SUBDIRS)
@mkdir -p bin
$(GOCMD) build -v -o bin/$(BINARY_NAME) .
@mv apt/libcalaos-apt.so bin/

$(SUBDIRS):
$(MAKE) -C $@

clean: ## Remove build related file
rm -fr ./bin
Expand Down
10 changes: 10 additions & 0 deletions apt/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
.PHONY: libcalaos-apt.so

all: libcalaos-apt.so

CFLAGS = $(shell pkg-config --cflags glib-2.0)
LDLIBS = $(shell pkg-config --libs glib-2.0)

libcalaos-apt.so: apt.cpp apt-cache-file.cpp
g++ -o $@ $^ $(CFLAGS) \
-std=c++17 -O2 -fPIC -shared
90 changes: 90 additions & 0 deletions apt/apt-cache-file.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
#include "apt-cache-file.h"

#include <iostream>

#include <apt-pkg/algorithms.h>
#include <apt-pkg/progress.h>
#include <apt-pkg/upgrade.h>

using namespace APT;

AptCacheFile::AptCacheFile()
{
}

AptCacheFile::~AptCacheFile()
{
Close();
}

bool AptCacheFile::Open(bool withLock)
{
//OpPackageKitProgress progress(m_job);
return pkgCacheFile::Open(/*&progress*/ nullptr, withLock);
}

void AptCacheFile::Close()
{
pkgCacheFile::Close();

// Discard all errors to avoid a future failure when opening
// the package cache
_error->Discard();
}

bool AptCacheFile::BuildCaches(bool withLock)
{
//OpPackageKitProgress progress(m_job);
return pkgCacheFile::BuildCaches(/*&progress*/ nullptr, withLock);
}

bool AptCacheFile::CheckDeps(bool AllowBroken)
{
if (_error->PendingError() == true) {
return false;
}

// Check that the system is OK
if (DCache->DelCount() != 0 || DCache->InstCount() != 0) {
_error->Error("Internal error, non-zero counts");
//show_errors(m_job, PK_ERROR_ENUM_INTERNAL_ERROR);

return false;
}

// Apply corrections for half-installed packages
if (pkgApplyStatus(*DCache) == false) {
_error->Error("Unable to apply corrections for half-installed packages");;
//show_errors(m_job, PK_ERROR_ENUM_INTERNAL_ERROR);
return false;
}

// Nothing is broken or we don't want to try fixing it
if (DCache->BrokenCount() == 0 || AllowBroken == true) {
return true;
}

// Attempt to fix broken things
if (pkgFixBroken(*DCache) == false || DCache->BrokenCount() != 0) {
// We failed to fix the cache
//ShowBroken(true, PK_ERROR_ENUM_UNFINISHED_TRANSACTION);

//g_warning("Unable to correct dependencies");
return false;
}

if (pkgMinimizeUpgrade(*DCache) == false) {
//g_warning("Unable to minimize the upgrade set");
//show_errors(m_job, PK_ERROR_ENUM_INTERNAL_ERROR);
return false;
}

// Fixing the cache is DONE no errors were found
return true;
}

bool AptCacheFile::DistUpgrade()
{
//OpPackageKitProgress progress(m_job);
return Upgrade::Upgrade(*this, Upgrade::ALLOW_EVERYTHING, nullptr /*&progress*/);
}
41 changes: 41 additions & 0 deletions apt/apt-cache-file.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
#pragma once

#include <apt-pkg/cachefile.h>
#include <apt-pkg/pkgrecords.h>
#include <apt-pkg/progress.h>

class AptCacheFile : public pkgCacheFile
{
public:
AptCacheFile();
~AptCacheFile();

/**
* Inits the package cache returning false if it can't open
*/
bool Open(bool withLock = false);

/**
* Closes the package cache
*/
void Close();

/**
* Build caches
*/
bool BuildCaches(bool withLock = false);

/**
* This routine generates the caches and then opens the dependency cache
* and verifies that the system is OK.
* @param AllowBroken when true it will try to perform the installation
* even if we have broken packages, when false it will try to fix
* the current situation
*/
bool CheckDeps(bool AllowBroken = false);

/**
* Mark Cache for dist-upgrade
*/
bool DistUpgrade();
};
128 changes: 128 additions & 0 deletions apt/apt.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,128 @@
#include "apt.h"
#include "apt-cache-file.h"

#include <vector>
#include <iostream>

#include <apt-pkg/init.h>
#include <apt-pkg/pkgsystem.h>

using namespace APT;
using namespace std;

typedef std::vector<Pkg> PkgList;

void aptInit()
{
if (!pkgInitConfig(*_config))
{
//g_debug("ERROR initializing backend configuration");
}

if (!pkgInitSystem(*_config, _system))
{
//g_debug("ERROR initializing backend system");
}

_config->CndSet("APT::Get::AutomaticRemove::Kernels",
_config->FindB("APT::Get::AutomaticRemove", true));
}

void *aptCacheGetArray()
{
auto cache = new AptCacheFile();

cout << "AptCacheFile Open()" << endl;
if (cache->Open(true) == false)
{
//Unable to get lock
//TODO: return error
delete cache;
return nullptr;
}

/*
_config->Set("Dpkg::Options::", "--force-confdef");
_config->Set("Dpkg::Options::", "--force-confold");
setenv("APT_LISTCHANGES_FRONTEND", "none", true);
setenv("APT_LISTBUGS_FRONTEND", "none", true);
*/

cout << "AptCacheFile CheckDeps()" << endl;
if (!cache->CheckDeps(false))
{
//System is in inconsistent state
//TODO: return error
delete cache;
return nullptr;
}

cout << "AptCacheFile DistUpgrade()" << endl;
if (!cache->DistUpgrade())
{
//Failed to get updates
//TODO: return error
delete cache;
return nullptr;
}

PkgList *plist = new PkgList();

cout << "Listing pkgs" << endl;
for (pkgCache::PkgIterator pkg = (*cache)->PkgBegin(); !pkg.end(); ++pkg)
{
const auto &state = (*cache)[pkg];

if (pkg->CurrentVer != 0 && state.Upgradable() && state.CandidateVer != nullptr)
{
string current = string(pkg.CurVersion() == 0 ? "none" : pkg.CurVersion());
string newest = string(pkg.VersionList().end() ? "none" : pkg.VersionList().VerStr());

cout << "Append pkg " << pkg.Name() << endl;

Pkg p{nullptr, nullptr, nullptr};
p.name = strdup(pkg.Name());
p.version_current = strdup(current.c_str());
p.version_new = strdup(newest.c_str());

plist->push_back(p);
}
}

return plist;
}

int aptCacheArrayCount(void *arr)
{
PkgList *plist = reinterpret_cast<PkgList *>(arr);
if (!plist) return 0;

return plist->size();
}

Pkg *aptCacheArrayGet(void *arr, int idx)
{
PkgList *plist = reinterpret_cast<PkgList *>(arr);
if (!plist) return nullptr;

if (idx < 0 || idx > plist->size())
return nullptr;

return &plist->at(idx);
}

void aptCacheArrayFree(void *arr)
{
PkgList *plist = reinterpret_cast<PkgList *>(arr);
if (!plist) return;

for (int i = 0;i < plist->size();i++)
{
free((*plist)[i].name);
free((*plist)[i].version_current);
free((*plist)[i].version_new);
}

delete plist;
}
36 changes: 36 additions & 0 deletions apt/apt.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
package apt

// #cgo pkg-config: apt-pkg
// #include "apt.h"
import (
"C"
)

type Pkg struct {
Name string
VersionCurrent string
VersionNew string
}

func init() {
C.aptInit()
}

func GetCachePackages() (plist []*Pkg) {
arr := C.aptCacheGetArray()
defer C.aptCacheArrayFree(arr)

for i := 0; i < int(C.aptCacheArrayCount(arr)); i++ {
p := (*C.Pkg)(C.aptCacheArrayGet(arr, C.int(i)))

pkg := &Pkg{
Name: C.GoString(p.name),
VersionCurrent: C.GoString(p.version_current),
VersionNew: C.GoString(p.version_new),
}

plist = append(plist, pkg)
}

return
}
22 changes: 22 additions & 0 deletions apt/apt.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
#pragma once

#ifdef __cplusplus
extern "C" {
#endif

typedef struct
{
char *name;
char *version_current;
char *version_new;
} Pkg;

void aptInit();
void *aptCacheGetArray();
int aptCacheArrayCount(void *arr);
Pkg *aptCacheArrayGet(void *arr, int idx);
void aptCacheArrayFree(void *arr);

#ifdef __cplusplus
} // extern "C"
#endif
Loading

0 comments on commit d5373a7

Please sign in to comment.