From 885ce25fe97dbbf5109748cd4d671367b565bbb6 Mon Sep 17 00:00:00 2001 From: robogg133 Date: Sun, 2 Nov 2025 21:30:43 -0300 Subject: [PATCH] database files and changes --- cmd/packets/database/database.go | 101 ----------------------- cmd/packets/database/execute.go | 132 +++++++++++++++++++++++++++++++ cmd/packets/database/query.go | 44 +++++++++++ cmd/packets/main.go | 68 ++++++++++++++-- cmd/packets/specifications.go | 2 +- cmd/packets/user.go | 37 +++++++++ test/bat/Packet.lua | 2 + 7 files changed, 278 insertions(+), 108 deletions(-) delete mode 100644 cmd/packets/database/database.go create mode 100644 cmd/packets/database/execute.go create mode 100644 cmd/packets/database/query.go create mode 100644 cmd/packets/user.go diff --git a/cmd/packets/database/database.go b/cmd/packets/database/database.go deleted file mode 100644 index a9d6127..0000000 --- a/cmd/packets/database/database.go +++ /dev/null @@ -1,101 +0,0 @@ -package database - -import ( - "database/sql" - "time" - - _ "github.com/mattn/go-sqlite3" - "github.com/roboogg133/packets/pkg/packet.lua.d" -) - -const ( - CreateInstructions = `CREATE TABLE installed_packges( - name TEXT NOT NULL, - id TEXT PRIMARY KEY, - version TEXT NOT NULL, - serial INTEGER NOT NULL, - maintainer TEXT NOT NULL, - verified INTEGER NOT NULL DEFAULT 0, - description TEXT NOT NULL, - upload_time TEXT NOT NULL, - installed_time TEXT NOT NULL, - - image BLOB, - - UNIQUE(name, signature), - UNIQUE(name, version), - UNIQUE(name, serial) -) - -CREATE TABLE package_files( - package_id TEXT PRIMARY KEY, - filepath TEXT NOT NULL, - is_dir INTEGER NOT NULL DEFAULT 0, - - UNIQUE(package_id, filepath) -) - -CREATE TABLE dependencies( - package_id TEXT NOT NULL, - dependency_name TEXT NOT NULL, - constraint TEXT NOT NULL, - - PRIMARY KEY (package_id, dependency_name) -) - - -CREATE TABLE build_dependencies( - package_id TEXT NOT NULL, - dependency_name TEXT NOT NULL, - constraint TEXT NOT NULL, - - PRIMARY KEY (package_id, dependency_name) -) - - -CREATE TABLE conflicts( - package_id TEXT NOT NULL, - dependency_name TEXT NOT NULL, - constraint TEXT NOT NULL, - - PRIMARY KEY (package_id, dependency_name) -) - -CREATE TABLE package_flags( - package_id TEXT NOT NULL, - flag TEXT NOT NULL, - name TEXT NOT NULL, - path TEXT NOT NULL, -) -` -) - -type DatabaseOptions struct { - // Add any additional options here -} - -func MarkAsInstalled(pkg packet.PacketLua, db *sql.DB, image *[]byte) error { - - if image != nil { - _, err := db.Exec("INSERT INTO installed_packages (name, id, version, installed_time, image) VALUES (?, ?, ?, ?, ?, ?, ?)", pkg.Name, pkg.Name+"@"+pkg.Version, pkg.Version, time.Now().UnixMilli(), image) - if err != nil { - return err - } - } else { - _, err := db.Exec("INSERT INTO installed_packages (name, id, version, installed_time, image) VALUES (?, ?, ?, ?, ?, ?, ?)", pkg.Name, pkg.Name+"@"+pkg.Version, pkg.Version, time.Now().UnixMilli(), []byte{1}) - if err != nil { - return err - } - } - return nil -} - -func MarkAsUninstalled(id string, db *sql.DB) error { - _, err := db.Exec("DELETE FROM installed_packages WHERE id = ?", id) - if err != nil { - return err - } - return nil -} - -func PrepareDataBase(db *sql.DB) { _, _ = db.Exec(CreateInstructions) } diff --git a/cmd/packets/database/execute.go b/cmd/packets/database/execute.go new file mode 100644 index 0000000..1e4153f --- /dev/null +++ b/cmd/packets/database/execute.go @@ -0,0 +1,132 @@ +package database + +import ( + "database/sql" + "fmt" + "strings" + "time" + + _ "github.com/mattn/go-sqlite3" + "github.com/roboogg133/packets/internal/lua" + "github.com/roboogg133/packets/pkg/install" + "github.com/roboogg133/packets/pkg/packet.lua.d" +) + +const ( + CreateInstructions = ` +CREATE TABLE IF NOT EXISTS installed_packages( + name TEXT NOT NULL, + id TEXT PRIMARY KEY, + version TEXT NOT NULL, + serial INTEGER NOT NULL, + maintainer TEXT NOT NULL, + verified INTEGER NOT NULL DEFAULT 0, + description TEXT NOT NULL, + upload_time TEXT NOT NULL, + installed_time INTEGER NOT NULL, + image BLOB, + UNIQUE(name, version), + UNIQUE(name, serial) +); + +CREATE TABLE IF NOT EXISTS package_files( + package_id TEXT NOT NULL, + path TEXT NOT NULL, + is_dir INTEGER NOT NULL DEFAULT 0, + UNIQUE(package_id, path) +); + +CREATE TABLE IF NOT EXISTS dependencies( + package_id TEXT NOT NULL, + dependency_name TEXT NOT NULL, + version_constraint TEXT NOT NULL, + PRIMARY KEY (package_id, dependency_name) +); + +CREATE TABLE IF NOT EXISTS build_dependencies( + package_id TEXT NOT NULL, + dependency_name TEXT NOT NULL, + version_constraint TEXT NOT NULL, + PRIMARY KEY (package_id, dependency_name) +); + +CREATE TABLE IF NOT EXISTS conflicts( + package_id TEXT NOT NULL, + dependency_name TEXT NOT NULL, + version_constraint TEXT NOT NULL, + PRIMARY KEY (package_id, dependency_name) +); + +CREATE TABLE IF NOT EXISTS package_flags( + package_id TEXT NOT NULL, + flag TEXT NOT NULL, + name TEXT NOT NULL, + path TEXT NOT NULL +); +` +) + +type DatabaseOptions struct { + // Add any additional options here +} + +func MarkAsInstalled(pkg packet.PacketLua, files []install.BasicFileStatus, PACKETDIR string, flags []lua.Flag, db *sql.DB, image []byte, upload_time int64) error { + + switch { + case upload_time == 0: + upload_time = time.Now().UnixMilli() + case image == nil: + image = []byte{1} + } + + _, err := db.Exec("INSERT INTO installed_packages (name, id, version, installed_time, image, serial, maintainer, description, upload_time) VALUES (?, ?, ?, ?, ?, ?,?,?,?)", pkg.Name, pkg.Name+"@"+pkg.Version, pkg.Version, time.Now().UnixMilli(), image, pkg.Serial, pkg.Maintainer, pkg.Description, time.Now().UnixMilli()) + if err != nil { + db.Exec("DELETE FROM installed_packages WHERE id = ?", pkg.Name+"@"+pkg.Version) + return err + } + + for _, v := range files { + v.Filepath, _ = strings.CutPrefix(v.Filepath, PACKETDIR) + _, err = db.Exec("INSERT INTO package_files (package_id, path, is_dir) VALUES (?, ?, ?)", pkg.Name+"@"+pkg.Version, v.Filepath, v.IsDir) + if err != nil { + db.Exec("DELETE FROM installed_packages WHERE id = ?", pkg.Name+"@"+pkg.Version) + db.Exec("DELETE FROM package_files WHERE package_id = ?", pkg.Name+"@"+pkg.Version) + return err + } + } + + for _, v := range flags { + _, err = db.Exec("INSERT INTO package_flags (package_id, flag, name, path) VALUES (?, ?, ?, ?)", pkg.Name+"@"+pkg.Version, v.FlagType, v.Name, v.Path) + if err != nil { + db.Exec("DELETE FROM installed_packages WHERE id = ?", pkg.Name+"@"+pkg.Version) + db.Exec("DELETE FROM package_files WHERE package_id = ?", pkg.Name+"@"+pkg.Version) + db.Exec("DELETE FROM package_flags WHERE package_id = ?", pkg.Name+"@"+pkg.Version) + + return err + } + } + + return nil +} + +func MarkAsUninstalled(id string, db *sql.DB) error { + if _, err := db.Exec("DELETE FROM installed_packages WHERE id = ?", id); err != nil { + return err + } + + if _, err := db.Exec("DELETE FROM package_files WHERE package_id = ?", id); err != nil { + return err + } + + if _, err := db.Exec("DELETE FROM package_flags WHERE package_id = ?", id); err != nil { + return err + } + return nil +} + +func PrepareDataBase(db *sql.DB) { + _, err := db.Exec(CreateInstructions) + if err != nil { + fmt.Println("Error preparing database:", err) + } +} diff --git a/cmd/packets/database/query.go b/cmd/packets/database/query.go new file mode 100644 index 0000000..278911d --- /dev/null +++ b/cmd/packets/database/query.go @@ -0,0 +1,44 @@ +package database + +import ( + "database/sql" + "strings" + + "github.com/roboogg133/packets/pkg/install" + "github.com/roboogg133/packets/pkg/packet.lua.d" +) + +// this function will get from a package name an id based on installed packages +func GetPackageId(name string, db *sql.DB) (packet.PackageID, error) { + var id packet.PackageID + + if strings.Contains(name, "@") { + id.ID = strings.SplitAfter(name, "@")[0] + return id, nil + } + + err := db.QueryRow("SELECT id FROM installed_packages WHERE name = ?", name).Scan(&id.ID) + return id, err +} + +func GetPackageFiles(packageID packet.PackageID, db *sql.DB) ([]install.BasicFileStatus, error) { + var files []install.BasicFileStatus + rows, err := db.Query("SELECT path, is_dir FROM package_files WHERE package_id = ?", packageID.ID) + if err != nil { + return nil, err + } + defer rows.Close() + + for rows.Next() { + var file install.BasicFileStatus + if err := rows.Scan(&file.Filepath, &file.IsDir); err != nil { + return nil, err + } + files = append(files, file) + } + if err := rows.Err(); err != nil { + return nil, err + } + + return files, nil +} diff --git a/cmd/packets/main.go b/cmd/packets/main.go index 31fa516..1baec21 100644 --- a/cmd/packets/main.go +++ b/cmd/packets/main.go @@ -15,6 +15,13 @@ import ( "github.com/spf13/cobra" ) +func GrantPrivilegies() { + if os.Geteuid() != 0 { + fmt.Println("error: this operation must be run as root") + os.Exit(1) + } +} + var Config *PacketsConfiguration var rootCmd = &cobra.Command{ @@ -29,14 +36,10 @@ var executeCmd = &cobra.Command{ Long: "Installs a package from a given Packet.lua file", Args: cobra.MinimumNArgs(1), PreRunE: func(cmd *cobra.Command, args []string) error { + GrantPrivilegies() return GetConfiguration() }, Run: func(cmd *cobra.Command, args []string) { - if os.Geteuid() != 0 { - fmt.Println("error: this operation must be run as root") - os.Exit(1) - } - for _, v := range args { if !strings.HasSuffix(v, ".lua") { fmt.Printf("error: %s need to have .lua suffix\n", v) @@ -127,7 +130,7 @@ var executeCmd = &cobra.Command{ defer db.Close() database.PrepareDataBase(db) - if err := database.MarkAsInstalled(pkg, db, nil); err != nil { + if err := database.MarkAsInstalled(pkg, files, configs.PacketDir, pkg.Flags, db, nil, 0); err != nil { fmt.Printf("error: %s", err.Error()) os.Exit(1) } @@ -135,7 +138,60 @@ var executeCmd = &cobra.Command{ }, } +var removeCmd = &cobra.Command{ + Use: "remove {name or id}", + Short: "Removes a package from the system", + Long: "Removes a package from the system", + Args: cobra.MinimumNArgs(1), + PreRun: func(cmd *cobra.Command, args []string) { + GrantPrivilegies() + }, + Run: func(cmd *cobra.Command, args []string) { + for _, arg := range args { + + db, err := sql.Open("sqlite3", InternalDB) + if err != nil { + fmt.Printf("error: %s\n", err.Error()) + os.Exit(1) + } + defer db.Close() + + id, err := database.GetPackageId(arg, db) + if err != nil { + if err == sql.ErrNoRows { + fmt.Printf("package %s not found\n", arg) + continue + } + fmt.Printf("error: %s\n", err.Error()) + continue + } + + files, err := database.GetPackageFiles(id, db) + if err != nil { + fmt.Printf("error: %s\n", err.Error()) + continue + } + + for _, file := range files { + if !file.IsDir { + if err := os.Remove(file.Filepath); err != nil { + fmt.Printf("error: %s\n", err.Error()) + continue + } + } + } + + if err := database.MarkAsUninstalled(id.ID, db); err != nil { + fmt.Printf("error removing package from database but successfully removed it from the system: %s\n", err.Error()) + continue + } + + } + }, +} + func main() { rootCmd.AddCommand(executeCmd) + rootCmd.AddCommand(removeCmd) rootCmd.Execute() } diff --git a/cmd/packets/specifications.go b/cmd/packets/specifications.go index 98e9508..50332b0 100644 --- a/cmd/packets/specifications.go +++ b/cmd/packets/specifications.go @@ -4,7 +4,7 @@ const ( ConfigurationDir = "/etc/packets" InternalDB = ConfigurationDir + "/internal.db" HomeDir = "/var/lib/packets" - PackageRootDir = "_pkgtest" + PackageRootDir = "/var/lib/packets/packages" NumberOfTryAttempts = 4 UserHomeDirPlaceholder = "{{ USER HOME FOLDER }}" UsernamePlaceholder = "{{ USERNAME }}" diff --git a/cmd/packets/user.go b/cmd/packets/user.go new file mode 100644 index 0000000..40de16c --- /dev/null +++ b/cmd/packets/user.go @@ -0,0 +1,37 @@ +package main + +import ( + "os/exec" + "strconv" + "strings" + "syscall" +) + +func GetPacketsUID() (int, error) { + _ = exec.Command("useradd", "-M", "-N", "-r", "-s", "/bin/false", "-d", "/etc/packets", "packets").Run() + cmd := exec.Command("id", "-u", "packets") + + out, err := cmd.CombinedOutput() + if err != nil { + return -1, err + } + + s := strings.TrimSpace(string(out)) + uid, err := strconv.Atoi(s) + if err != nil { + return -1, err + } + return uid, nil +} + +func ChangeToNoPermission() error { + uid, err := GetPacketsUID() + if err != nil { + return err + } + + return syscall.Setresuid(0, uid, 0) + +} + +func ElevatePermission() error { return syscall.Setresuid(0, 0, 0) } diff --git a/test/bat/Packet.lua b/test/bat/Packet.lua index daa3773..0972dc1 100644 --- a/test/bat/Packet.lua +++ b/test/bat/Packet.lua @@ -56,6 +56,8 @@ return { if not suc then error("failed to copy bat: " .. errmsg) end + + os.copy("bat.1", pathjoin(PACKETDIR, "/usr/share/man/man1/bat.1")) end, }