14 Commits

Author SHA1 Message Date
Clayton Craft
d77e1cd11d filelist/osk-sdl: add deprecation warning
Co-authored-by: Oliver Smith <ollieparanoid@postmarketos.org>
2023-10-12 23:26:16 -07:00
Clayton Craft
2ec78bfcfc mkinitfs: print error when failure to rm tmp dir, and make it non-fatal (MR 40)
This prints the error when the work dir can't be removed. This also
changes mkinitfs so that it does't fail in this situation.

The reasoning for this change in behavior is that mkinitfs returning
non-zero will signal to the caller that there's potentially a problem
with configuring boot-related stuff on their system, and a failure to rm
the work dir is just noise. If the cause of that failure is a deeper
problem, the log message should help figure it out.

fixes #35
2023-08-24 17:13:15 -07:00
Clayton Craft
fedf55b573 filelist/*: support comment lines starting with # (MR 41) 2023-08-24 17:11:47 -07:00
Clayton Craft
30681d2f0a filelist/*: skip empty lines (MR 41)
fixes #36
2023-08-24 17:11:22 -07:00
Clayton Craft
74de5f9798 mkinitfs: handle errors from archive.AddItems (MR 41) 2023-08-24 17:10:12 -07:00
Pablo Correa Gómez
2f4937c52d deviceinfo: add tests for ReadDeviceinfo (MR 37) 2023-06-18 10:18:15 -07:00
Pablo Correa Gómez
b1e44d8ec2 main: read /usr/share/deviceinfo/deviceinfo in addition to /etc/deviceinfo (MR 37)
Relates https://gitlab.com/postmarketOS/pmaports/-/issues/1836

The error checking for the detection of both files is not ideal, but there
are no obvious better solutions. For now, we want to avoid requiring one
by default, since it allows this change to be forward compatible so not
all MRs related to /usr/share have to go in at once. I followed the same
pattern as in boot-deploy!29 although there we check for "deviceinfo_arch"
to make sure that at least one of those files is complete.

The other alternative would be to add an Arch field to DeviceInfo struct,
and use it to check that at least one of the files was complete, and
ignore any errors if it exists. Since this is not ideal either, keep the
double test, and let's take care of fixes once one of them is compulsory.
2023-06-18 10:18:14 -07:00
Pablo Correa Gómez
c87b926a53 Move logic to check if deviceinfo file exists to pkgs/deviceinfo (MR 37)
This is mostly a preparatory commit to later be able to read the
deviceinfo from multiple places. It has a bit better encapsulation,
and makes the functions methods, so that they can update deviceinfo
file in-place.
2023-06-18 10:18:14 -07:00
Pablo Correa Gómez
b2cdfe9da4 main: return if unexpected error happens checking for deviceinfo file (MR 37) 2023-06-18 10:18:12 -07:00
Gabriel Marcano
a15c02f3aa archive: support using lz4 legacy (MR 36)
fixes: https://gitlab.com/postmarketOS/postmarketos-mkinitfs/-/issues/27
2023-04-10 17:45:59 -07:00
Clayton Craft
0054fde90d cmd/mkinitfs: Exclude initramfs files from initramfs-extra (MR 34)
When testing on pmOS with qemu/x86_64, this results in some nice
reduction in size of the initramfs-extra (gzip'd, default compression):

Before:
        /mkinitfs # ls -la /boot/initramfs-extra
        -rw-r--r--    1 root     root       3544429 Mar 19 23:06 /boot/initramfs-extra

After:
        /mkinitfs # ls -la /boot/initramfs-extra
        -rw-r--r--    1 root     root       2234020 Mar 19 23:08 /boot/initramfs-extra

Fixes #23
2023-04-06 22:21:27 -07:00
Clayton Craft
dceef20121 cmd/mkinitfs: unroll generateArchive (MR 34)
There's some repetition that's added by unrolling this, but it will
allow passing the main initramfs archive's filelister to
archive.AddItemsExclude when generating the initramfs-extra.

I looked at several ways to implement this, this seems like least
terrible thing to do... The runner-up was to return a FileList from
archive.AddItems, and pass that around... Eww.
2023-04-06 22:21:27 -07:00
Clayton Craft
25017f3a3b archive: add AddItemsExclude method (MR 34)
This allows passing a filelister of things to exclude from the archive
2023-04-06 22:21:27 -07:00
Clayton Craft
67ce1a9c2e filelist/initramfs: cache list of files (MR 34)
Allows subsequent calls to List() to return quickly
2023-04-06 22:21:25 -07:00
17 changed files with 217 additions and 94 deletions

View File

@@ -49,18 +49,13 @@ func main() {
log.Default().SetFlags(log.Lmicroseconds) log.Default().SetFlags(log.Lmicroseconds)
deviceinfoFile := "/etc/deviceinfo" var devinfo deviceinfo.DeviceInfo
if exists, err := misc.Exists(deviceinfoFile); !exists { deverr_usr := devinfo.ReadDeviceinfo("/usr/share/deviceinfo/deviceinfo")
log.Printf("NOTE: %q not found, this file is required by mkinitfs.\n", deviceinfoFile) deverr_etc := devinfo.ReadDeviceinfo("/etc/deviceinfo")
return if deverr_etc != nil && deverr_usr != nil {
} else if err != nil { log.Println("Error reading deviceinfo")
retCode = 1 log.Println("\t/usr/share/deviceinfo/deviceinfo:", deverr_usr)
log.Printf("received unexpected error when getting status for %q: %s", deviceinfoFile, err) log.Println("\t/etc/deviceinfo:", deverr_etc)
}
devinfo, err := deviceinfo.ReadDeviceinfo(deviceinfoFile)
if err != nil {
log.Println(err)
retCode = 1 retCode = 1
return return
} }
@@ -85,17 +80,25 @@ func main() {
defer func() { defer func() {
e := os.RemoveAll(workDir) e := os.RemoveAll(workDir)
if e != nil && err == nil { if e != nil && err == nil {
err = e log.Println(e)
retCode = 1 log.Println("unable to remove temporary work directory")
} }
}() }()
log.Print("Generating for kernel version: ", kernVer) log.Print("Generating for kernel version: ", kernVer)
log.Print("Output directory: ", *outDir) log.Print("Output directory: ", *outDir)
//
// initramfs
//
// deviceinfo.InitfsCompression needs a little more post-processing // deviceinfo.InitfsCompression needs a little more post-processing
compressionFormat, compressionLevel := archive.ExtractFormatLevel(devinfo.InitfsCompression) compressionFormat, compressionLevel := archive.ExtractFormatLevel(devinfo.InitfsCompression)
if err := generateArchive("initramfs", compressionFormat, compressionLevel, workDir, []filelist.FileLister{ log.Printf("== Generating %s ==\n", "initramfs")
log.Printf("- Using compression format %s with level %q\n", compressionFormat, compressionLevel)
start := time.Now()
initramfsAr := archive.New(compressionFormat, compressionLevel)
initfs := initramfs.New([]filelist.FileLister{
hookdirs.New("/usr/share/mkinitfs/dirs"), hookdirs.New("/usr/share/mkinitfs/dirs"),
hookdirs.New("/etc/mkinitfs/dirs"), hookdirs.New("/etc/mkinitfs/dirs"),
hookfiles.New("/usr/share/mkinitfs/files"), hookfiles.New("/usr/share/mkinitfs/files"),
@@ -104,16 +107,32 @@ func main() {
hookscripts.New("/etc/mkinitfs/hooks", "/hooks"), hookscripts.New("/etc/mkinitfs/hooks", "/hooks"),
modules.New(strings.Fields(devinfo.ModulesInitfs), "/usr/share/mkinitfs/modules"), modules.New(strings.Fields(devinfo.ModulesInitfs), "/usr/share/mkinitfs/modules"),
modules.New([]string{}, "/etc/mkinitfs/modules"), modules.New([]string{}, "/etc/mkinitfs/modules"),
}); err != nil { })
if err := initramfsAr.AddItems(initfs); err != nil {
log.Println(err) log.Println(err)
log.Println("failed to generate: ", "initramfs") log.Println("failed to generate: ", "initramfs")
retCode = 1 retCode = 1
return return
} }
if err := initramfsAr.Write(filepath.Join(workDir, "initramfs"), os.FileMode(0644)); err != nil {
log.Println(err)
log.Println("failed to generate: ", "initramfs")
retCode = 1
return
}
misc.TimeFunc(start, "initramfs")
//
// initramfs-extra
//
// deviceinfo.InitfsExtraCompression needs a little more post-processing // deviceinfo.InitfsExtraCompression needs a little more post-processing
compressionFormat, compressionLevel = archive.ExtractFormatLevel(devinfo.InitfsExtraCompression) compressionFormat, compressionLevel = archive.ExtractFormatLevel(devinfo.InitfsExtraCompression)
if err := generateArchive("initramfs-extra", compressionFormat, compressionLevel, workDir, []filelist.FileLister{ log.Printf("== Generating %s ==\n", "initramfs-extra")
log.Printf("- Using compression format %s with level %q\n", compressionFormat, compressionLevel)
start = time.Now()
initramfsExtraAr := archive.New(compressionFormat, compressionLevel)
initfsExtra := initramfs.New([]filelist.FileLister{
hookfiles.New("/usr/share/mkinitfs/files-extra"), hookfiles.New("/usr/share/mkinitfs/files-extra"),
hookfiles.New("/etc/mkinitfs/files-extra"), hookfiles.New("/etc/mkinitfs/files-extra"),
hookscripts.New("/usr/share/mkinitfs/hooks-extra", "/hooks-extra"), hookscripts.New("/usr/share/mkinitfs/hooks-extra", "/hooks-extra"),
@@ -121,12 +140,20 @@ func main() {
modules.New([]string{}, "/usr/share/mkinitfs/modules-extra"), modules.New([]string{}, "/usr/share/mkinitfs/modules-extra"),
modules.New([]string{}, "/etc/mkinitfs/modules-extra"), modules.New([]string{}, "/etc/mkinitfs/modules-extra"),
osksdl.New(devinfo.MesaDriver), osksdl.New(devinfo.MesaDriver),
}); err != nil { })
if err := initramfsExtraAr.AddItemsExclude(initfsExtra, initfs); err != nil {
log.Println(err) log.Println(err)
log.Println("failed to generate: ", "initramfs-extra") log.Println("failed to generate: ", "initramfs-extra")
retCode = 1 retCode = 1
return return
} }
if err := initramfsExtraAr.Write(filepath.Join(workDir, "initramfs-extra"), os.FileMode(0644)); err != nil {
log.Println(err)
log.Println("failed to generate: ", "initramfs-extra")
retCode = 1
return
}
misc.TimeFunc(start, "initramfs-extra")
// Final processing of initramfs / kernel is done by boot-deploy // Final processing of initramfs / kernel is done by boot-deploy
if !disableBootDeploy { if !disableBootDeploy {
@@ -146,23 +173,3 @@ func bootDeploy(workDir, outDir, ubootBoardname string) error {
bd := bootdeploy.New(workDir, outDir, ubootBoardname) bd := bootdeploy.New(workDir, outDir, ubootBoardname)
return bd.Run() return bd.Run()
} }
func generateArchive(name string, format archive.CompressFormat, level archive.CompressLevel, path string, features []filelist.FileLister) error {
log.Printf("== Generating %s ==\n", name)
log.Printf("- Using compression format %s with level %q\n", format, level)
defer misc.TimeFunc(time.Now(), name)
a := archive.New(format, level)
fs := initramfs.New(features)
if err := a.AddItems(fs); err != nil {
return err
}
log.Println("- Writing and verifying archive: ", name)
if err := a.Write(filepath.Join(path, name), os.FileMode(0644)); err != nil {
return err
}
return nil
}

View File

@@ -38,7 +38,8 @@ Design goals of this project are:
The canonical deviceinfo "specification" is at The canonical deviceinfo "specification" is at
https://wiki.postmarketos.org/wiki/Deviceinfo_reference https://wiki.postmarketos.org/wiki/Deviceinfo_reference
mkinitfs reads deviceinfo values from */etc/deviceinfo*. The following variables mkinitfs reads deviceinfo values from */usr/share/deviceinfo/deviceinfo* and
*/etc/deviceinfo*, in that order. The following variables
are *required* by mkinitfs: are *required* by mkinitfs:
- deviceinfo_initfs_compression - deviceinfo_initfs_compression
@@ -63,7 +64,7 @@ it are for constructing the initramfs archive.
Configuration under */usr/share/mkinitfs* is intended to be managed by Configuration under */usr/share/mkinitfs* is intended to be managed by
distributions, while configuration under */etc/mkinitfs* is for users to distributions, while configuration under */etc/mkinitfs* is for users to
create/manage. mkinitfs reads configuration from */usr/share/mkinitfs* first, and then from */etc/mkinitfs*. create/manage. mkinitfs reads configuration from */usr/share/mkinitfs* first, and then from */etc/mkinitfs*.
## /usr/share/mkinitfs/files, /etc/mkinitfs/files ## /usr/share/mkinitfs/files, /etc/mkinitfs/files
## /usr/share/mkinitfs/files-extra, /etc/mkinitfs/files-extra ## /usr/share/mkinitfs/files-extra, /etc/mkinitfs/files-extra
@@ -99,6 +100,9 @@ create/manage. mkinitfs reads configuration from */usr/share/mkinitfs* first, an
path(s) under the relevant directory in */etc/mkinitfs*, and changing path(s) under the relevant directory in */etc/mkinitfs*, and changing
the destination path. the destination path.
Any lines in these files that start with *#* are considered comments, and
skipped.
## /usr/share/mkinitfs/hooks, /etc/mkinitfs/hooks ## /usr/share/mkinitfs/hooks, /etc/mkinitfs/hooks
## /usr/share/mkinitfs/hooks-extra*, /etc/mkinitfs/hooks-extra ## /usr/share/mkinitfs/hooks-extra*, /etc/mkinitfs/hooks-extra
@@ -120,12 +124,18 @@ create/manage. mkinitfs reads configuration from */usr/share/mkinitfs* first, an
Modules are installed in the initramfs archive under the same path they Modules are installed in the initramfs archive under the same path they
exist on the system where mkinitfs is executed. exist on the system where mkinitfs is executed.
Any lines in these files that start with *#* are considered comments, and
skipped.
## /usr/share/mkinitfs/dirs, /etc/mkinitfs/dirs ## /usr/share/mkinitfs/dirs, /etc/mkinitfs/dirs
Files with the *.dirs* extension in these directories are lists of Files with the *.dirs* extension in these directories are lists of
directories to create within the initramfs. There is no *-extra* variant, directories to create within the initramfs. There is no *-extra* variant,
since directories are of negligible size. since directories are of negligible size.
Any lines in these files that start with *#* are considered comments, and
skipped.
# BOOT-DEPLOY # BOOT-DEPLOY
After generating archives, mkinitfs will execute *boot-deploy*, using *$PATH* to After generating archives, mkinitfs will execute *boot-deploy*, using *$PATH* to
@@ -136,7 +146,7 @@ search for the app. The following commandline options are passed to it:
Currently this is hardcoded to be "initramfs" Currently this is hardcoded to be "initramfs"
*-k* <kernel filename> *-k* <kernel filename>
*-d* <work directory> *-d* <work directory>
Path to the directory containing the build artifacts from mkinitfs. Path to the directory containing the build artifacts from mkinitfs.

1
go.mod
View File

@@ -5,6 +5,7 @@ go 1.20
require ( require (
github.com/cavaliercoder/go-cpio v0.0.0-20180626203310-925f9528c45e github.com/cavaliercoder/go-cpio v0.0.0-20180626203310-925f9528c45e
github.com/klauspost/compress v1.15.12 github.com/klauspost/compress v1.15.12
github.com/pierrec/lz4/v4 v4.1.17
github.com/ulikunitz/xz v0.5.10 github.com/ulikunitz/xz v0.5.10
golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c
) )

2
go.sum
View File

@@ -2,6 +2,8 @@ github.com/cavaliercoder/go-cpio v0.0.0-20180626203310-925f9528c45e h1:hHg27A0RS
github.com/cavaliercoder/go-cpio v0.0.0-20180626203310-925f9528c45e/go.mod h1:oDpT4efm8tSYHXV5tHSdRvBet/b/QzxZ+XyyPehvm3A= github.com/cavaliercoder/go-cpio v0.0.0-20180626203310-925f9528c45e/go.mod h1:oDpT4efm8tSYHXV5tHSdRvBet/b/QzxZ+XyyPehvm3A=
github.com/klauspost/compress v1.15.12 h1:YClS/PImqYbn+UILDnqxQCZ3RehC9N318SU3kElDUEM= github.com/klauspost/compress v1.15.12 h1:YClS/PImqYbn+UILDnqxQCZ3RehC9N318SU3kElDUEM=
github.com/klauspost/compress v1.15.12/go.mod h1:QPwzmACJjUTFsnSHH934V6woptycfrDDJnH7hvFVbGM= github.com/klauspost/compress v1.15.12/go.mod h1:QPwzmACJjUTFsnSHH934V6woptycfrDDJnH7hvFVbGM=
github.com/pierrec/lz4/v4 v4.1.17 h1:kV4Ip+/hUBC+8T6+2EgburRtkE9ef4nbY3f4dFhGjMc=
github.com/pierrec/lz4/v4 v4.1.17/go.mod h1:gZWDp/Ze/IJXGXf23ltt2EXimqmTUXEy0GFuRQyBid4=
github.com/ulikunitz/xz v0.5.10 h1:t92gobL9l3HE202wg3rlk19F6X+JOxl9BBrCCMYEYd8= github.com/ulikunitz/xz v0.5.10 h1:t92gobL9l3HE202wg3rlk19F6X+JOxl9BBrCCMYEYd8=
github.com/ulikunitz/xz v0.5.10/go.mod h1:nbz6k7qbPmH4IRqmfOplQw/tblSgqTqBwxkY0oWt/14= github.com/ulikunitz/xz v0.5.10/go.mod h1:nbz6k7qbPmH4IRqmfOplQw/tblSgqTqBwxkY0oWt/14=
golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c h1:F1jZWGFhYfh0Ci55sIpILtKKK8p3i2/krTr0H1rg74I= golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c h1:F1jZWGFhYfh0Ci55sIpILtKKK8p3i2/krTr0H1rg74I=

View File

@@ -18,6 +18,7 @@ import (
"github.com/cavaliercoder/go-cpio" "github.com/cavaliercoder/go-cpio"
"github.com/klauspost/compress/zstd" "github.com/klauspost/compress/zstd"
"github.com/pierrec/lz4/v4"
"github.com/ulikunitz/xz" "github.com/ulikunitz/xz"
"gitlab.com/postmarketOS/postmarketos-mkinitfs/internal/filelist" "gitlab.com/postmarketOS/postmarketos-mkinitfs/internal/filelist"
"gitlab.com/postmarketOS/postmarketos-mkinitfs/internal/osutil" "gitlab.com/postmarketOS/postmarketos-mkinitfs/internal/osutil"
@@ -28,6 +29,7 @@ type CompressFormat string
const ( const (
FormatGzip CompressFormat = "gzip" FormatGzip CompressFormat = "gzip"
FormatLzma CompressFormat = "lzma" FormatLzma CompressFormat = "lzma"
FormatLz4 CompressFormat = "lz4"
FormatZstd CompressFormat = "zstd" FormatZstd CompressFormat = "zstd"
FormatNone CompressFormat = "none" FormatNone CompressFormat = "none"
) )
@@ -104,6 +106,7 @@ func ExtractFormatLevel(s string) (format CompressFormat, level CompressLevel) {
case FormatLzma: case FormatLzma:
log.Println("Format lzma doesn't support a compression level, using default settings") log.Println("Format lzma doesn't support a compression level, using default settings")
level = LevelDefault level = LevelDefault
case FormatLz4:
case FormatNone: case FormatNone:
case FormatZstd: case FormatZstd:
default: default:
@@ -200,6 +203,38 @@ func (archive *Archive) AddItems(flister filelist.FileLister) error {
return nil return nil
} }
// AddItemsExclude is like AddItems, but takes a second FileLister that lists
// items that should not be added to the archive from the first FileLister
func (archive *Archive) AddItemsExclude(flister filelist.FileLister, exclude filelist.FileLister) error {
list, err := flister.List()
if err != nil {
return err
}
excludeList, err := exclude.List()
if err != nil {
return err
}
for i := range list.IterItems() {
dest, found := excludeList.Get(i.Source)
if found {
if i.Dest != dest {
found = false
}
}
if !found {
if err := archive.AddItem(i.Source, i.Dest); err != nil {
return err
}
}
}
return nil
}
// Adds the given file or directory at "source" to the archive at "dest" // Adds the given file or directory at "source" to the archive at "dest"
func (archive *Archive) AddItem(source string, dest string) error { func (archive *Archive) AddItem(source string, dest string) error {
@@ -316,6 +351,23 @@ func (archive *Archive) writeCompressed(path string, mode os.FileMode) (err erro
if err != nil { if err != nil {
return err return err
} }
case FormatLz4:
// The default compression for the lz4 library is Fast, and
// they don't define a Default level otherwise
level := lz4.Fast
switch archive.compress_level {
case LevelBest:
level = lz4.Level9
case LevelFast:
level = lz4.Fast
}
var writer = lz4.NewWriter(fd)
err = writer.Apply(lz4.LegacyOption(true), lz4.CompressionLevelOption(level))
if err != nil {
return err
}
compressor = writer
case FormatNone: case FormatNone:
compressor = fd compressor = fd
case FormatZstd: case FormatZstd:

View File

@@ -249,6 +249,12 @@ func TestExtractFormatLevel(t *testing.T) {
expectedFormat: FormatLzma, expectedFormat: FormatLzma,
expectedLevel: LevelDefault, expectedLevel: LevelDefault,
}, },
{
name: "lz4, fast",
in: "lz4:fast",
expectedFormat: FormatLz4,
expectedLevel: LevelFast,
},
{ {
name: "none", name: "none",
in: "none", in: "none",

View File

@@ -1,12 +1,6 @@
package filelist package filelist
import ( import "sync"
"fmt"
"path/filepath"
"sync"
"gitlab.com/postmarketOS/postmarketos-mkinitfs/internal/misc"
)
type FileLister interface { type FileLister interface {
List() (*FileList, error) List() (*FileList, error)
@@ -51,26 +45,6 @@ func (f *FileList) Import(src *FileList) {
} }
} }
func (f *FileList) AddGlobbed(src string, dest string) error {
fFiles, err := misc.GetFiles([]string{src}, true)
if err != nil {
return fmt.Errorf("unable to add %q: %w", src, err)
}
// loop over all returned files from GetFile
for _, file := range fFiles {
if len(fFiles) > 1 {
// Glob with arbitrary subdirectories, so we need to
// remove the src path and prepend the dest path
f.Add(file, filepath.Join(dest, file[len(src):]))
} else {
// dest path specified, and only 1 file
f.Add(file, dest)
}
}
return nil
}
// iterate through the list and and send each one as a new File over the // iterate through the list and and send each one as a new File over the
// returned channel // returned channel
func (f *FileList) IterItems() <-chan File { func (f *FileList) IterItems() <-chan File {

View File

@@ -6,6 +6,7 @@ import (
"log" "log"
"os" "os"
"path/filepath" "path/filepath"
"strings"
"gitlab.com/postmarketOS/postmarketos-mkinitfs/internal/filelist" "gitlab.com/postmarketOS/postmarketos-mkinitfs/internal/filelist"
) )
@@ -44,6 +45,10 @@ func (h *HookDirs) List() (*filelist.FileList, error) {
s := bufio.NewScanner(f) s := bufio.NewScanner(f)
for s.Scan() { for s.Scan() {
dir := s.Text() dir := s.Text()
if len(dir) == 0 || strings.HasPrefix(dir, "#") {
continue
}
files.Add(dir, dir) files.Add(dir, dir)
} }
} }

View File

@@ -10,6 +10,7 @@ import (
"strings" "strings"
"gitlab.com/postmarketOS/postmarketos-mkinitfs/internal/filelist" "gitlab.com/postmarketOS/postmarketos-mkinitfs/internal/filelist"
"gitlab.com/postmarketOS/postmarketos-mkinitfs/internal/misc"
) )
type HookFiles struct { type HookFiles struct {
@@ -57,15 +58,29 @@ func slurpFiles(fd io.Reader) (*filelist.FileList, error) {
s := bufio.NewScanner(fd) s := bufio.NewScanner(fd)
for s.Scan() { for s.Scan() {
src, dest, has_dest := strings.Cut(s.Text(), ":") line := s.Text()
if len(line) == 0 || strings.HasPrefix(line, "#") {
if !has_dest { continue
dest = src
} }
err := files.AddGlobbed(src, dest) src, dest, has_dest := strings.Cut(line, ":")
fFiles, err := misc.GetFiles([]string{src}, true)
if err != nil { if err != nil {
return nil, err return nil, fmt.Errorf("unable to add %q: %w", src, err)
}
// loop over all returned files from GetFile
for _, file := range fFiles {
if !has_dest {
files.Add(file, file)
} else if len(fFiles) > 1 {
// Don't support specifying dest if src was a glob
// NOTE: this could support this later...
files.Add(file, file)
} else {
// dest path specified, and only 1 file
files.Add(file, dest)
}
} }
} }

View File

@@ -35,13 +35,8 @@ func (h *HookScripts) List() (*filelist.FileList, error) {
} }
for _, file := range fileInfo { for _, file := range fileInfo {
path := filepath.Join(h.scriptsDir, file.Name()) path := filepath.Join(h.scriptsDir, file.Name())
if file.IsDir() { log.Printf("-- Including script: %s\n", path)
log.Printf("-- Including dir %s\n", path) files.Add(path, filepath.Join(h.destPath, file.Name()))
files.AddGlobbed(filepath.Join(path, "*"), filepath.Join(h.destPath, file.Name()))
} else {
log.Printf("-- Including script: %s\n", path)
files.Add(path, filepath.Join(h.destPath, file.Name()))
}
} }
return files, nil return files, nil
} }

View File

@@ -9,6 +9,7 @@ import (
// combining the output from them. // combining the output from them.
type Initramfs struct { type Initramfs struct {
features []filelist.FileLister features []filelist.FileLister
files *filelist.FileList
} }
// New returns a new Initramfs that generate a list of files based on the given // New returns a new Initramfs that generate a list of files based on the given
@@ -20,15 +21,18 @@ func New(features []filelist.FileLister) *Initramfs {
} }
func (i *Initramfs) List() (*filelist.FileList, error) { func (i *Initramfs) List() (*filelist.FileList, error) {
files := filelist.NewFileList() if i.files != nil {
return i.files, nil
}
i.files = filelist.NewFileList()
for _, f := range i.features { for _, f := range i.features {
list, err := f.List() list, err := f.List()
if err != nil { if err != nil {
return nil, err return nil, err
} }
files.Import(list) i.files.Import(list)
} }
return files, nil return i.files, nil
} }

View File

@@ -95,6 +95,9 @@ func slurpModules(fd io.Reader, modDir string) (*filelist.FileList, error) {
s := bufio.NewScanner(fd) s := bufio.NewScanner(fd)
for s.Scan() { for s.Scan() {
line := s.Text() line := s.Text()
if len(line) == 0 || strings.HasPrefix(line, "#") {
continue
}
dir, file := filepath.Split(line) dir, file := filepath.Split(line)
if file == "" { if file == "" {
// item is a directory // item is a directory
@@ -194,7 +197,12 @@ func getModuleDeps(modName string, modulesDep io.Reader) ([]string, error) {
s := bufio.NewScanner(modulesDep) s := bufio.NewScanner(modulesDep)
for s.Scan() { for s.Scan() {
fields := strings.Fields(s.Text()) line := s.Text()
if len(line) == 0 || strings.HasPrefix(line, "#") {
continue
}
fields := strings.Fields(line)
if len(fields) == 0 { if len(fields) == 0 {
continue continue
} }

View File

@@ -37,6 +37,12 @@ func (s *OskSdl) List() (*filelist.FileList, error) {
log.Println("- Including osk-sdl support") log.Println("- Including osk-sdl support")
log.Println("******************* DEPRECATION WARNING *******************")
log.Println("Using osk-sdl is deprecated in postmarketOS!")
log.Println("Consider switching to unl0kr:")
log.Println("https://postmarketos.org/edge/2023/10/04/osk-sdl-deprecated/")
log.Println("******************* DEPRECATION WARNING *******************")
confFiles := []string{ confFiles := []string{
"/etc/osk.conf", "/etc/osk.conf",
"/etc/ts.conf", "/etc/ts.conf",

View File

@@ -11,6 +11,8 @@ import (
"os" "os"
"reflect" "reflect"
"strings" "strings"
"gitlab.com/postmarketOS/postmarketos-mkinitfs/internal/misc"
) )
type DeviceInfo struct { type DeviceInfo struct {
@@ -21,24 +23,31 @@ type DeviceInfo struct {
UbootBoardname string UbootBoardname string
} }
func ReadDeviceinfo(file string) (DeviceInfo, error) { // Reads the relevant entries from "file" into DeviceInfo struct
var deviceinfo DeviceInfo // Any already-set entries will be overwriten if they are present
// in "file"
func (d *DeviceInfo) ReadDeviceinfo(file string) error {
if exists, err := misc.Exists(file); !exists {
return fmt.Errorf("%q not found, required by mkinitfs", file)
} else if err != nil {
return fmt.Errorf("unexpected error getting status for %q: %s", file, err)
}
fd, err := os.Open(file) fd, err := os.Open(file)
if err != nil { if err != nil {
return deviceinfo, err return err
} }
defer fd.Close() defer fd.Close()
if err := unmarshal(fd, &deviceinfo); err != nil { if err := d.unmarshal(fd); err != nil {
return deviceinfo, err return err
} }
return deviceinfo, nil return nil
} }
// Unmarshals a deviceinfo into a DeviceInfo struct // Unmarshals a deviceinfo into a DeviceInfo struct
func unmarshal(r io.Reader, devinfo *DeviceInfo) error { func (d *DeviceInfo) unmarshal(r io.Reader) error {
s := bufio.NewScanner(r) s := bufio.NewScanner(r)
for s.Scan() { for s.Scan() {
line := s.Text() line := s.Text()
@@ -74,7 +83,7 @@ func unmarshal(r io.Reader, devinfo *DeviceInfo) error {
return fmt.Errorf("error parsing deviceinfo line, invalid format: %s", line) return fmt.Errorf("error parsing deviceinfo line, invalid format: %s", line)
} }
field := reflect.ValueOf(devinfo).Elem().FieldByName(fieldName) field := reflect.ValueOf(d).Elem().FieldByName(fieldName)
if !field.IsValid() { if !field.IsValid() {
// an option that meets the deviceinfo "specification", but isn't // an option that meets the deviceinfo "specification", but isn't
// one we care about in this module // one we care about in this module

View File

@@ -10,6 +10,32 @@ import (
"testing" "testing"
) )
// Test ReadDeviceinfo and the logic of reading from multiple files
func TestReadDeviceinfo(t *testing.T) {
modules_expected := "panfrost foo bar bazz"
mesa_expected := "msm"
var devinfo DeviceInfo
err := devinfo.ReadDeviceinfo("./test_resources/deviceinfo-missing")
if !strings.Contains(err.Error(), "required by mkinitfs") {
t.Errorf("received an unexpected err: %s", err)
}
err = devinfo.ReadDeviceinfo("./test_resources/deviceinfo-first")
if err != nil {
t.Errorf("received an unexpected err: %s", err)
}
err = devinfo.ReadDeviceinfo("./test_resources/deviceinfo-msm")
if err != nil {
t.Errorf("received an unexpected err: %s", err)
}
if devinfo.ModulesInitfs != modules_expected {
t.Errorf("expected %q, got: %q", modules_expected, devinfo.ModulesInitfs)
}
if devinfo.MesaDriver != mesa_expected {
t.Errorf("expected %q, got: %q", mesa_expected, devinfo.MesaDriver)
}
}
// Test conversion of name to DeviceInfo struct field format // Test conversion of name to DeviceInfo struct field format
func TestNameToField(t *testing.T) { func TestNameToField(t *testing.T) {
tables := []struct { tables := []struct {
@@ -58,7 +84,7 @@ func TestUnmarshal(t *testing.T) {
var d DeviceInfo var d DeviceInfo
for _, table := range tables { for _, table := range tables {
testName := fmt.Sprintf("unmarshal::'%s':", strings.ReplaceAll(table.in, "\n", "\\n")) testName := fmt.Sprintf("unmarshal::'%s':", strings.ReplaceAll(table.in, "\n", "\\n"))
if err := unmarshal(strings.NewReader(table.in), &d); err != nil { if err := d.unmarshal(strings.NewReader(table.in)); err != nil {
t.Errorf("%s received an unexpected err: ", err) t.Errorf("%s received an unexpected err: ", err)
} }

View File

@@ -0,0 +1,2 @@
deviceinfo_modules_initfs="panfrost foo bar bazz"
deviceinfo_mesa_driver="panfrost"

View File

@@ -0,0 +1 @@
deviceinfo_mesa_driver="msm"