mirror of
https://github.com/lxc/distrobuilder.git
synced 2026-02-05 06:45:19 +01:00
*: Switch to errors without stack traces
The zap logger includes the verbose output if the error implements the Formatter interface which errors.Error (from the pkg/errors package) does. This includes the stack trace which causes the visible error message to be rather messy. Using fmt.Errorf and errors.New (standard library) solves the problem as these don't implement the Formatter interface. Signed-off-by: Thomas Hipp <thomas.hipp@canonical.com>
This commit is contained in:
@@ -1,11 +1,11 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"os"
|
||||
"path/filepath"
|
||||
|
||||
"github.com/pkg/errors"
|
||||
"go.uber.org/zap"
|
||||
"golang.org/x/sys/unix"
|
||||
)
|
||||
@@ -22,9 +22,9 @@ func getOverlay(logger *zap.SugaredLogger, cacheDir, sourceDir string) (func(),
|
||||
|
||||
switch stat.Type {
|
||||
case unix.XFS_SUPER_MAGIC:
|
||||
return nil, "", errors.Errorf("overlay not supported on xfs")
|
||||
return nil, "", errors.New("overlay not supported on xfs")
|
||||
case 0x2fc12fc1:
|
||||
return nil, "", errors.Errorf("overlay not supported on zfs")
|
||||
return nil, "", errors.New("overlay not supported on zfs")
|
||||
}
|
||||
}
|
||||
|
||||
@@ -34,24 +34,24 @@ func getOverlay(logger *zap.SugaredLogger, cacheDir, sourceDir string) (func(),
|
||||
|
||||
err := os.Mkdir(upperDir, 0755)
|
||||
if err != nil {
|
||||
return nil, "", errors.WithMessagef(err, "Failed to create directory %q", upperDir)
|
||||
return nil, "", fmt.Errorf("Failed to create directory %q: %w", upperDir, err)
|
||||
}
|
||||
|
||||
err = os.Mkdir(overlayDir, 0755)
|
||||
if err != nil {
|
||||
return nil, "", errors.WithMessagef(err, "Failed to create directory %q", overlayDir)
|
||||
return nil, "", fmt.Errorf("Failed to create directory %q: %w", overlayDir, err)
|
||||
}
|
||||
|
||||
err = os.Mkdir(workDir, 0755)
|
||||
if err != nil {
|
||||
return nil, "", errors.WithMessagef(err, "Failed to create directory %q", workDir)
|
||||
return nil, "", fmt.Errorf("Failed to create directory %q: %w", workDir, err)
|
||||
}
|
||||
|
||||
opts := fmt.Sprintf("lowerdir=%s,upperdir=%s,workdir=%s", sourceDir, upperDir, workDir)
|
||||
|
||||
err = unix.Mount("overlay", overlayDir, "overlay", 0, opts)
|
||||
if err != nil {
|
||||
return nil, "", errors.WithMessage(err, "Failed to mount overlay")
|
||||
return nil, "", fmt.Errorf("Failed to mount overlay: %w", err)
|
||||
}
|
||||
|
||||
cleanup := func() {
|
||||
|
||||
@@ -54,6 +54,7 @@ import "C"
|
||||
import (
|
||||
"bufio"
|
||||
"bytes"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
@@ -64,7 +65,6 @@ import (
|
||||
"time"
|
||||
|
||||
lxd "github.com/lxc/lxd/shared"
|
||||
"github.com/pkg/errors"
|
||||
"github.com/spf13/cobra"
|
||||
"go.uber.org/zap"
|
||||
"gopkg.in/yaml.v2"
|
||||
@@ -242,7 +242,7 @@ func (c *cmdGlobal) preRunBuild(cmd *cobra.Command, args []string) error {
|
||||
// Create and set target directory if provided
|
||||
err := os.MkdirAll(args[1], 0755)
|
||||
if err != nil {
|
||||
return errors.WithMessagef(err, "Failed to create directory %q", args[1])
|
||||
return fmt.Errorf("Failed to create directory %q: %w", args[1], err)
|
||||
}
|
||||
c.targetDir = args[1]
|
||||
} else {
|
||||
@@ -250,7 +250,7 @@ func (c *cmdGlobal) preRunBuild(cmd *cobra.Command, args []string) error {
|
||||
var err error
|
||||
c.targetDir, err = os.Getwd()
|
||||
if err != nil {
|
||||
return errors.WithMessage(err, "Failed to get working directory")
|
||||
return fmt.Errorf("Failed to get working directory: %w", err)
|
||||
}
|
||||
}
|
||||
if isRunningBuildDir {
|
||||
@@ -262,20 +262,20 @@ func (c *cmdGlobal) preRunBuild(cmd *cobra.Command, args []string) error {
|
||||
// Create source directory if it doesn't exist
|
||||
err := os.MkdirAll(c.sourceDir, 0755)
|
||||
if err != nil {
|
||||
return errors.WithMessagef(err, "Failed to create directory %q", c.sourceDir)
|
||||
return fmt.Errorf("Failed to create directory %q: %w", c.sourceDir, err)
|
||||
}
|
||||
|
||||
// Get the image definition
|
||||
c.definition, err = getDefinition(args[0], c.flagOptions)
|
||||
if err != nil {
|
||||
return errors.WithMessage(err, "Failed to get definition")
|
||||
return fmt.Errorf("Failed to get definition: %w", err)
|
||||
}
|
||||
|
||||
// Create cache directory if we also plan on creating LXC or LXD images
|
||||
if !isRunningBuildDir {
|
||||
err = os.MkdirAll(c.flagCacheDir, 0755)
|
||||
if err != nil {
|
||||
return errors.WithMessagef(err, "Failed to create directory %q", c.flagCacheDir)
|
||||
return fmt.Errorf("Failed to create directory %q: %w", c.flagCacheDir, err)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -283,33 +283,33 @@ func (c *cmdGlobal) preRunBuild(cmd *cobra.Command, args []string) error {
|
||||
for i, key := range c.definition.Source.Keys {
|
||||
c.definition.Source.Keys[i], err = shared.RenderTemplate(key, c.definition)
|
||||
if err != nil {
|
||||
return errors.WithMessage(err, "Failed to render source keys")
|
||||
return fmt.Errorf("Failed to render source keys: %w", err)
|
||||
}
|
||||
}
|
||||
|
||||
// Run template on source URL
|
||||
c.definition.Source.URL, err = shared.RenderTemplate(c.definition.Source.URL, c.definition)
|
||||
if err != nil {
|
||||
return errors.WithMessage(err, "Failed to render source URL")
|
||||
return fmt.Errorf("Failed to render source URL: %w", err)
|
||||
}
|
||||
|
||||
// Load and run downloader
|
||||
downloader, err := sources.Load(c.definition.Source.Downloader, c.logger, *c.definition, c.sourceDir, c.flagCacheDir)
|
||||
if err != nil {
|
||||
return errors.WithMessagef(err, "Failed to load downloader %q", c.definition.Source.Downloader)
|
||||
return fmt.Errorf("Failed to load downloader %q: %w", c.definition.Source.Downloader, err)
|
||||
}
|
||||
|
||||
c.logger.Info("Downloading source")
|
||||
|
||||
err = downloader.Run()
|
||||
if err != nil {
|
||||
return errors.WithMessage(err, "Error while downloading source")
|
||||
return fmt.Errorf("Error while downloading source: %w", err)
|
||||
}
|
||||
|
||||
// Setup the mounts and chroot into the rootfs
|
||||
exitChroot, err := shared.SetupChroot(c.sourceDir, c.definition.Environment, nil)
|
||||
if err != nil {
|
||||
return errors.WithMessage(err, "Failed to setup chroot")
|
||||
return fmt.Errorf("Failed to setup chroot: %w", err)
|
||||
}
|
||||
// Unmount everything and exit the chroot
|
||||
defer exitChroot()
|
||||
@@ -333,7 +333,7 @@ func (c *cmdGlobal) preRunBuild(cmd *cobra.Command, args []string) error {
|
||||
// running build-lxd.
|
||||
ok, err := cmd.Flags().GetBool("vm")
|
||||
if err != nil {
|
||||
return errors.WithMessagef(err, `Failed to get bool value of "vm"`)
|
||||
return fmt.Errorf(`Failed to get bool value of "vm": %w`, err)
|
||||
}
|
||||
|
||||
if ok {
|
||||
@@ -346,14 +346,14 @@ func (c *cmdGlobal) preRunBuild(cmd *cobra.Command, args []string) error {
|
||||
|
||||
manager, err := managers.Load(c.definition.Packages.Manager, c.logger, *c.definition)
|
||||
if err != nil {
|
||||
return errors.WithMessagef(err, "Failed to load manager %q", c.definition.Packages.Manager)
|
||||
return fmt.Errorf("Failed to load manager %q: %w", c.definition.Packages.Manager, err)
|
||||
}
|
||||
|
||||
c.logger.Info("Managing repositories")
|
||||
|
||||
err = manager.ManageRepositories(imageTargets)
|
||||
if err != nil {
|
||||
return errors.WithMessage(err, "Failed to manage repositories")
|
||||
return fmt.Errorf("Failed to manage repositories: %w", err)
|
||||
}
|
||||
|
||||
c.logger.Infow("Running hooks", "trigger", "post-unpack")
|
||||
@@ -362,7 +362,7 @@ func (c *cmdGlobal) preRunBuild(cmd *cobra.Command, args []string) error {
|
||||
for _, hook := range c.definition.GetRunnableActions("post-unpack", imageTargets) {
|
||||
err := shared.RunScript(hook.Action)
|
||||
if err != nil {
|
||||
return errors.WithMessage(err, "Failed to run post-unpack")
|
||||
return fmt.Errorf("Failed to run post-unpack: %w", err)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -371,7 +371,7 @@ func (c *cmdGlobal) preRunBuild(cmd *cobra.Command, args []string) error {
|
||||
// Install/remove/update packages
|
||||
err = manager.ManagePackages(imageTargets)
|
||||
if err != nil {
|
||||
return errors.WithMessage(err, "Failed to manage packages")
|
||||
return fmt.Errorf("Failed to manage packages: %w", err)
|
||||
}
|
||||
|
||||
c.logger.Infow("Running hooks", "trigger", "post-packages")
|
||||
@@ -380,7 +380,7 @@ func (c *cmdGlobal) preRunBuild(cmd *cobra.Command, args []string) error {
|
||||
for _, hook := range c.definition.GetRunnableActions("post-packages", imageTargets) {
|
||||
err := shared.RunScript(hook.Action)
|
||||
if err != nil {
|
||||
return errors.WithMessage(err, "Failed to run post-packages")
|
||||
return fmt.Errorf("Failed to run post-packages: %w", err)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -400,7 +400,7 @@ func (c *cmdGlobal) preRunPack(cmd *cobra.Command, args []string) error {
|
||||
// resolve path
|
||||
c.sourceDir, err = filepath.Abs(args[1])
|
||||
if err != nil {
|
||||
return errors.WithMessagef(err, "Failed to get absolute path of %q", args[1])
|
||||
return fmt.Errorf("Failed to get absolute path of %q: %w", args[1], err)
|
||||
}
|
||||
|
||||
c.targetDir = "."
|
||||
@@ -411,7 +411,7 @@ func (c *cmdGlobal) preRunPack(cmd *cobra.Command, args []string) error {
|
||||
// Get the image definition
|
||||
c.definition, err = getDefinition(args[0], c.flagOptions)
|
||||
if err != nil {
|
||||
return errors.WithMessage(err, "Failed to get definition")
|
||||
return fmt.Errorf("Failed to get definition: %w", err)
|
||||
}
|
||||
|
||||
return nil
|
||||
@@ -458,7 +458,7 @@ func (c *cmdGlobal) getOverlayDir() (string, func(), error) {
|
||||
// Use rsync if overlay doesn't work
|
||||
err = shared.RsyncLocal(c.sourceDir+"/", overlayDir)
|
||||
if err != nil {
|
||||
return "", nil, errors.WithMessage(err, "Failed to copy image content")
|
||||
return "", nil, fmt.Errorf("Failed to copy image content: %w", err)
|
||||
}
|
||||
} else {
|
||||
cleanup, overlayDir, err = getOverlay(c.logger, c.flagCacheDir, c.sourceDir)
|
||||
@@ -470,7 +470,7 @@ func (c *cmdGlobal) getOverlayDir() (string, func(), error) {
|
||||
// Use rsync if overlay doesn't work
|
||||
err = shared.RsyncLocal(c.sourceDir+"/", overlayDir)
|
||||
if err != nil {
|
||||
return "", nil, errors.WithMessage(err, "Failed to copy image content")
|
||||
return "", nil, fmt.Errorf("Failed to copy image content: %w", err)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -515,7 +515,7 @@ func getDefinition(fname string, options []string) (*shared.Definition, error) {
|
||||
|
||||
err := def.SetValue(parts[0], parts[1])
|
||||
if err != nil {
|
||||
return nil, errors.WithMessagef(err, "Failed to set option %s", o)
|
||||
return nil, fmt.Errorf("Failed to set option %s: %w", o, err)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"github.com/pkg/errors"
|
||||
"fmt"
|
||||
|
||||
"github.com/spf13/cobra"
|
||||
|
||||
"github.com/lxc/distrobuilder/generators"
|
||||
@@ -28,7 +29,7 @@ func (c *cmdBuildDir) command() *cobra.Command {
|
||||
|
||||
generator, err := generators.Load(file.Generator, c.global.logger, c.global.flagCacheDir, c.global.targetDir, file)
|
||||
if err != nil {
|
||||
return errors.WithMessagef(err, "Failed to load generator %q", file.Generator)
|
||||
return fmt.Errorf("Failed to load generator %q: %w", file.Generator, err)
|
||||
}
|
||||
|
||||
c.global.logger.Infow("Running generator", "generator", file.Generator)
|
||||
|
||||
@@ -3,7 +3,6 @@ package main
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/pkg/errors"
|
||||
"github.com/spf13/cobra"
|
||||
|
||||
"github.com/lxc/distrobuilder/generators"
|
||||
@@ -33,7 +32,7 @@ func (c *cmdLXC) commandBuild() *cobra.Command {
|
||||
RunE: func(cmd *cobra.Command, args []string) error {
|
||||
overlayDir, cleanup, err := c.global.getOverlayDir()
|
||||
if err != nil {
|
||||
return errors.WithMessage(err, "Failed to get overlay directory")
|
||||
return fmt.Errorf("Failed to get overlay directory: %w", err)
|
||||
}
|
||||
|
||||
if cleanup != nil {
|
||||
@@ -67,7 +66,7 @@ func (c *cmdLXC) commandPack() *cobra.Command {
|
||||
RunE: func(cmd *cobra.Command, args []string) error {
|
||||
overlayDir, cleanup, err := c.global.getOverlayDir()
|
||||
if err != nil {
|
||||
return errors.WithMessage(err, "Failed to get overlay directory")
|
||||
return fmt.Errorf("Failed to get overlay directory: %w", err)
|
||||
}
|
||||
|
||||
if cleanup != nil {
|
||||
@@ -81,7 +80,7 @@ func (c *cmdLXC) commandPack() *cobra.Command {
|
||||
|
||||
err = c.runPack(cmd, args, overlayDir)
|
||||
if err != nil {
|
||||
return errors.WithMessage(err, "Failed to pack image")
|
||||
return fmt.Errorf("Failed to pack image: %w", err)
|
||||
}
|
||||
|
||||
return c.run(cmd, args, overlayDir)
|
||||
@@ -97,7 +96,7 @@ func (c *cmdLXC) runPack(cmd *cobra.Command, args []string, overlayDir string) e
|
||||
// Setup the mounts and chroot into the rootfs
|
||||
exitChroot, err := shared.SetupChroot(overlayDir, c.global.definition.Environment, nil)
|
||||
if err != nil {
|
||||
return errors.WithMessage(err, "Failed to setup chroot")
|
||||
return fmt.Errorf("Failed to setup chroot: %w", err)
|
||||
}
|
||||
// Unmount everything and exit the chroot
|
||||
defer exitChroot()
|
||||
@@ -106,14 +105,14 @@ func (c *cmdLXC) runPack(cmd *cobra.Command, args []string, overlayDir string) e
|
||||
|
||||
manager, err := managers.Load(c.global.definition.Packages.Manager, c.global.logger, *c.global.definition)
|
||||
if err != nil {
|
||||
return errors.WithMessagef(err, "Failed to load manager %q", c.global.definition.Packages.Manager)
|
||||
return fmt.Errorf("Failed to load manager %q: %w", c.global.definition.Packages.Manager, err)
|
||||
}
|
||||
|
||||
c.global.logger.Info("Managing repositories")
|
||||
|
||||
err = manager.ManageRepositories(imageTargets)
|
||||
if err != nil {
|
||||
return errors.WithMessage(err, "Failed to manage repositories")
|
||||
return fmt.Errorf("Failed to manage repositories: %w", err)
|
||||
}
|
||||
|
||||
c.global.logger.Infow("Running hooks", "trigger", "post-unpack")
|
||||
@@ -122,7 +121,7 @@ func (c *cmdLXC) runPack(cmd *cobra.Command, args []string, overlayDir string) e
|
||||
for _, hook := range c.global.definition.GetRunnableActions("post-unpack", imageTargets) {
|
||||
err := shared.RunScript(hook.Action)
|
||||
if err != nil {
|
||||
return errors.WithMessage(err, "Failed to run post-unpack")
|
||||
return fmt.Errorf("Failed to run post-unpack: %w", err)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -131,7 +130,7 @@ func (c *cmdLXC) runPack(cmd *cobra.Command, args []string, overlayDir string) e
|
||||
// Install/remove/update packages
|
||||
err = manager.ManagePackages(imageTargets)
|
||||
if err != nil {
|
||||
return errors.WithMessage(err, "Failed to manage packages")
|
||||
return fmt.Errorf("Failed to manage packages: %w", err)
|
||||
}
|
||||
|
||||
c.global.logger.Infow("Running hooks", "trigger", "post-packages")
|
||||
@@ -140,7 +139,7 @@ func (c *cmdLXC) runPack(cmd *cobra.Command, args []string, overlayDir string) e
|
||||
for _, hook := range c.global.definition.GetRunnableActions("post-packages", imageTargets) {
|
||||
err := shared.RunScript(hook.Action)
|
||||
if err != nil {
|
||||
return errors.WithMessage(err, "Failed to run post-packages")
|
||||
return fmt.Errorf("Failed to run post-packages: %w", err)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -159,21 +158,21 @@ func (c *cmdLXC) run(cmd *cobra.Command, args []string, overlayDir string) error
|
||||
|
||||
generator, err := generators.Load(file.Generator, c.global.logger, c.global.flagCacheDir, overlayDir, file)
|
||||
if err != nil {
|
||||
return errors.WithMessagef(err, "Failed to load generator %q", file.Generator)
|
||||
return fmt.Errorf("Failed to load generator %q: %w", file.Generator, err)
|
||||
}
|
||||
|
||||
c.global.logger.Infow("Running generator", "generator", file.Generator)
|
||||
|
||||
err = generator.RunLXC(img, c.global.definition.Targets.LXC)
|
||||
if err != nil {
|
||||
return errors.WithMessagef(err, "Failed to run generator %q", file.Generator)
|
||||
return fmt.Errorf("Failed to run generator %q: %w", file.Generator, err)
|
||||
}
|
||||
}
|
||||
|
||||
exitChroot, err := shared.SetupChroot(overlayDir,
|
||||
c.global.definition.Environment, nil)
|
||||
if err != nil {
|
||||
return errors.WithMessagef(err, "Failed to setup chroot in %q", overlayDir)
|
||||
return fmt.Errorf("Failed to setup chroot in %q: %w", overlayDir, err)
|
||||
}
|
||||
|
||||
addSystemdGenerator()
|
||||
@@ -185,7 +184,7 @@ func (c *cmdLXC) run(cmd *cobra.Command, args []string, overlayDir string) error
|
||||
err := shared.RunScript(action.Action)
|
||||
if err != nil {
|
||||
exitChroot()
|
||||
return errors.WithMessage(err, "Failed to run post-files")
|
||||
return fmt.Errorf("Failed to run post-files: %w", err)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -193,7 +192,7 @@ func (c *cmdLXC) run(cmd *cobra.Command, args []string, overlayDir string) error
|
||||
|
||||
err = img.Build(c.flagCompression)
|
||||
if err != nil {
|
||||
return errors.WithMessage(err, "Failed to create LXC image")
|
||||
return fmt.Errorf("Failed to create LXC image: %w", err)
|
||||
}
|
||||
|
||||
return nil
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"os"
|
||||
"os/exec"
|
||||
"path/filepath"
|
||||
|
||||
lxd "github.com/lxc/lxd/shared"
|
||||
"github.com/pkg/errors"
|
||||
"github.com/spf13/cobra"
|
||||
"golang.org/x/sys/unix"
|
||||
|
||||
@@ -47,7 +47,7 @@ func (c *cmdLXD) commandBuild() *cobra.Command {
|
||||
if c.flagVM {
|
||||
err := c.checkVMDependencies()
|
||||
if err != nil {
|
||||
return errors.WithMessage(err, "Failed to check VM dependencies")
|
||||
return fmt.Errorf("Failed to check VM dependencies: %w", err)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -56,7 +56,7 @@ func (c *cmdLXD) commandBuild() *cobra.Command {
|
||||
RunE: func(cmd *cobra.Command, args []string) error {
|
||||
overlayDir, cleanup, err := c.global.getOverlayDir()
|
||||
if err != nil {
|
||||
return errors.WithMessage(err, "Failed to get overlay directory")
|
||||
return fmt.Errorf("Failed to get overlay directory: %w", err)
|
||||
}
|
||||
|
||||
if cleanup != nil {
|
||||
@@ -99,7 +99,7 @@ func (c *cmdLXD) commandPack() *cobra.Command {
|
||||
if c.flagVM {
|
||||
err := c.checkVMDependencies()
|
||||
if err != nil {
|
||||
return errors.WithMessage(err, "Failed to check VM dependencies")
|
||||
return fmt.Errorf("Failed to check VM dependencies: %w", err)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -108,7 +108,7 @@ func (c *cmdLXD) commandPack() *cobra.Command {
|
||||
RunE: func(cmd *cobra.Command, args []string) error {
|
||||
overlayDir, cleanup, err := c.global.getOverlayDir()
|
||||
if err != nil {
|
||||
return errors.WithMessage(err, "Failed to get overlay directory")
|
||||
return fmt.Errorf("Failed to get overlay directory: %w", err)
|
||||
}
|
||||
|
||||
if cleanup != nil {
|
||||
@@ -126,7 +126,7 @@ func (c *cmdLXD) commandPack() *cobra.Command {
|
||||
|
||||
err = c.runPack(cmd, args, overlayDir)
|
||||
if err != nil {
|
||||
return errors.WithMessage(err, "Failed to pack image")
|
||||
return fmt.Errorf("Failed to pack image: %w", err)
|
||||
}
|
||||
|
||||
return c.run(cmd, args, overlayDir)
|
||||
@@ -144,7 +144,7 @@ func (c *cmdLXD) runPack(cmd *cobra.Command, args []string, overlayDir string) e
|
||||
// Setup the mounts and chroot into the rootfs
|
||||
exitChroot, err := shared.SetupChroot(overlayDir, c.global.definition.Environment, nil)
|
||||
if err != nil {
|
||||
return errors.WithMessagef(err, "Failed to setup chroot")
|
||||
return fmt.Errorf("Failed to setup chroot: %w", err)
|
||||
}
|
||||
// Unmount everything and exit the chroot
|
||||
defer exitChroot()
|
||||
@@ -159,14 +159,14 @@ func (c *cmdLXD) runPack(cmd *cobra.Command, args []string, overlayDir string) e
|
||||
|
||||
manager, err := managers.Load(c.global.definition.Packages.Manager, c.global.logger, *c.global.definition)
|
||||
if err != nil {
|
||||
return errors.WithMessagef(err, "Failed to load manager %q", c.global.definition.Packages.Manager)
|
||||
return fmt.Errorf("Failed to load manager %q: %w", c.global.definition.Packages.Manager, err)
|
||||
}
|
||||
|
||||
c.global.logger.Info("Managing repositories")
|
||||
|
||||
err = manager.ManageRepositories(imageTargets)
|
||||
if err != nil {
|
||||
return errors.WithMessage(err, "Failed to manage repositories")
|
||||
return fmt.Errorf("Failed to manage repositories: %w", err)
|
||||
}
|
||||
|
||||
c.global.logger.Infow("Running hooks", "trigger", "post-unpack")
|
||||
@@ -175,7 +175,7 @@ func (c *cmdLXD) runPack(cmd *cobra.Command, args []string, overlayDir string) e
|
||||
for _, hook := range c.global.definition.GetRunnableActions("post-unpack", imageTargets) {
|
||||
err := shared.RunScript(hook.Action)
|
||||
if err != nil {
|
||||
return errors.WithMessage(err, "Failed to run post-unpack")
|
||||
return fmt.Errorf("Failed to run post-unpack: %w", err)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -184,7 +184,7 @@ func (c *cmdLXD) runPack(cmd *cobra.Command, args []string, overlayDir string) e
|
||||
// Install/remove/update packages
|
||||
err = manager.ManagePackages(imageTargets)
|
||||
if err != nil {
|
||||
return errors.WithMessage(err, "Failed to manage packages")
|
||||
return fmt.Errorf("Failed to manage packages: %w", err)
|
||||
}
|
||||
|
||||
c.global.logger.Info("Running hooks", "trigger", "post-packages")
|
||||
@@ -193,7 +193,7 @@ func (c *cmdLXD) runPack(cmd *cobra.Command, args []string, overlayDir string) e
|
||||
for _, hook := range c.global.definition.GetRunnableActions("post-packages", imageTargets) {
|
||||
err := shared.RunScript(hook.Action)
|
||||
if err != nil {
|
||||
return errors.WithMessage(err, "Failed to run post-packages")
|
||||
return fmt.Errorf("Failed to run post-packages: %w", err)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -219,14 +219,14 @@ func (c *cmdLXD) run(cmd *cobra.Command, args []string, overlayDir string) error
|
||||
|
||||
generator, err := generators.Load(file.Generator, c.global.logger, c.global.flagCacheDir, overlayDir, file)
|
||||
if err != nil {
|
||||
return errors.WithMessagef(err, "Failed to load generator %q", file.Generator)
|
||||
return fmt.Errorf("Failed to load generator %q: %w", file.Generator, err)
|
||||
}
|
||||
|
||||
c.global.logger.Infow("Running generator", "generator", file.Generator)
|
||||
|
||||
err = generator.RunLXD(img, c.global.definition.Targets.LXD)
|
||||
if err != nil {
|
||||
return errors.WithMessage(err, "Failed to create LXD data")
|
||||
return fmt.Errorf("Failed to create LXD data: %w", err)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -240,63 +240,63 @@ func (c *cmdLXD) run(cmd *cobra.Command, args []string, overlayDir string) error
|
||||
|
||||
err := os.Mkdir(vmDir, 0755)
|
||||
if err != nil {
|
||||
return errors.WithMessagef(err, "Failed to create directory %q", vmDir)
|
||||
return fmt.Errorf("Failed to create directory %q: %w", vmDir, err)
|
||||
}
|
||||
|
||||
imgFilename, err := shared.RenderTemplate(fmt.Sprintf("%s.raw", c.global.definition.Image.Name), c.global.definition)
|
||||
if err != nil {
|
||||
return errors.WithMessage(err, "Failed to render template")
|
||||
return fmt.Errorf("Failed to render template: %w", err)
|
||||
}
|
||||
|
||||
imgFile := filepath.Join(c.global.flagCacheDir, imgFilename)
|
||||
|
||||
vm, err = newVM(imgFile, vmDir, c.global.definition.Targets.LXD.VM.Filesystem, c.global.definition.Targets.LXD.VM.Size)
|
||||
if err != nil {
|
||||
return errors.WithMessage(err, "Failed to instanciate VM")
|
||||
return fmt.Errorf("Failed to instanciate VM: %w", err)
|
||||
}
|
||||
|
||||
err = vm.createEmptyDiskImage()
|
||||
if err != nil {
|
||||
return errors.WithMessage(err, "Failed to create disk image")
|
||||
return fmt.Errorf("Failed to create disk image: %w", err)
|
||||
}
|
||||
|
||||
err = vm.createPartitions()
|
||||
if err != nil {
|
||||
return errors.WithMessage(err, "Failed to create partitions")
|
||||
return fmt.Errorf("Failed to create partitions: %w", err)
|
||||
}
|
||||
|
||||
err = vm.mountImage()
|
||||
if err != nil {
|
||||
return errors.WithMessage(err, "Failed to mount image")
|
||||
return fmt.Errorf("Failed to mount image: %w", err)
|
||||
}
|
||||
defer vm.umountImage()
|
||||
|
||||
err = vm.createRootFS()
|
||||
if err != nil {
|
||||
return errors.WithMessage(err, "Failed to create root filesystem")
|
||||
return fmt.Errorf("Failed to create root filesystem: %w", err)
|
||||
}
|
||||
|
||||
err = vm.mountRootPartition()
|
||||
if err != nil {
|
||||
return errors.WithMessage(err, "failed to mount root partion")
|
||||
return fmt.Errorf("failed to mount root partion: %w", err)
|
||||
}
|
||||
defer lxd.RunCommand("umount", "-R", vmDir)
|
||||
|
||||
err = vm.createUEFIFS()
|
||||
if err != nil {
|
||||
return errors.WithMessage(err, "Failed to create UEFI filesystem")
|
||||
return fmt.Errorf("Failed to create UEFI filesystem: %w", err)
|
||||
}
|
||||
|
||||
err = vm.mountUEFIPartition()
|
||||
if err != nil {
|
||||
return errors.WithMessage(err, "Failed to mount UEFI partition")
|
||||
return fmt.Errorf("Failed to mount UEFI partition: %w", err)
|
||||
}
|
||||
|
||||
// We cannot use LXD's rsync package as that uses the --delete flag which
|
||||
// causes an issue due to the boot/efi directory being present.
|
||||
err = shared.RsyncLocal(overlayDir+"/", vmDir)
|
||||
if err != nil {
|
||||
return errors.WithMessage(err, "Failed to copy rootfs")
|
||||
return fmt.Errorf("Failed to copy rootfs: %w", err)
|
||||
}
|
||||
|
||||
rootfsDir = vmDir
|
||||
@@ -331,7 +331,7 @@ func (c *cmdLXD) run(cmd *cobra.Command, args []string, overlayDir string) error
|
||||
exitChroot, err := shared.SetupChroot(rootfsDir,
|
||||
c.global.definition.Environment, mounts)
|
||||
if err != nil {
|
||||
return errors.WithMessage(err, "Failed to chroot")
|
||||
return fmt.Errorf("Failed to chroot: %w", err)
|
||||
}
|
||||
|
||||
addSystemdGenerator()
|
||||
@@ -343,7 +343,7 @@ func (c *cmdLXD) run(cmd *cobra.Command, args []string, overlayDir string) error
|
||||
err := shared.RunScript(action.Action)
|
||||
if err != nil {
|
||||
exitChroot()
|
||||
return errors.WithMessage(err, "Failed to run post-files")
|
||||
return fmt.Errorf("Failed to run post-files: %w", err)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -353,18 +353,18 @@ func (c *cmdLXD) run(cmd *cobra.Command, args []string, overlayDir string) error
|
||||
if c.flagVM {
|
||||
_, err := lxd.RunCommand("umount", "-R", vmDir)
|
||||
if err != nil {
|
||||
return errors.WithMessagef(err, "Failed to unmount %q", vmDir)
|
||||
return fmt.Errorf("Failed to unmount %q: %w", vmDir, err)
|
||||
}
|
||||
|
||||
err = vm.umountImage()
|
||||
if err != nil {
|
||||
return errors.WithMessage(err, "Failed to unmount image")
|
||||
return fmt.Errorf("Failed to unmount image: %w", err)
|
||||
}
|
||||
}
|
||||
|
||||
err = img.Build(c.flagType == "unified", c.flagCompression, c.flagVM)
|
||||
if err != nil {
|
||||
return errors.WithMessage(err, "Failed to create LXD image")
|
||||
return fmt.Errorf("Failed to create LXD image: %w", err)
|
||||
}
|
||||
|
||||
return nil
|
||||
@@ -376,7 +376,7 @@ func (c *cmdLXD) checkVMDependencies() error {
|
||||
for _, dep := range dependencies {
|
||||
_, err := exec.LookPath(dep)
|
||||
if err != nil {
|
||||
return errors.Errorf("Required tool %q is missing", dep)
|
||||
return fmt.Errorf("Required tool %q is missing", dep)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -4,6 +4,7 @@ import (
|
||||
"bufio"
|
||||
"bytes"
|
||||
"encoding/hex"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"net/http"
|
||||
@@ -16,7 +17,6 @@ import (
|
||||
|
||||
"github.com/flosch/pongo2"
|
||||
lxd "github.com/lxc/lxd/shared"
|
||||
"github.com/pkg/errors"
|
||||
"github.com/spf13/cobra"
|
||||
"golang.org/x/sys/unix"
|
||||
|
||||
@@ -70,7 +70,7 @@ func (c *cmdRepackWindows) command() *cobra.Command {
|
||||
|
||||
overlayDir, cleanup, err := c.global.getOverlayDir()
|
||||
if err != nil {
|
||||
return errors.WithMessage(err, "Failed to get overlay directory")
|
||||
return fmt.Errorf("Failed to get overlay directory: %w", err)
|
||||
}
|
||||
|
||||
if cleanup != nil {
|
||||
@@ -100,7 +100,7 @@ func (c *cmdRepackWindows) preRun(cmd *cobra.Command, args []string) error {
|
||||
detectedVersion := detectWindowsVersion(filepath.Base(args[0]))
|
||||
|
||||
if detectedVersion == "" {
|
||||
return errors.Errorf("Failed to detect Windows version. Please provide the version using the --windows-version flag")
|
||||
return errors.New("Failed to detect Windows version. Please provide the version using the --windows-version flag")
|
||||
}
|
||||
|
||||
c.flagWindowsVersion = detectedVersion
|
||||
@@ -108,7 +108,7 @@ func (c *cmdRepackWindows) preRun(cmd *cobra.Command, args []string) error {
|
||||
supportedVersions := []string{"w11", "w10", "2k19", "2k12", "2k16", "2k22"}
|
||||
|
||||
if !lxd.StringInSlice(c.flagWindowsVersion, supportedVersions) {
|
||||
return errors.Errorf("Version must be one of %v", supportedVersions)
|
||||
return fmt.Errorf("Version must be one of %v", supportedVersions)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -125,7 +125,7 @@ func (c *cmdRepackWindows) preRun(cmd *cobra.Command, args []string) error {
|
||||
// Check dependencies
|
||||
err := c.checkDependencies()
|
||||
if err != nil {
|
||||
return errors.WithMessage(err, "Failed to check dependencies")
|
||||
return fmt.Errorf("Failed to check dependencies: %w", err)
|
||||
}
|
||||
|
||||
// if an error is returned, disable the usage message
|
||||
@@ -134,14 +134,14 @@ func (c *cmdRepackWindows) preRun(cmd *cobra.Command, args []string) error {
|
||||
// Clean up cache directory before doing anything
|
||||
err = os.RemoveAll(c.global.flagCacheDir)
|
||||
if err != nil {
|
||||
return errors.WithMessagef(err, "Failed to remove directory %q", c.global.flagCacheDir)
|
||||
return fmt.Errorf("Failed to remove directory %q: %w", c.global.flagCacheDir, err)
|
||||
}
|
||||
|
||||
success := false
|
||||
|
||||
err = os.Mkdir(c.global.flagCacheDir, 0755)
|
||||
if err != nil {
|
||||
return errors.WithMessagef(err, "Failed to create directory %q", c.global.flagCacheDir)
|
||||
return fmt.Errorf("Failed to create directory %q: %w", c.global.flagCacheDir, err)
|
||||
}
|
||||
defer func() {
|
||||
if c.global.flagCleanup && !success {
|
||||
@@ -154,7 +154,7 @@ func (c *cmdRepackWindows) preRun(cmd *cobra.Command, args []string) error {
|
||||
// Create source path
|
||||
err = os.MkdirAll(c.global.sourceDir, 0755)
|
||||
if err != nil {
|
||||
return errors.WithMessagef(err, "Failed to create directory %q", c.global.sourceDir)
|
||||
return fmt.Errorf("Failed to create directory %q: %w", c.global.sourceDir, err)
|
||||
}
|
||||
|
||||
logger.Info("Mounting Windows ISO")
|
||||
@@ -162,7 +162,7 @@ func (c *cmdRepackWindows) preRun(cmd *cobra.Command, args []string) error {
|
||||
// Mount ISO
|
||||
_, err = lxd.RunCommand("mount", "-o", "loop", args[0], c.global.sourceDir)
|
||||
if err != nil {
|
||||
return errors.WithMessagef(err, "Failed to mount %q at %q", args[0], c.global.sourceDir)
|
||||
return fmt.Errorf("Failed to mount %q at %q: %w", args[0], c.global.sourceDir, err)
|
||||
}
|
||||
|
||||
success = true
|
||||
@@ -184,12 +184,12 @@ func (c *cmdRepackWindows) run(cmd *cobra.Command, args []string, overlayDir str
|
||||
if !lxd.PathExists(virtioISOPath) {
|
||||
err := os.MkdirAll(filepath.Dir(virtioISOPath), 0755)
|
||||
if err != nil {
|
||||
return errors.WithMessagef(err, "Failed to create directory %q", filepath.Dir(virtioISOPath))
|
||||
return fmt.Errorf("Failed to create directory %q: %w", filepath.Dir(virtioISOPath), err)
|
||||
}
|
||||
|
||||
f, err := os.Create(virtioISOPath)
|
||||
if err != nil {
|
||||
return errors.WithMessagef(err, "Failed to create file %q", virtioISOPath)
|
||||
return fmt.Errorf("Failed to create file %q: %w", virtioISOPath, err)
|
||||
}
|
||||
defer f.Close()
|
||||
|
||||
@@ -199,7 +199,7 @@ func (c *cmdRepackWindows) run(cmd *cobra.Command, args []string, overlayDir str
|
||||
|
||||
_, err = lxd.DownloadFileHash(&client, "", nil, nil, "virtio-win.iso", virtioURL, "", nil, f)
|
||||
if err != nil {
|
||||
return errors.WithMessagef(err, "Failed to download %q", virtioURL)
|
||||
return fmt.Errorf("Failed to download %q: %w", virtioURL, err)
|
||||
}
|
||||
|
||||
f.Close()
|
||||
@@ -209,7 +209,7 @@ func (c *cmdRepackWindows) run(cmd *cobra.Command, args []string, overlayDir str
|
||||
if !lxd.PathExists(driverPath) {
|
||||
err := os.MkdirAll(driverPath, 0755)
|
||||
if err != nil {
|
||||
return errors.WithMessagef(err, "Failed to create directory %q", driverPath)
|
||||
return fmt.Errorf("Failed to create directory %q: %w", driverPath, err)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -218,7 +218,7 @@ func (c *cmdRepackWindows) run(cmd *cobra.Command, args []string, overlayDir str
|
||||
// Mount driver ISO
|
||||
_, err := lxd.RunCommand("mount", "-o", "loop", virtioISOPath, driverPath)
|
||||
if err != nil {
|
||||
return errors.WithMessagef(err, "Failed to mount %q at %q", virtioISOPath, driverPath)
|
||||
return fmt.Errorf("Failed to mount %q at %q: %w", virtioISOPath, driverPath, err)
|
||||
}
|
||||
defer unix.Unmount(driverPath, 0)
|
||||
|
||||
@@ -235,7 +235,7 @@ func (c *cmdRepackWindows) run(cmd *cobra.Command, args []string, overlayDir str
|
||||
|
||||
entries, err = ioutil.ReadDir(sourcesDir)
|
||||
if err != nil {
|
||||
return errors.WithMessagef(err, "Failed to read directory %q", sourcesDir)
|
||||
return fmt.Errorf("Failed to read directory %q: %w", sourcesDir, err)
|
||||
}
|
||||
|
||||
var bootWim string
|
||||
@@ -259,18 +259,18 @@ func (c *cmdRepackWindows) run(cmd *cobra.Command, args []string, overlayDir str
|
||||
}
|
||||
|
||||
if bootWim == "" {
|
||||
return errors.Errorf("Unable to find boot.wim")
|
||||
return errors.New("Unable to find boot.wim")
|
||||
}
|
||||
|
||||
if installWim == "" {
|
||||
return errors.Errorf("Unable to find install.wim")
|
||||
return errors.New("Unable to find install.wim")
|
||||
}
|
||||
|
||||
var buf bytes.Buffer
|
||||
|
||||
err = lxd.RunCommandWithFds(nil, &buf, "wimlib-imagex", "info", installWim)
|
||||
if err != nil {
|
||||
return errors.WithMessage(err, "Failed to retrieve wim file information")
|
||||
return fmt.Errorf("Failed to retrieve wim file information: %w", err)
|
||||
}
|
||||
|
||||
indexes := []int{}
|
||||
@@ -284,7 +284,7 @@ func (c *cmdRepackWindows) run(cmd *cobra.Command, args []string, overlayDir str
|
||||
|
||||
index, err := strconv.Atoi(fields[len(fields)-1])
|
||||
if err != nil {
|
||||
return errors.WithMessage(err, "Failed to determine wim file indexes")
|
||||
return fmt.Errorf("Failed to determine wim file indexes: %w", err)
|
||||
}
|
||||
indexes = append(indexes, index)
|
||||
}
|
||||
@@ -293,14 +293,14 @@ func (c *cmdRepackWindows) run(cmd *cobra.Command, args []string, overlayDir str
|
||||
// This injects the drivers into the installation process
|
||||
err = c.modifyWim(bootWim, 2)
|
||||
if err != nil {
|
||||
return errors.WithMessagef(err, "Failed to modify index 2 of %q", filepath.Base(bootWim))
|
||||
return fmt.Errorf("Failed to modify index 2 of %q: %w", filepath.Base(bootWim), err)
|
||||
}
|
||||
|
||||
// This injects the drivers into the final OS
|
||||
for _, idx := range indexes {
|
||||
err = c.modifyWim(installWim, idx)
|
||||
if err != nil {
|
||||
return errors.WithMessagef(err, "Failed to modify index %d of %q", idx, filepath.Base(installWim))
|
||||
return fmt.Errorf("Failed to modify index %d of %q: %w", idx, filepath.Base(installWim), err)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -308,7 +308,7 @@ func (c *cmdRepackWindows) run(cmd *cobra.Command, args []string, overlayDir str
|
||||
|
||||
stdout, err := lxd.RunCommand("genisoimage", "--version")
|
||||
if err != nil {
|
||||
return errors.WithMessage(err, "Failed to determine version of genisoimage")
|
||||
return fmt.Errorf("Failed to determine version of genisoimage: %w", err)
|
||||
}
|
||||
|
||||
version := strings.Split(stdout, "\n")[0]
|
||||
@@ -319,7 +319,7 @@ func (c *cmdRepackWindows) run(cmd *cobra.Command, args []string, overlayDir str
|
||||
_, err = lxd.RunCommand("genisoimage", "--allow-limited-size", "-l", "-no-emul-boot", "-b", "efi/microsoft/boot/efisys.bin", "-o", args[1], overlayDir)
|
||||
}
|
||||
if err != nil {
|
||||
return errors.WithMessage(err, "Failed to generate ISO")
|
||||
return fmt.Errorf("Failed to generate ISO: %w", err)
|
||||
}
|
||||
|
||||
return nil
|
||||
@@ -335,7 +335,7 @@ func (c *cmdRepackWindows) modifyWim(path string, index int) error {
|
||||
if !lxd.PathExists(wimPath) {
|
||||
err := os.MkdirAll(wimPath, 0755)
|
||||
if err != nil {
|
||||
return errors.WithMessagef(err, "Failed to create directory %q", wimPath)
|
||||
return fmt.Errorf("Failed to create directory %q: %w", wimPath, err)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -343,7 +343,7 @@ func (c *cmdRepackWindows) modifyWim(path string, index int) error {
|
||||
|
||||
_, err := lxd.RunCommand("wimlib-imagex", "mountrw", wimFile, strconv.Itoa(index), wimPath, "--allow-other")
|
||||
if err != nil {
|
||||
return errors.WithMessagef(err, "Failed to mount %q", filepath.Base(wimFile))
|
||||
return fmt.Errorf("Failed to mount %q: %w", filepath.Base(wimFile), err)
|
||||
}
|
||||
defer func() {
|
||||
if !success {
|
||||
@@ -353,23 +353,23 @@ func (c *cmdRepackWindows) modifyWim(path string, index int) error {
|
||||
|
||||
dirs, err := c.getWindowsDirectories(wimPath)
|
||||
if err != nil {
|
||||
return errors.WithMessage(err, "Failed to get required windows directories")
|
||||
return fmt.Errorf("Failed to get required windows directories: %w", err)
|
||||
}
|
||||
|
||||
if dirs["filerepository"] == "" {
|
||||
return errors.Errorf("Failed to determine windows/system32/driverstore/filerepository path")
|
||||
return errors.New("Failed to determine windows/system32/driverstore/filerepository path")
|
||||
}
|
||||
|
||||
if dirs["inf"] == "" {
|
||||
return errors.Errorf("Failed to determine windows/inf path")
|
||||
return errors.New("Failed to determine windows/inf path")
|
||||
}
|
||||
|
||||
if dirs["config"] == "" {
|
||||
return errors.Errorf("Failed to determine windows/system32/config path")
|
||||
return errors.New("Failed to determine windows/system32/config path")
|
||||
}
|
||||
|
||||
if dirs["drivers"] == "" {
|
||||
return errors.Errorf("Failed to determine windows/system32/drivers path")
|
||||
return errors.New("Failed to determine windows/system32/drivers path")
|
||||
}
|
||||
|
||||
logger.Infow("Modifying WIM file", "file", filepath.Base(path), "index", index)
|
||||
@@ -377,12 +377,12 @@ func (c *cmdRepackWindows) modifyWim(path string, index int) error {
|
||||
// Create registry entries and copy files
|
||||
err = c.injectDrivers(dirs)
|
||||
if err != nil {
|
||||
return errors.WithMessage(err, "Failed to inject drivers")
|
||||
return fmt.Errorf("Failed to inject drivers: %w", err)
|
||||
}
|
||||
|
||||
_, err = lxd.RunCommand("wimlib-imagex", "unmount", wimPath, "--commit")
|
||||
if err != nil {
|
||||
return errors.WithMessage(err, "Failed to unmount WIM image")
|
||||
return fmt.Errorf("Failed to unmount WIM image: %w", err)
|
||||
}
|
||||
|
||||
success = true
|
||||
@@ -395,7 +395,7 @@ func (c *cmdRepackWindows) checkDependencies() error {
|
||||
for _, dep := range dependencies {
|
||||
_, err := exec.LookPath(dep)
|
||||
if err != nil {
|
||||
return errors.Errorf("Required tool %q is missing", dep)
|
||||
return fmt.Errorf("Required tool %q is missing", dep)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -522,7 +522,7 @@ func (c *cmdRepackWindows) injectDrivers(dirs map[string]string) error {
|
||||
if !lxd.PathExists(targetBasePath) {
|
||||
err := os.MkdirAll(targetBasePath, 0755)
|
||||
if err != nil {
|
||||
return errors.WithMessagef(err, "Failed to create directory %q", targetBasePath)
|
||||
return fmt.Errorf("Failed to create directory %q: %w", targetBasePath, err)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -536,7 +536,7 @@ func (c *cmdRepackWindows) injectDrivers(dirs map[string]string) error {
|
||||
|
||||
err := shared.Copy(path, targetPath)
|
||||
if err != nil {
|
||||
return errors.WithMessagef(err, "Failed to copy %q to %q", filepath.Base(path), targetPath)
|
||||
return fmt.Errorf("Failed to copy %q to %q: %w", filepath.Base(path), targetPath, err)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -547,13 +547,13 @@ func (c *cmdRepackWindows) injectDrivers(dirs map[string]string) error {
|
||||
|
||||
err = shared.Copy(path, target)
|
||||
if err != nil {
|
||||
return errors.WithMessagef(err, "Failed to copy %q to %q", filepath.Base(path), target)
|
||||
return fmt.Errorf("Failed to copy %q to %q: %w", filepath.Base(path), target, err)
|
||||
}
|
||||
|
||||
// Retrieve the ClassGuid which is needed for the Windows registry entries.
|
||||
file, err := os.Open(path)
|
||||
if err != nil {
|
||||
return errors.WithMessagef(err, "Failed to open %s", path)
|
||||
return fmt.Errorf("Failed to open %s: %w", path, err)
|
||||
}
|
||||
|
||||
re := regexp.MustCompile(`(?i)^ClassGuid[ ]*=[ ]*(.+)$`)
|
||||
@@ -571,7 +571,7 @@ func (c *cmdRepackWindows) injectDrivers(dirs map[string]string) error {
|
||||
|
||||
_, ok := ctx["classGuid"]
|
||||
if !ok {
|
||||
return errors.Errorf("Failed to determine classGUID for driver %q", driver)
|
||||
return fmt.Errorf("Failed to determine classGUID for driver %q", driver)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -582,26 +582,26 @@ func (c *cmdRepackWindows) injectDrivers(dirs map[string]string) error {
|
||||
|
||||
err = shared.Copy(path, target)
|
||||
if err != nil {
|
||||
return errors.WithMessagef(err, "Failed to copy %q to %q", filepath.Base(path), target)
|
||||
return fmt.Errorf("Failed to copy %q to %q: %w", filepath.Base(path), target, err)
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
})
|
||||
if err != nil {
|
||||
return errors.WithMessage(err, "Failed to copy driver files")
|
||||
return fmt.Errorf("Failed to copy driver files: %w", err)
|
||||
}
|
||||
|
||||
// Update Windows DRIVERS registry
|
||||
if info.DriversRegistry != "" {
|
||||
tpl, err := pongo2.FromString(info.DriversRegistry)
|
||||
if err != nil {
|
||||
return errors.WithMessagef(err, "Failed to parse template for driver %q", driver)
|
||||
return fmt.Errorf("Failed to parse template for driver %q: %w", driver, err)
|
||||
}
|
||||
|
||||
out, err := tpl.Execute(ctx)
|
||||
if err != nil {
|
||||
return errors.WithMessagef(err, "Failed to render template for driver %q", driver)
|
||||
return fmt.Errorf("Failed to render template for driver %q: %w", driver, err)
|
||||
}
|
||||
|
||||
driversRegistry = fmt.Sprintf("%s\n\n%s", driversRegistry, out)
|
||||
@@ -611,12 +611,12 @@ func (c *cmdRepackWindows) injectDrivers(dirs map[string]string) error {
|
||||
if info.SystemRegistry != "" {
|
||||
tpl, err := pongo2.FromString(info.SystemRegistry)
|
||||
if err != nil {
|
||||
return errors.WithMessagef(err, "Failed to parse template for driver %q", driver)
|
||||
return fmt.Errorf("Failed to parse template for driver %q: %w", driver, err)
|
||||
}
|
||||
|
||||
out, err := tpl.Execute(ctx)
|
||||
if err != nil {
|
||||
return errors.WithMessagef(err, "Failed to render template for driver %q", driver)
|
||||
return fmt.Errorf("Failed to render template for driver %q: %w", driver, err)
|
||||
}
|
||||
|
||||
systemRegistry = fmt.Sprintf("%s\n\n%s", systemRegistry, out)
|
||||
@@ -626,12 +626,12 @@ func (c *cmdRepackWindows) injectDrivers(dirs map[string]string) error {
|
||||
if info.SoftwareRegistry != "" {
|
||||
tpl, err := pongo2.FromString(info.SoftwareRegistry)
|
||||
if err != nil {
|
||||
return errors.WithMessagef(err, "Failed to parse template for driver %q", driver)
|
||||
return fmt.Errorf("Failed to parse template for driver %q: %w", driver, err)
|
||||
}
|
||||
|
||||
out, err := tpl.Execute(ctx)
|
||||
if err != nil {
|
||||
return errors.WithMessagef(err, "Failed to render template for driver %q", driver)
|
||||
return fmt.Errorf("Failed to render template for driver %q: %w", driver, err)
|
||||
}
|
||||
|
||||
softwareRegistry = fmt.Sprintf("%s\n\n%s", softwareRegistry, out)
|
||||
@@ -644,21 +644,21 @@ func (c *cmdRepackWindows) injectDrivers(dirs map[string]string) error {
|
||||
|
||||
err := lxd.RunCommandWithFds(strings.NewReader(driversRegistry), nil, "hivexregedit", "--merge", "--prefix='HKEY_LOCAL_MACHINE\\DRIVERS'", filepath.Join(dirs["config"], "DRIVERS"))
|
||||
if err != nil {
|
||||
return errors.WithMessage(err, "Failed to edit Windows DRIVERS registry")
|
||||
return fmt.Errorf("Failed to edit Windows DRIVERS registry: %w", err)
|
||||
}
|
||||
|
||||
logger.Debugw("Updating Windows registry", "hivefile", "SYSTEM")
|
||||
|
||||
err = lxd.RunCommandWithFds(strings.NewReader(systemRegistry), nil, "hivexregedit", "--merge", "--prefix='HKEY_LOCAL_MACHINE\\SYSTEM'", filepath.Join(dirs["config"], "SYSTEM"))
|
||||
if err != nil {
|
||||
return errors.WithMessage(err, "Failed to edit Windows SYSTEM registry")
|
||||
return fmt.Errorf("Failed to edit Windows SYSTEM registry: %w", err)
|
||||
}
|
||||
|
||||
logger.Debugw("Updating Windows registry", "hivefile", "SOFTWARE")
|
||||
|
||||
err = lxd.RunCommandWithFds(strings.NewReader(softwareRegistry), nil, "hivexregedit", "--merge", "--prefix='HKEY_LOCAL_MACHINE\\SOFTWARE'", filepath.Join(dirs["config"], "SOFTWARE"))
|
||||
if err != nil {
|
||||
return errors.WithMessage(err, "Failed to edit Windows SOFTWARE registry")
|
||||
return fmt.Errorf("Failed to edit Windows SOFTWARE registry: %w", err)
|
||||
}
|
||||
|
||||
return nil
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"os"
|
||||
"path/filepath"
|
||||
@@ -8,7 +9,6 @@ import (
|
||||
"strings"
|
||||
|
||||
lxd "github.com/lxc/lxd/shared"
|
||||
"github.com/pkg/errors"
|
||||
"golang.org/x/sys/unix"
|
||||
|
||||
"github.com/lxc/distrobuilder/shared"
|
||||
@@ -28,7 +28,7 @@ func newVM(imageFile, rootfsDir, fs string, size uint64) (*vm, error) {
|
||||
}
|
||||
|
||||
if !lxd.StringInSlice(fs, []string{"btrfs", "ext4"}) {
|
||||
return nil, errors.Errorf("Unsupported fs: %s", fs)
|
||||
return nil, fmt.Errorf("Unsupported fs: %s", fs)
|
||||
}
|
||||
|
||||
if size == 0 {
|
||||
@@ -61,18 +61,18 @@ func (v *vm) getUEFIDevFile() string {
|
||||
func (v *vm) createEmptyDiskImage() error {
|
||||
f, err := os.Create(v.imageFile)
|
||||
if err != nil {
|
||||
return errors.WithMessagef(err, "Failed to open %s", v.imageFile)
|
||||
return fmt.Errorf("Failed to open %s: %w", v.imageFile, err)
|
||||
}
|
||||
defer f.Close()
|
||||
|
||||
err = f.Chmod(0600)
|
||||
if err != nil {
|
||||
return errors.WithMessagef(err, "Failed to chmod %s", v.imageFile)
|
||||
return fmt.Errorf("Failed to chmod %s: %w", v.imageFile, err)
|
||||
}
|
||||
|
||||
err = f.Truncate(int64(v.size))
|
||||
if err != nil {
|
||||
return errors.WithMessagef(err, "Failed to create sparse file %s", v.imageFile)
|
||||
return fmt.Errorf("Failed to create sparse file %s: %w", v.imageFile, err)
|
||||
}
|
||||
|
||||
return nil
|
||||
@@ -88,7 +88,7 @@ func (v *vm) createPartitions() error {
|
||||
for _, cmd := range args {
|
||||
err := shared.RunCommand("sgdisk", append([]string{v.imageFile}, cmd...)...)
|
||||
if err != nil {
|
||||
return errors.WithMessage(err, "Failed to create partitions")
|
||||
return fmt.Errorf("Failed to create partitions: %w", err)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -103,7 +103,7 @@ func (v *vm) mountImage() error {
|
||||
|
||||
stdout, err := lxd.RunCommand("losetup", "-P", "-f", "--show", v.imageFile)
|
||||
if err != nil {
|
||||
return errors.WithMessage(err, "Failed to setup loop device")
|
||||
return fmt.Errorf("Failed to setup loop device: %w", err)
|
||||
}
|
||||
|
||||
v.loopDevice = strings.TrimSpace(stdout)
|
||||
@@ -113,7 +113,7 @@ func (v *vm) mountImage() error {
|
||||
|
||||
out, err := lxd.RunCommand("lsblk", "--raw", "--output", "MAJ:MIN", "--noheadings", v.loopDevice)
|
||||
if err != nil {
|
||||
return errors.WithMessage(err, "Failed to list block devices")
|
||||
return fmt.Errorf("Failed to list block devices: %w", err)
|
||||
}
|
||||
|
||||
deviceNumbers := strings.Split(out, "\n")
|
||||
@@ -123,19 +123,19 @@ func (v *vm) mountImage() error {
|
||||
|
||||
major, err := strconv.Atoi(fields[0])
|
||||
if err != nil {
|
||||
return errors.WithMessagef(err, "Failed to parse %q", fields[0])
|
||||
return fmt.Errorf("Failed to parse %q: %w", fields[0], err)
|
||||
}
|
||||
|
||||
minor, err := strconv.Atoi(fields[1])
|
||||
if err != nil {
|
||||
return errors.WithMessagef(err, "Failed to parse %q", fields[1])
|
||||
return fmt.Errorf("Failed to parse %q: %w", fields[1], err)
|
||||
}
|
||||
|
||||
dev := unix.Mkdev(uint32(major), uint32(minor))
|
||||
|
||||
err = unix.Mknod(v.getUEFIDevFile(), unix.S_IFBLK|0644, int(dev))
|
||||
if err != nil {
|
||||
return errors.WithMessagef(err, "Failed to create block device %q", v.getUEFIDevFile())
|
||||
return fmt.Errorf("Failed to create block device %q: %w", v.getUEFIDevFile(), err)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -144,19 +144,19 @@ func (v *vm) mountImage() error {
|
||||
|
||||
major, err := strconv.Atoi(fields[0])
|
||||
if err != nil {
|
||||
return errors.WithMessagef(err, "Failed to parse %q", fields[0])
|
||||
return fmt.Errorf("Failed to parse %q: %w", fields[0], err)
|
||||
}
|
||||
|
||||
minor, err := strconv.Atoi(fields[1])
|
||||
if err != nil {
|
||||
return errors.WithMessagef(err, "Failed to parse %q", fields[1])
|
||||
return fmt.Errorf("Failed to parse %q: %w", fields[1], err)
|
||||
}
|
||||
|
||||
dev := unix.Mkdev(uint32(major), uint32(minor))
|
||||
|
||||
err = unix.Mknod(v.getRootfsDevFile(), unix.S_IFBLK|0644, int(dev))
|
||||
if err != nil {
|
||||
return errors.WithMessagef(err, "Failed to create block device %q", v.getRootfsDevFile())
|
||||
return fmt.Errorf("Failed to create block device %q: %w", v.getRootfsDevFile(), err)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -171,21 +171,21 @@ func (v *vm) umountImage() error {
|
||||
|
||||
err := shared.RunCommand("losetup", "-d", v.loopDevice)
|
||||
if err != nil {
|
||||
return errors.WithMessage(err, "Failed to detach loop device")
|
||||
return fmt.Errorf("Failed to detach loop device: %w", err)
|
||||
}
|
||||
|
||||
// Make sure that p1 and p2 are also removed.
|
||||
if lxd.PathExists(v.getUEFIDevFile()) {
|
||||
err := os.Remove(v.getUEFIDevFile())
|
||||
if err != nil {
|
||||
return errors.WithMessagef(err, "Failed to remove file %q", v.getUEFIDevFile())
|
||||
return fmt.Errorf("Failed to remove file %q: %w", v.getUEFIDevFile(), err)
|
||||
}
|
||||
}
|
||||
|
||||
if lxd.PathExists(v.getRootfsDevFile()) {
|
||||
err := os.Remove(v.getRootfsDevFile())
|
||||
if err != nil {
|
||||
return errors.WithMessagef(err, "Failed to remove file %q", v.getRootfsDevFile())
|
||||
return fmt.Errorf("Failed to remove file %q: %w", v.getRootfsDevFile(), err)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -196,20 +196,20 @@ func (v *vm) umountImage() error {
|
||||
|
||||
func (v *vm) createRootFS() error {
|
||||
if v.loopDevice == "" {
|
||||
return errors.Errorf("Disk image not mounted")
|
||||
return errors.New("Disk image not mounted")
|
||||
}
|
||||
|
||||
switch v.rootFS {
|
||||
case "btrfs":
|
||||
err := shared.RunCommand("mkfs.btrfs", "-f", "-L", "rootfs", v.getRootfsDevFile())
|
||||
if err != nil {
|
||||
return errors.WithMessage(err, "Failed to create btrfs filesystem")
|
||||
return fmt.Errorf("Failed to create btrfs filesystem: %w", err)
|
||||
}
|
||||
|
||||
// Create the root subvolume as well
|
||||
err = shared.RunCommand("mount", v.getRootfsDevFile(), v.rootfsDir)
|
||||
if err != nil {
|
||||
return errors.WithMessagef(err, "Failed to mount %q at %q", v.getRootfsDevFile(), v.rootfsDir)
|
||||
return fmt.Errorf("Failed to mount %q at %q: %w", v.getRootfsDevFile(), v.rootfsDir, err)
|
||||
}
|
||||
defer shared.RunCommand("umount", v.rootfsDir)
|
||||
|
||||
@@ -280,7 +280,7 @@ func (v *vm) mountUEFIPartition() error {
|
||||
|
||||
err := os.MkdirAll(mountpoint, 0755)
|
||||
if err != nil {
|
||||
return errors.WithMessagef(err, "Failed to create directory %q", mountpoint)
|
||||
return fmt.Errorf("Failed to create directory %q: %w", mountpoint, err)
|
||||
}
|
||||
|
||||
return shared.RunCommand("mount", v.getUEFIDevFile(), mountpoint)
|
||||
|
||||
@@ -10,7 +10,6 @@ import (
|
||||
"github.com/flosch/pongo2"
|
||||
lxd "github.com/lxc/lxd/shared"
|
||||
"github.com/lxc/lxd/shared/api"
|
||||
"github.com/pkg/errors"
|
||||
|
||||
"github.com/lxc/distrobuilder/image"
|
||||
"github.com/lxc/distrobuilder/shared"
|
||||
@@ -35,14 +34,14 @@ func (g *cloudInit) RunLXC(img *image.LXCImage, target shared.DefinitionTargetLX
|
||||
if lxd.StringInSlice(info.Name(), []string{"cloud-init-local", "cloud-config", "cloud-init", "cloud-final"}) {
|
||||
err := os.Remove(path)
|
||||
if err != nil {
|
||||
return errors.WithMessagef(err, "Failed to remove file %q", path)
|
||||
return fmt.Errorf("Failed to remove file %q: %w", path, err)
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
})
|
||||
if err != nil {
|
||||
return errors.WithMessagef(err, "Failed to walk file tree %q", fullPath)
|
||||
return fmt.Errorf("Failed to walk file tree %q: %w", fullPath, err)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -65,7 +64,7 @@ func (g *cloudInit) RunLXC(img *image.LXCImage, target shared.DefinitionTargetLX
|
||||
if re.MatchString(info.Name()) {
|
||||
err := os.Remove(path)
|
||||
if err != nil {
|
||||
return errors.WithMessagef(err, "Failed to remove file %q", path)
|
||||
return fmt.Errorf("Failed to remove file %q: %w", path, err)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -79,7 +78,7 @@ func (g *cloudInit) RunLXC(img *image.LXCImage, target shared.DefinitionTargetLX
|
||||
if !lxd.PathExists(path) {
|
||||
err := os.MkdirAll(path, 0755)
|
||||
if err != nil {
|
||||
return errors.WithMessagef(err, "Failed to create directory %q", path)
|
||||
return fmt.Errorf("Failed to create directory %q: %w", path, err)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -88,7 +87,7 @@ func (g *cloudInit) RunLXC(img *image.LXCImage, target shared.DefinitionTargetLX
|
||||
|
||||
f, err := os.Create(path)
|
||||
if err != nil {
|
||||
return errors.WithMessagef(err, "Failed to create file %q", path)
|
||||
return fmt.Errorf("Failed to create file %q: %w", path, err)
|
||||
}
|
||||
defer f.Close()
|
||||
|
||||
@@ -101,7 +100,7 @@ func (g *cloudInit) RunLXD(img *image.LXDImage, target shared.DefinitionTargetLX
|
||||
|
||||
err := os.MkdirAll(templateDir, 0755)
|
||||
if err != nil {
|
||||
return errors.WithMessagef(err, "Failed to create directory %q", templateDir)
|
||||
return fmt.Errorf("Failed to create directory %q: %w", templateDir, err)
|
||||
}
|
||||
|
||||
var content string
|
||||
@@ -133,7 +132,7 @@ config:
|
||||
control: auto{% else %}{{ config_get("user.network-config", "") }}{% endif %}
|
||||
`
|
||||
default:
|
||||
return errors.Errorf("Unknown cloud-init configuration: %s", g.defFile.Name)
|
||||
return fmt.Errorf("Unknown cloud-init configuration: %s", g.defFile.Name)
|
||||
}
|
||||
|
||||
template := fmt.Sprintf("cloud-init-%s.tpl", g.defFile.Name)
|
||||
@@ -141,7 +140,7 @@ config:
|
||||
|
||||
file, err := os.Create(path)
|
||||
if err != nil {
|
||||
return errors.WithMessagef(err, "Failed to create file %q", path)
|
||||
return fmt.Errorf("Failed to create file %q: %w", path, err)
|
||||
}
|
||||
|
||||
defer file.Close()
|
||||
@@ -158,18 +157,18 @@ config:
|
||||
if g.defFile.Pongo {
|
||||
tpl, err := pongo2.FromString(content)
|
||||
if err != nil {
|
||||
return errors.WithMessage(err, "Failed to parse template")
|
||||
return fmt.Errorf("Failed to parse template: %w", err)
|
||||
}
|
||||
|
||||
content, err = tpl.Execute(pongo2.Context{"lxd": target})
|
||||
if err != nil {
|
||||
return errors.WithMessage(err, "Failed to execute template")
|
||||
return fmt.Errorf("Failed to execute template: %w", err)
|
||||
}
|
||||
}
|
||||
|
||||
_, err = file.WriteString(content)
|
||||
if err != nil {
|
||||
return errors.WithMessagef(err, "Failed to write to content to %s template", g.defFile.Name)
|
||||
return fmt.Errorf("Failed to write to content to %s template: %w", g.defFile.Name, err)
|
||||
}
|
||||
|
||||
if len(g.defFile.Template.Properties) > 0 {
|
||||
|
||||
@@ -7,8 +7,6 @@ import (
|
||||
"path/filepath"
|
||||
"strings"
|
||||
|
||||
"github.com/pkg/errors"
|
||||
|
||||
"github.com/lxc/distrobuilder/image"
|
||||
"github.com/lxc/distrobuilder/shared"
|
||||
lxd "github.com/lxc/lxd/shared"
|
||||
@@ -46,12 +44,12 @@ func (g *copy) Run() error {
|
||||
|
||||
dirFiles, err := ioutil.ReadDir(filepath.Dir(srcPath))
|
||||
if err != nil {
|
||||
return errors.WithMessagef(err, "Failed to read directory %q", filepath.Dir(srcPath))
|
||||
return fmt.Errorf("Failed to read directory %q: %w", filepath.Dir(srcPath), err)
|
||||
}
|
||||
for _, f := range dirFiles {
|
||||
match, err := filepath.Match(srcPath, filepath.Join(filepath.Dir(srcPath), f.Name()))
|
||||
if err != nil {
|
||||
return errors.WithMessage(err, "Failed to match pattern")
|
||||
return fmt.Errorf("Failed to match pattern: %w", err)
|
||||
}
|
||||
if match {
|
||||
files = append(files, filepath.Join(filepath.Dir(srcPath), f.Name()))
|
||||
@@ -63,7 +61,7 @@ func (g *copy) Run() error {
|
||||
// Look for the literal file
|
||||
_, err = os.Stat(srcPath)
|
||||
if err != nil {
|
||||
return errors.WithMessagef(err, "Failed to stat file %q", srcPath)
|
||||
return fmt.Errorf("Failed to stat file %q: %w", srcPath, err)
|
||||
}
|
||||
err = g.doCopy(srcPath, destPath, g.defFile)
|
||||
case 1:
|
||||
@@ -79,7 +77,7 @@ func (g *copy) Run() error {
|
||||
}
|
||||
}
|
||||
if err != nil {
|
||||
return errors.WithMessage(err, "Failed to copy file(s)")
|
||||
return fmt.Errorf("Failed to copy file(s): %w", err)
|
||||
}
|
||||
|
||||
return nil
|
||||
@@ -88,7 +86,7 @@ func (g *copy) Run() error {
|
||||
func (g *copy) doCopy(srcPath, destPath string, defFile shared.DefinitionFile) error {
|
||||
in, err := os.Stat(srcPath)
|
||||
if err != nil {
|
||||
return errors.WithMessagef(err, "Failed to stat file %q", srcPath)
|
||||
return fmt.Errorf("Failed to stat file %q: %w", srcPath, err)
|
||||
}
|
||||
|
||||
switch in.Mode() & os.ModeType {
|
||||
@@ -99,16 +97,16 @@ func (g *copy) doCopy(srcPath, destPath string, defFile shared.DefinitionFile) e
|
||||
}
|
||||
err := g.copyFile(srcPath, destPath, defFile)
|
||||
if err != nil {
|
||||
return errors.WithMessagef(err, "Failed to copy file %q to %q", srcPath, destPath)
|
||||
return fmt.Errorf("Failed to copy file %q to %q: %w", srcPath, destPath, err)
|
||||
}
|
||||
|
||||
case os.ModeDir:
|
||||
err := g.copyDir(srcPath, destPath, defFile)
|
||||
if err != nil {
|
||||
return errors.WithMessagef(err, "Failed to copy file %q to %q", srcPath, destPath)
|
||||
return fmt.Errorf("Failed to copy file %q to %q: %w", srcPath, destPath, err)
|
||||
}
|
||||
default:
|
||||
return errors.Errorf("File type of %q not supported", srcPath)
|
||||
return fmt.Errorf("File type of %q not supported", srcPath)
|
||||
}
|
||||
|
||||
return nil
|
||||
@@ -122,23 +120,23 @@ func (g *copy) copyDir(srcPath, destPath string, defFile shared.DefinitionFile)
|
||||
|
||||
rel, err := filepath.Rel(srcPath, src)
|
||||
if err != nil {
|
||||
return errors.WithMessagef(err, "Failed to get relative path of %q", srcPath)
|
||||
return fmt.Errorf("Failed to get relative path of %q: %w", srcPath, err)
|
||||
}
|
||||
dest := filepath.Join(destPath, rel)
|
||||
if err != nil {
|
||||
return errors.WithMessage(err, "Failed to join path elements")
|
||||
return fmt.Errorf("Failed to join path elements: %w", err)
|
||||
}
|
||||
|
||||
switch fi.Mode() & os.ModeType {
|
||||
case 0, os.ModeSymlink:
|
||||
err = g.copyFile(src, dest, defFile)
|
||||
if err != nil {
|
||||
return errors.WithMessagef(err, "Failed to copy file %q to %q", src, dest)
|
||||
return fmt.Errorf("Failed to copy file %q to %q: %w", src, dest, err)
|
||||
}
|
||||
case os.ModeDir:
|
||||
err := os.MkdirAll(dest, os.ModePerm)
|
||||
if err != nil {
|
||||
return errors.WithMessagef(err, "Failed to create directory %q", dest)
|
||||
return fmt.Errorf("Failed to create directory %q: %w", dest, err)
|
||||
}
|
||||
default:
|
||||
fmt.Printf("File type of %q not supported, skipping", src)
|
||||
@@ -146,7 +144,7 @@ func (g *copy) copyDir(srcPath, destPath string, defFile shared.DefinitionFile)
|
||||
return nil
|
||||
})
|
||||
if err != nil {
|
||||
return errors.WithMessagef(err, "Failed to walk file tree of %q", srcPath)
|
||||
return fmt.Errorf("Failed to walk file tree of %q: %w", srcPath, err)
|
||||
}
|
||||
|
||||
return nil
|
||||
@@ -160,23 +158,23 @@ func (g *copy) copyFile(src, dest string, defFile shared.DefinitionFile) error {
|
||||
err = os.MkdirAll(dir, os.ModePerm)
|
||||
}
|
||||
if err != nil {
|
||||
return errors.WithMessagef(err, "Failed to create directory %q", dir)
|
||||
return fmt.Errorf("Failed to create directory %q: %w", dir, err)
|
||||
}
|
||||
|
||||
err = lxd.FileCopy(src, dest)
|
||||
if err != nil {
|
||||
return errors.WithMessagef(err, "Failed to copy file %q to %q", src, dest)
|
||||
return fmt.Errorf("Failed to copy file %q to %q: %w", src, dest, err)
|
||||
}
|
||||
|
||||
out, err := os.Open(dest)
|
||||
if err != nil {
|
||||
return errors.WithMessagef(err, "Failed to open file %q", dest)
|
||||
return fmt.Errorf("Failed to open file %q: %w", dest, err)
|
||||
}
|
||||
defer out.Close()
|
||||
|
||||
err = updateFileAccess(out, defFile)
|
||||
if err != nil {
|
||||
return errors.WithMessagef(err, "Failed to update file access of %q", dest)
|
||||
return fmt.Errorf("Failed to update file access of %q: %w", dest, err)
|
||||
}
|
||||
|
||||
return nil
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
package generators
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
|
||||
"github.com/flosch/pongo2"
|
||||
"github.com/pkg/errors"
|
||||
|
||||
"github.com/lxc/distrobuilder/image"
|
||||
"github.com/lxc/distrobuilder/shared"
|
||||
@@ -23,24 +23,24 @@ func (g *dump) RunLXC(img *image.LXCImage, target shared.DefinitionTargetLXC) er
|
||||
if g.defFile.Pongo {
|
||||
tpl, err := pongo2.FromString(g.defFile.Content)
|
||||
if err != nil {
|
||||
return errors.WithMessage(err, "Failed to parse template")
|
||||
return fmt.Errorf("Failed to parse template: %w", err)
|
||||
}
|
||||
|
||||
content, err = tpl.Execute(pongo2.Context{"lxc": target})
|
||||
if err != nil {
|
||||
return errors.WithMessage(err, "Failed to execute template")
|
||||
return fmt.Errorf("Failed to execute template: %w", err)
|
||||
}
|
||||
}
|
||||
|
||||
err := g.run(content)
|
||||
if err != nil {
|
||||
return errors.WithMessage(err, "Failed to dump content")
|
||||
return fmt.Errorf("Failed to dump content: %w", err)
|
||||
}
|
||||
|
||||
if g.defFile.Templated {
|
||||
err = img.AddTemplate(g.defFile.Path)
|
||||
if err != nil {
|
||||
return errors.WithMessage(err, "Failed to add template")
|
||||
return fmt.Errorf("Failed to add template: %w", err)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -54,12 +54,12 @@ func (g *dump) RunLXD(img *image.LXDImage, target shared.DefinitionTargetLXD) er
|
||||
if g.defFile.Pongo {
|
||||
tpl, err := pongo2.FromString(g.defFile.Content)
|
||||
if err != nil {
|
||||
return errors.WithMessage(err, "Failed to parse template")
|
||||
return fmt.Errorf("Failed to parse template: %w", err)
|
||||
}
|
||||
|
||||
content, err = tpl.Execute(pongo2.Context{"lxd": target})
|
||||
if err != nil {
|
||||
return errors.WithMessagef(err, "Failed to execute template")
|
||||
return fmt.Errorf("Failed to execute template: %w", err)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -77,13 +77,13 @@ func (g *dump) run(content string) error {
|
||||
// Create any missing directory
|
||||
err := os.MkdirAll(filepath.Dir(path), 0755)
|
||||
if err != nil {
|
||||
return errors.WithMessagef(err, "Failed to create directory %q", filepath.Dir(path))
|
||||
return fmt.Errorf("Failed to create directory %q: %w", filepath.Dir(path), err)
|
||||
}
|
||||
|
||||
// Open the target file (create if needed)
|
||||
file, err := os.Create(path)
|
||||
if err != nil {
|
||||
return errors.WithMessagef(err, "Failed to create file %q", path)
|
||||
return fmt.Errorf("Failed to create file %q: %w", path, err)
|
||||
}
|
||||
defer file.Close()
|
||||
|
||||
@@ -95,12 +95,12 @@ func (g *dump) run(content string) error {
|
||||
// Write the content
|
||||
_, err = file.WriteString(content)
|
||||
if err != nil {
|
||||
return errors.WithMessagef(err, "Failed to write string to file %q", path)
|
||||
return fmt.Errorf("Failed to write string to file %q: %w", path, err)
|
||||
}
|
||||
|
||||
err = updateFileAccess(file, g.defFile)
|
||||
if err != nil {
|
||||
return errors.WithMessagef(err, "Failed to update file access of %q", path)
|
||||
return fmt.Errorf("Failed to update file access of %q: %w", path, err)
|
||||
}
|
||||
|
||||
return nil
|
||||
|
||||
@@ -1,12 +1,11 @@
|
||||
package generators
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"os"
|
||||
"path/filepath"
|
||||
|
||||
"github.com/pkg/errors"
|
||||
|
||||
"github.com/lxc/distrobuilder/image"
|
||||
"github.com/lxc/distrobuilder/shared"
|
||||
)
|
||||
@@ -24,7 +23,7 @@ func (g *fstab) RunLXC(img *image.LXCImage, target shared.DefinitionTargetLXC) e
|
||||
func (g *fstab) RunLXD(img *image.LXDImage, target shared.DefinitionTargetLXD) error {
|
||||
f, err := os.Create(filepath.Join(g.sourceDir, "etc/fstab"))
|
||||
if err != nil {
|
||||
return errors.WithMessagef(err, "Failed to create file %q", filepath.Join(g.sourceDir, "etc/fstab"))
|
||||
return fmt.Errorf("Failed to create file %q: %w", filepath.Join(g.sourceDir, "etc/fstab"), err)
|
||||
}
|
||||
defer f.Close()
|
||||
|
||||
@@ -46,7 +45,7 @@ LABEL=UEFI /boot/efi vfat defaults 0 0
|
||||
|
||||
_, err = f.WriteString(fmt.Sprintf(content, fs, options))
|
||||
if err != nil {
|
||||
return errors.WithMessagef(err, "Failed to write string to file %q", filepath.Join(g.sourceDir, "etc/fstab"))
|
||||
return fmt.Errorf("Failed to write string to file %q: %w", filepath.Join(g.sourceDir, "etc/fstab"), err)
|
||||
}
|
||||
|
||||
return nil
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
package generators
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
"path/filepath"
|
||||
|
||||
lxd "github.com/lxc/lxd/shared"
|
||||
"github.com/lxc/lxd/shared/api"
|
||||
"github.com/pkg/errors"
|
||||
|
||||
"github.com/lxc/distrobuilder/image"
|
||||
"github.com/lxc/distrobuilder/shared"
|
||||
@@ -27,20 +27,20 @@ func (g *hostname) RunLXC(img *image.LXCImage, target shared.DefinitionTargetLXC
|
||||
// Create new hostname file
|
||||
file, err := os.Create(filepath.Join(g.sourceDir, g.defFile.Path))
|
||||
if err != nil {
|
||||
return errors.WithMessagef(err, "Failed to create file %q", filepath.Join(g.sourceDir, g.defFile.Path))
|
||||
return fmt.Errorf("Failed to create file %q: %w", filepath.Join(g.sourceDir, g.defFile.Path), err)
|
||||
}
|
||||
defer file.Close()
|
||||
|
||||
// Write LXC specific string to the hostname file
|
||||
_, err = file.WriteString("LXC_NAME\n")
|
||||
if err != nil {
|
||||
return errors.WithMessage(err, "Failed to write to hostname file")
|
||||
return fmt.Errorf("Failed to write to hostname file: %w", err)
|
||||
}
|
||||
|
||||
// Add hostname path to LXC's templates file
|
||||
err = img.AddTemplate(g.defFile.Path)
|
||||
if err != nil {
|
||||
return errors.WithMessage(err, "Failed to add template")
|
||||
return fmt.Errorf("Failed to add template: %w", err)
|
||||
}
|
||||
|
||||
return nil
|
||||
@@ -58,18 +58,18 @@ func (g *hostname) RunLXD(img *image.LXDImage, target shared.DefinitionTargetLXD
|
||||
|
||||
err := os.MkdirAll(templateDir, 0755)
|
||||
if err != nil {
|
||||
return errors.WithMessagef(err, "Failed to create directory %q", templateDir)
|
||||
return fmt.Errorf("Failed to create directory %q: %w", templateDir, err)
|
||||
}
|
||||
|
||||
file, err := os.Create(filepath.Join(templateDir, "hostname.tpl"))
|
||||
if err != nil {
|
||||
return errors.WithMessagef(err, "Failed to create file %q", filepath.Join(templateDir, "hostname.tpl"))
|
||||
return fmt.Errorf("Failed to create file %q: %w", filepath.Join(templateDir, "hostname.tpl"), err)
|
||||
}
|
||||
defer file.Close()
|
||||
|
||||
_, err = file.WriteString("{{ container.name }}\n")
|
||||
if err != nil {
|
||||
return errors.WithMessage(err, "Failed to write to hostname file")
|
||||
return fmt.Errorf("Failed to write to hostname file: %w", err)
|
||||
}
|
||||
|
||||
// Add to LXD templates
|
||||
|
||||
@@ -1,13 +1,12 @@
|
||||
package generators
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
|
||||
"github.com/pkg/errors"
|
||||
|
||||
"github.com/lxc/distrobuilder/image"
|
||||
"github.com/lxc/distrobuilder/shared"
|
||||
lxd "github.com/lxc/lxd/shared"
|
||||
@@ -29,7 +28,7 @@ func (g *hosts) RunLXC(img *image.LXCImage, target shared.DefinitionTargetLXC) e
|
||||
// Read the current content
|
||||
content, err := ioutil.ReadFile(filepath.Join(g.sourceDir, g.defFile.Path))
|
||||
if err != nil {
|
||||
return errors.WithMessagef(err, "Failed to read file %q", filepath.Join(g.sourceDir, g.defFile.Path))
|
||||
return fmt.Errorf("Failed to read file %q: %w", filepath.Join(g.sourceDir, g.defFile.Path), err)
|
||||
}
|
||||
|
||||
// Replace hostname with placeholder
|
||||
@@ -42,20 +41,20 @@ func (g *hosts) RunLXC(img *image.LXCImage, target shared.DefinitionTargetLXC) e
|
||||
|
||||
f, err := os.Create(filepath.Join(g.sourceDir, g.defFile.Path))
|
||||
if err != nil {
|
||||
return errors.WithMessagef(err, "Failed to create file %q", filepath.Join(g.sourceDir, g.defFile.Path))
|
||||
return fmt.Errorf("Failed to create file %q: %w", filepath.Join(g.sourceDir, g.defFile.Path), err)
|
||||
}
|
||||
defer f.Close()
|
||||
|
||||
// Overwrite the file
|
||||
_, err = f.Write(content)
|
||||
if err != nil {
|
||||
return errors.WithMessagef(err, "Failed to write to file %q", filepath.Join(g.sourceDir, g.defFile.Path))
|
||||
return fmt.Errorf("Failed to write to file %q: %w", filepath.Join(g.sourceDir, g.defFile.Path), err)
|
||||
}
|
||||
|
||||
// Add hostname path to LXC's templates file
|
||||
err = img.AddTemplate(g.defFile.Path)
|
||||
if err != nil {
|
||||
errors.WithMessage(err, "Failed to add template")
|
||||
return fmt.Errorf("Failed to add template: %w", err)
|
||||
}
|
||||
|
||||
return nil
|
||||
@@ -74,13 +73,13 @@ func (g *hosts) RunLXD(img *image.LXDImage, target shared.DefinitionTargetLXD) e
|
||||
// Create templates path
|
||||
err := os.MkdirAll(templateDir, 0755)
|
||||
if err != nil {
|
||||
return errors.WithMessagef(err, "Failed to create directory %q", templateDir)
|
||||
return fmt.Errorf("Failed to create directory %q: %w", templateDir, err)
|
||||
}
|
||||
|
||||
// Read the current content
|
||||
content, err := ioutil.ReadFile(filepath.Join(g.sourceDir, g.defFile.Path))
|
||||
if err != nil {
|
||||
return errors.WithMessagef(err, "Failed to read file %q", filepath.Join(g.sourceDir, g.defFile.Path))
|
||||
return fmt.Errorf("Failed to read file %q: %w", filepath.Join(g.sourceDir, g.defFile.Path), err)
|
||||
}
|
||||
|
||||
// Replace hostname with placeholder
|
||||
@@ -94,7 +93,7 @@ func (g *hosts) RunLXD(img *image.LXDImage, target shared.DefinitionTargetLXD) e
|
||||
// Write the template
|
||||
err = ioutil.WriteFile(filepath.Join(templateDir, "hosts.tpl"), content, 0644)
|
||||
if err != nil {
|
||||
return errors.WithMessagef(err, "Failed to write file %q", filepath.Join(templateDir, "hosts.tpl"))
|
||||
return fmt.Errorf("Failed to write file %q: %w", filepath.Join(templateDir, "hosts.tpl"), err)
|
||||
}
|
||||
|
||||
img.Metadata.Templates[g.defFile.Path] = &api.ImageMetadataTemplate{
|
||||
|
||||
@@ -2,14 +2,13 @@ package generators
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
|
||||
"github.com/pkg/errors"
|
||||
|
||||
"github.com/lxc/distrobuilder/image"
|
||||
"github.com/lxc/distrobuilder/shared"
|
||||
lxd "github.com/lxc/lxd/shared"
|
||||
@@ -30,13 +29,13 @@ func (g *lxdAgent) RunLXD(img *image.LXDImage, target shared.DefinitionTargetLXD
|
||||
|
||||
fi, err := os.Lstat(initFile)
|
||||
if err != nil {
|
||||
return errors.WithMessagef(err, "Failed to stat file %q", initFile)
|
||||
return fmt.Errorf("Failed to stat file %q: %w", initFile, err)
|
||||
}
|
||||
|
||||
if fi.Mode()&os.ModeSymlink != 0 {
|
||||
linkTarget, err := os.Readlink(initFile)
|
||||
if err != nil {
|
||||
return errors.WithMessagef(err, "Failed to read link %q", initFile)
|
||||
return fmt.Errorf("Failed to read link %q: %w", initFile, err)
|
||||
}
|
||||
|
||||
if strings.Contains(linkTarget, "systemd") {
|
||||
@@ -94,12 +93,12 @@ WantedBy=multi-user.target
|
||||
|
||||
err := ioutil.WriteFile(path, []byte(lxdAgentServiceUnit), 0644)
|
||||
if err != nil {
|
||||
return errors.WithMessagef(err, "Failed to write file %q", path)
|
||||
return fmt.Errorf("Failed to write file %q: %w", path, err)
|
||||
}
|
||||
|
||||
err = os.Symlink(path, filepath.Join(g.sourceDir, "/etc/systemd/system/multi-user.target.wants/lxd-agent.service"))
|
||||
if err != nil {
|
||||
return errors.WithMessagef(err, "Failed to create symlink %q", filepath.Join(g.sourceDir, "/etc/systemd/system/multi-user.target.wants/lxd-agent.service"))
|
||||
return fmt.Errorf("Failed to create symlink %q: %w", filepath.Join(g.sourceDir, "/etc/systemd/system/multi-user.target.wants/lxd-agent.service"), err)
|
||||
}
|
||||
|
||||
lxdAgentSetupScript := `#!/bin/sh
|
||||
@@ -147,7 +146,7 @@ chown -R root:root "${PREFIX}"
|
||||
|
||||
err = ioutil.WriteFile(path, []byte(lxdAgentSetupScript), 0755)
|
||||
if err != nil {
|
||||
return errors.WithMessagef(err, "Failed to write file %q", path)
|
||||
return fmt.Errorf("Failed to write file %q: %w", path, err)
|
||||
}
|
||||
|
||||
udevPath := filepath.Join("/", "lib", "udev", "rules.d")
|
||||
@@ -159,7 +158,7 @@ chown -R root:root "${PREFIX}"
|
||||
lxdAgentRules := `ACTION=="add", SYMLINK=="virtio-ports/org.linuxcontainers.lxd", TAG+="systemd", ACTION=="add", RUN+="/bin/systemctl start lxd-agent.service"`
|
||||
err = ioutil.WriteFile(filepath.Join(g.sourceDir, udevPath, "99-lxd-agent.rules"), []byte(lxdAgentRules), 0400)
|
||||
if err != nil {
|
||||
return errors.WithMessagef(err, "Failed to write file %q", filepath.Join(g.sourceDir, udevPath, "99-lxd-agent.rules"))
|
||||
return fmt.Errorf("Failed to write file %q: %w", filepath.Join(g.sourceDir, udevPath, "99-lxd-agent.rules"), err)
|
||||
}
|
||||
|
||||
return nil
|
||||
@@ -187,12 +186,12 @@ depend() {
|
||||
|
||||
err := ioutil.WriteFile(filepath.Join(g.sourceDir, "/etc/init.d/lxd-agent"), []byte(lxdAgentScript), 0755)
|
||||
if err != nil {
|
||||
return errors.WithMessagef(err, "Failed to write file %q", filepath.Join(g.sourceDir, "/etc/init.d/lxd-agent"))
|
||||
return fmt.Errorf("Failed to write file %q: %w", filepath.Join(g.sourceDir, "/etc/init.d/lxd-agent"), err)
|
||||
}
|
||||
|
||||
err = os.Symlink("/etc/init.d/lxd-agent", filepath.Join(g.sourceDir, "/etc/runlevels/default/lxd-agent"))
|
||||
if err != nil {
|
||||
return errors.WithMessagef(err, "Failed to create symlink %q", filepath.Join(g.sourceDir, "/etc/runlevels/default/lxd-agent"))
|
||||
return fmt.Errorf("Failed to create symlink %q: %w", filepath.Join(g.sourceDir, "/etc/runlevels/default/lxd-agent"), err)
|
||||
}
|
||||
|
||||
lxdConfigShareMountScript := `#!/sbin/openrc-run
|
||||
@@ -213,12 +212,12 @@ start_pre() {
|
||||
|
||||
err = ioutil.WriteFile(filepath.Join(g.sourceDir, "/etc/init.d/lxd-agent-9p"), []byte(lxdConfigShareMountScript), 0755)
|
||||
if err != nil {
|
||||
return errors.WithMessagef(err, "Failed to write file %q", filepath.Join(g.sourceDir, "/etc/init.d/lxd-agent-9p"))
|
||||
return fmt.Errorf("Failed to write file %q: %w", filepath.Join(g.sourceDir, "/etc/init.d/lxd-agent-9p"), err)
|
||||
}
|
||||
|
||||
err = os.Symlink("/etc/init.d/lxd-agent-9p", filepath.Join(g.sourceDir, "/etc/runlevels/default/lxd-agent-9p"))
|
||||
if err != nil {
|
||||
return errors.WithMessagef(err, "Failed to create symlink %q", filepath.Join(g.sourceDir, "/etc/runlevels/default/lxd-agent-9p"))
|
||||
return fmt.Errorf("Failed to create symlink %q: %w", filepath.Join(g.sourceDir, "/etc/runlevels/default/lxd-agent-9p"), err)
|
||||
}
|
||||
|
||||
lxdConfigShareMountVirtioFSScript := `#!/sbin/openrc-run
|
||||
@@ -238,12 +237,12 @@ start_pre() {
|
||||
|
||||
err = ioutil.WriteFile(filepath.Join(g.sourceDir, "/etc/init.d/lxd-agent-virtiofs"), []byte(lxdConfigShareMountVirtioFSScript), 0755)
|
||||
if err != nil {
|
||||
return errors.WithMessagef(err, "Failed to write file %q", filepath.Join(g.sourceDir, "/etc/init.d/lxd-agent-virtiofs"))
|
||||
return fmt.Errorf("Failed to write file %q: %w", filepath.Join(g.sourceDir, "/etc/init.d/lxd-agent-virtiofs"), err)
|
||||
}
|
||||
|
||||
err = os.Symlink("/etc/init.d/lxd-agent-virtiofs", filepath.Join(g.sourceDir, "/etc/runlevels/default/lxd-agent-virtiofs"))
|
||||
if err != nil {
|
||||
return errors.WithMessagef(err, "Failed to create symlink %q", filepath.Join(g.sourceDir, "/etc/runlevels/default/lxd-agent-virtiofs"))
|
||||
return fmt.Errorf("Failed to create symlink %q: %w", filepath.Join(g.sourceDir, "/etc/runlevels/default/lxd-agent-virtiofs"), err)
|
||||
}
|
||||
|
||||
return nil
|
||||
@@ -263,7 +262,7 @@ exec lxd-agent
|
||||
|
||||
err := ioutil.WriteFile(filepath.Join(g.sourceDir, "/etc/init/lxd-agent"), []byte(lxdAgentScript), 0755)
|
||||
if err != nil {
|
||||
return errors.WithMessagef(err, "Failed to write file %q", filepath.Join(g.sourceDir, "/etc/init/lxd-agent"))
|
||||
return fmt.Errorf("Failed to write file %q: %w", filepath.Join(g.sourceDir, "/etc/init/lxd-agent"), err)
|
||||
}
|
||||
|
||||
lxdConfigShareMountScript := `Description "LXD agent 9p mount"
|
||||
@@ -292,7 +291,7 @@ exec mount -t 9p config /run/lxd_config/drive -o access=0,trans=virtio
|
||||
|
||||
err = ioutil.WriteFile(filepath.Join(g.sourceDir, "/etc/init/lxd-agent-9p"), []byte(lxdConfigShareMountScript), 0755)
|
||||
if err != nil {
|
||||
return errors.WithMessagef(err, "Failed to write file %q", filepath.Join(g.sourceDir, "/etc/init/lxd-agent-9p"))
|
||||
return fmt.Errorf("Failed to write file %q: %w", filepath.Join(g.sourceDir, "/etc/init/lxd-agent-9p"), err)
|
||||
}
|
||||
|
||||
lxdConfigShareMountVirtioFSScript := `Description "LXD agent virtio-fs mount"
|
||||
@@ -316,7 +315,7 @@ exec mount -t virtiofs config /run/lxd_config/drive
|
||||
|
||||
err = ioutil.WriteFile(filepath.Join(g.sourceDir, "/etc/init/lxd-agent-virtiofs"), []byte(lxdConfigShareMountVirtioFSScript), 0755)
|
||||
if err != nil {
|
||||
return errors.WithMessagef(err, "Failed to write file %q", filepath.Join(g.sourceDir, "/etc/init/lxd-agent-virtiofs"))
|
||||
return fmt.Errorf("Failed to write file %q: %w", filepath.Join(g.sourceDir, "/etc/init/lxd-agent-virtiofs"), err)
|
||||
}
|
||||
|
||||
return nil
|
||||
@@ -325,7 +324,7 @@ exec mount -t virtiofs config /run/lxd_config/drive
|
||||
func (g *lxdAgent) getInitSystemFromInittab() error {
|
||||
f, err := os.Open(filepath.Join(g.sourceDir, "etc", "inittab"))
|
||||
if err != nil {
|
||||
return errors.WithMessagef(err, "Failed to open file %q", filepath.Join(g.sourceDir, "etc", "inittab"))
|
||||
return fmt.Errorf("Failed to open file %q: %w", filepath.Join(g.sourceDir, "etc", "inittab"), err)
|
||||
}
|
||||
defer f.Close()
|
||||
|
||||
|
||||
@@ -8,7 +8,6 @@ import (
|
||||
|
||||
"github.com/flosch/pongo2"
|
||||
"github.com/lxc/lxd/shared/api"
|
||||
"github.com/pkg/errors"
|
||||
|
||||
"github.com/lxc/distrobuilder/image"
|
||||
"github.com/lxc/distrobuilder/shared"
|
||||
@@ -30,13 +29,13 @@ func (g *template) RunLXD(img *image.LXDImage, target shared.DefinitionTargetLXD
|
||||
|
||||
err := os.MkdirAll(templateDir, 0755)
|
||||
if err != nil {
|
||||
return errors.WithMessagef(err, "Failed to create directory %q", templateDir)
|
||||
return fmt.Errorf("Failed to create directory %q: %w", templateDir, err)
|
||||
}
|
||||
template := fmt.Sprintf("%s.tpl", g.defFile.Name)
|
||||
|
||||
file, err := os.Create(filepath.Join(templateDir, template))
|
||||
if err != nil {
|
||||
return errors.WithMessagef(err, "Failed to create file %q", filepath.Join(templateDir, template))
|
||||
return fmt.Errorf("Failed to create file %q: %w", filepath.Join(templateDir, template), err)
|
||||
}
|
||||
|
||||
defer file.Close()
|
||||
@@ -51,18 +50,18 @@ func (g *template) RunLXD(img *image.LXDImage, target shared.DefinitionTargetLXD
|
||||
if g.defFile.Pongo {
|
||||
tpl, err := pongo2.FromString(content)
|
||||
if err != nil {
|
||||
return errors.WithMessage(err, "Failed to parse template")
|
||||
return fmt.Errorf("Failed to parse template: %w", err)
|
||||
}
|
||||
|
||||
content, err = tpl.Execute(pongo2.Context{"lxd": target})
|
||||
if err != nil {
|
||||
return errors.WithMessagef(err, "Failed to execute template")
|
||||
return fmt.Errorf("Failed to execute template: %w", err)
|
||||
}
|
||||
}
|
||||
|
||||
_, err = file.WriteString(content)
|
||||
if err != nil {
|
||||
return errors.WithMessagef(err, "Failed to write to content to %s template", g.defFile.Name)
|
||||
return fmt.Errorf("Failed to write to content to %s template: %w", g.defFile.Name, err)
|
||||
}
|
||||
|
||||
// Add to LXD templates
|
||||
|
||||
@@ -1,11 +1,10 @@
|
||||
package generators
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
"strconv"
|
||||
|
||||
"github.com/pkg/errors"
|
||||
|
||||
"github.com/lxc/distrobuilder/shared"
|
||||
)
|
||||
|
||||
@@ -14,12 +13,12 @@ func updateFileAccess(file *os.File, defFile shared.DefinitionFile) error {
|
||||
if defFile.Mode != "" {
|
||||
mode, err := strconv.ParseUint(defFile.Mode, 8, 64)
|
||||
if err != nil {
|
||||
return errors.WithMessage(err, "Failed to parse file mode")
|
||||
return fmt.Errorf("Failed to parse file mode: %w", err)
|
||||
}
|
||||
|
||||
err = file.Chmod(os.FileMode(mode))
|
||||
if err != nil {
|
||||
return errors.WithMessage(err, "Failed to change file mode")
|
||||
return fmt.Errorf("Failed to change file mode: %w", err)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -27,12 +26,12 @@ func updateFileAccess(file *os.File, defFile shared.DefinitionFile) error {
|
||||
if defFile.GID != "" {
|
||||
gid, err := strconv.Atoi(defFile.GID)
|
||||
if err != nil {
|
||||
return errors.WithMessage(err, "Failed to parse GID")
|
||||
return fmt.Errorf("Failed to parse GID: %w", err)
|
||||
}
|
||||
|
||||
err = file.Chown(-1, gid)
|
||||
if err != nil {
|
||||
return errors.WithMessage(err, "Failed to change GID")
|
||||
return fmt.Errorf("Failed to change GID: %w", err)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -40,12 +39,12 @@ func updateFileAccess(file *os.File, defFile shared.DefinitionFile) error {
|
||||
if defFile.UID != "" {
|
||||
uid, err := strconv.Atoi(defFile.UID)
|
||||
if err != nil {
|
||||
return errors.WithMessage(err, "Failed to parse UID")
|
||||
return fmt.Errorf("Failed to parse UID: %w", err)
|
||||
}
|
||||
|
||||
err = file.Chown(uid, -1)
|
||||
if err != nil {
|
||||
return errors.WithMessage(err, "Failed to change UID")
|
||||
return fmt.Errorf("Failed to change UID: %w", err)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
41
image/lxc.go
41
image/lxc.go
@@ -8,7 +8,6 @@ import (
|
||||
"time"
|
||||
|
||||
lxd "github.com/lxc/lxd/shared"
|
||||
"github.com/pkg/errors"
|
||||
|
||||
"github.com/lxc/distrobuilder/shared"
|
||||
)
|
||||
@@ -48,13 +47,13 @@ func (l *LXCImage) AddTemplate(path string) error {
|
||||
file, err := os.OpenFile(filepath.Join(metaDir, "templates"),
|
||||
os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644)
|
||||
if err != nil {
|
||||
return errors.WithMessagef(err, "Failed to open file %q", filepath.Join(metaDir, "templates"))
|
||||
return fmt.Errorf("Failed to open file %q: %w", filepath.Join(metaDir, "templates"), err)
|
||||
}
|
||||
defer file.Close()
|
||||
|
||||
_, err = file.WriteString(fmt.Sprintf("%v\n", path))
|
||||
if err != nil {
|
||||
return errors.WithMessage(err, "Failed to write to template file")
|
||||
return fmt.Errorf("Failed to write to template file: %w", err)
|
||||
}
|
||||
|
||||
return nil
|
||||
@@ -64,17 +63,17 @@ func (l *LXCImage) AddTemplate(path string) error {
|
||||
func (l *LXCImage) Build(compression string) error {
|
||||
err := l.createMetadata()
|
||||
if err != nil {
|
||||
return errors.WithMessage(err, "Failed to create metadata")
|
||||
return fmt.Errorf("Failed to create metadata: %w", err)
|
||||
}
|
||||
|
||||
err = l.packMetadata()
|
||||
if err != nil {
|
||||
return errors.WithMessage(err, "Failed to pack metadata")
|
||||
return fmt.Errorf("Failed to pack metadata: %w", err)
|
||||
}
|
||||
|
||||
err = shared.Pack(filepath.Join(l.targetDir, "rootfs.tar"), compression, l.sourceDir, ".")
|
||||
if err != nil {
|
||||
return errors.WithMessagef(err, "Failed to pack %q", filepath.Join(l.targetDir, "rootfs.tar"))
|
||||
return fmt.Errorf("Failed to pack %q: %w", filepath.Join(l.targetDir, "rootfs.tar"), err)
|
||||
}
|
||||
|
||||
return nil
|
||||
@@ -105,22 +104,22 @@ func (l *LXCImage) createMetadata() error {
|
||||
case "all":
|
||||
err := l.writeConfig(i, filepath.Join(metaDir, "config"), c.Content)
|
||||
if err != nil {
|
||||
return errors.WithMessagef(err, "Failed to write config %q", filepath.Join(metaDir, "config"))
|
||||
return fmt.Errorf("Failed to write config %q: %w", filepath.Join(metaDir, "config"), err)
|
||||
}
|
||||
|
||||
err = l.writeConfig(i, filepath.Join(metaDir, "config-user"), c.Content)
|
||||
if err != nil {
|
||||
return errors.WithMessagef(err, "Failed to write config %q", filepath.Join(metaDir, "config-user"))
|
||||
return fmt.Errorf("Failed to write config %q: %w", filepath.Join(metaDir, "config-user"), err)
|
||||
}
|
||||
case "system":
|
||||
err := l.writeConfig(i, filepath.Join(metaDir, "config"), c.Content)
|
||||
if err != nil {
|
||||
return errors.WithMessagef(err, "Failed to write config %q", filepath.Join(metaDir, "config"))
|
||||
return fmt.Errorf("Failed to write config %q: %w", filepath.Join(metaDir, "config"), err)
|
||||
}
|
||||
case "user":
|
||||
err := l.writeConfig(i, filepath.Join(metaDir, "config-user"), c.Content)
|
||||
if err != nil {
|
||||
return errors.WithMessagef(err, "Failed to write config %q", filepath.Join(metaDir, "config-user"))
|
||||
return fmt.Errorf("Failed to write config %q: %w", filepath.Join(metaDir, "config-user"), err)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -129,14 +128,14 @@ func (l *LXCImage) createMetadata() error {
|
||||
err := l.writeMetadata(filepath.Join(metaDir, "create-message"),
|
||||
l.definition.Targets.LXC.CreateMessage, false)
|
||||
if err != nil {
|
||||
return errors.WithMessage(err, "Error writing 'create-message'")
|
||||
return fmt.Errorf("Error writing 'create-message': %w", err)
|
||||
}
|
||||
|
||||
err = l.writeMetadata(filepath.Join(metaDir, "expiry"),
|
||||
fmt.Sprint(shared.GetExpiryDate(time.Now(), l.definition.Image.Expiry).Unix()),
|
||||
false)
|
||||
if err != nil {
|
||||
return errors.WithMessage(err, "Error writing 'expiry'")
|
||||
return fmt.Errorf("Error writing 'expiry': %w", err)
|
||||
}
|
||||
|
||||
var excludesUser string
|
||||
@@ -156,13 +155,13 @@ func (l *LXCImage) createMetadata() error {
|
||||
return nil
|
||||
})
|
||||
if err != nil {
|
||||
return errors.WithMessage(err, "Error while walking /dev")
|
||||
return fmt.Errorf("Error while walking /dev: %w", err)
|
||||
}
|
||||
}
|
||||
|
||||
err = l.writeMetadata(filepath.Join(metaDir, "excludes-user"), excludesUser, false)
|
||||
if err != nil {
|
||||
return errors.WithMessage(err, "Error writing 'excludes-user'")
|
||||
return fmt.Errorf("Error writing 'excludes-user': %w", err)
|
||||
}
|
||||
|
||||
return nil
|
||||
@@ -174,7 +173,7 @@ func (l *LXCImage) packMetadata() error {
|
||||
// Get all config and config-user files
|
||||
configs, err := filepath.Glob(filepath.Join(l.cacheDir, "metadata", "config*"))
|
||||
if err != nil {
|
||||
return errors.WithMessage(err, "Failed to match file pattern")
|
||||
return fmt.Errorf("Failed to match file pattern: %w", err)
|
||||
}
|
||||
|
||||
for _, c := range configs {
|
||||
@@ -188,7 +187,7 @@ func (l *LXCImage) packMetadata() error {
|
||||
err = shared.Pack(filepath.Join(l.targetDir, "meta.tar"), "xz",
|
||||
filepath.Join(l.cacheDir, "metadata"), files...)
|
||||
if err != nil {
|
||||
return errors.WithMessage(err, "Failed to create metadata")
|
||||
return fmt.Errorf("Failed to create metadata: %w", err)
|
||||
}
|
||||
|
||||
return nil
|
||||
@@ -201,19 +200,19 @@ func (l *LXCImage) writeMetadata(filename, content string, appendContent bool) e
|
||||
if appendContent {
|
||||
file, err = os.OpenFile(filename, os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644)
|
||||
if err != nil {
|
||||
return errors.WithMessagef(err, "Failed to open file %q", filename)
|
||||
return fmt.Errorf("Failed to open file %q: %w", filename, err)
|
||||
}
|
||||
} else {
|
||||
file, err = os.Create(filename)
|
||||
if err != nil {
|
||||
return errors.WithMessagef(err, "Failed to create file %q", filename)
|
||||
return fmt.Errorf("Failed to create file %q: %w", filename, err)
|
||||
}
|
||||
}
|
||||
defer file.Close()
|
||||
|
||||
out, err := shared.RenderTemplate(content, l.definition)
|
||||
if err != nil {
|
||||
return errors.WithMessage(err, "Failed to render template")
|
||||
return fmt.Errorf("Failed to render template: %w", err)
|
||||
}
|
||||
|
||||
// Append final new line if missing
|
||||
@@ -224,7 +223,7 @@ func (l *LXCImage) writeMetadata(filename, content string, appendContent bool) e
|
||||
// Write the content
|
||||
_, err = file.WriteString(out)
|
||||
if err != nil {
|
||||
return errors.WithMessage(err, "Failed to write string")
|
||||
return fmt.Errorf("Failed to write string: %w", err)
|
||||
}
|
||||
|
||||
return nil
|
||||
@@ -237,7 +236,7 @@ func (l *LXCImage) writeConfig(compatLevel uint, filename, content string) error
|
||||
}
|
||||
err := l.writeMetadata(filename, content, true)
|
||||
if err != nil {
|
||||
return errors.WithMessagef(err, "Error writing '%s'", filepath.Base(filename))
|
||||
return fmt.Errorf("Error writing '%s': %w", filepath.Base(filename), err)
|
||||
}
|
||||
|
||||
return nil
|
||||
|
||||
25
image/lxd.go
25
image/lxd.go
@@ -7,7 +7,6 @@ import (
|
||||
"time"
|
||||
|
||||
"github.com/lxc/lxd/shared/api"
|
||||
"github.com/pkg/errors"
|
||||
"gopkg.in/yaml.v2"
|
||||
|
||||
"github.com/lxc/distrobuilder/shared"
|
||||
@@ -41,23 +40,23 @@ func NewLXDImage(sourceDir, targetDir, cacheDir string,
|
||||
func (l *LXDImage) Build(unified bool, compression string, vm bool) error {
|
||||
err := l.createMetadata()
|
||||
if err != nil {
|
||||
return errors.WithMessage(err, "Failed to create metadata")
|
||||
return fmt.Errorf("Failed to create metadata: %w", err)
|
||||
}
|
||||
|
||||
file, err := os.Create(filepath.Join(l.cacheDir, "metadata.yaml"))
|
||||
if err != nil {
|
||||
return errors.WithMessage(err, "Failed to create metadata.yaml")
|
||||
return fmt.Errorf("Failed to create metadata.yaml: %w", err)
|
||||
}
|
||||
defer file.Close()
|
||||
|
||||
data, err := yaml.Marshal(l.Metadata)
|
||||
if err != nil {
|
||||
return errors.WithMessage(err, "Failed to marshal yaml")
|
||||
return fmt.Errorf("Failed to marshal yaml: %w", err)
|
||||
}
|
||||
|
||||
_, err = file.Write(data)
|
||||
if err != nil {
|
||||
return errors.WithMessage(err, "Failed to write metadata")
|
||||
return fmt.Errorf("Failed to write metadata: %w", err)
|
||||
}
|
||||
|
||||
paths := []string{"metadata.yaml"}
|
||||
@@ -86,7 +85,7 @@ func (l *LXDImage) Build(unified bool, compression string, vm bool) error {
|
||||
rawImage,
|
||||
qcowImage)
|
||||
if err != nil {
|
||||
return errors.WithMessagef(err, "Failed to create qcow2 image %q", qcowImage)
|
||||
return fmt.Errorf("Failed to create qcow2 image %q: %w", qcowImage, err)
|
||||
}
|
||||
defer func() {
|
||||
os.RemoveAll(rawImage)
|
||||
@@ -100,7 +99,7 @@ func (l *LXDImage) Build(unified bool, compression string, vm bool) error {
|
||||
// Rename image to rootfs.img
|
||||
err = os.Rename(qcowImage, filepath.Join(filepath.Dir(qcowImage), "rootfs.img"))
|
||||
if err != nil {
|
||||
return errors.WithMessagef(err, "Failed to rename image %q -> %q", qcowImage, filepath.Join(filepath.Dir(qcowImage), "rootfs.img"))
|
||||
return fmt.Errorf("Failed to rename image %q -> %q: %w", qcowImage, filepath.Join(filepath.Dir(qcowImage), "rootfs.img"), err)
|
||||
}
|
||||
|
||||
err = shared.Pack(targetTarball, "", l.cacheDir, "rootfs.img")
|
||||
@@ -111,7 +110,7 @@ func (l *LXDImage) Build(unified bool, compression string, vm bool) error {
|
||||
"", l.sourceDir, "--transform", "s,^./,rootfs/,", ".")
|
||||
}
|
||||
if err != nil {
|
||||
return errors.WithMessagef(err, "Failed to pack tarball %q", targetTarball)
|
||||
return fmt.Errorf("Failed to pack tarball %q: %w", targetTarball, err)
|
||||
}
|
||||
defer func() {
|
||||
if vm {
|
||||
@@ -122,7 +121,7 @@ func (l *LXDImage) Build(unified bool, compression string, vm bool) error {
|
||||
// Add the metadata to the tarball which is located in the cache directory
|
||||
err = shared.PackUpdate(targetTarball, compression, l.cacheDir, paths...)
|
||||
if err != nil {
|
||||
return errors.WithMessagef(err, "Failed to add metadata to tarball %q", targetTarball)
|
||||
return fmt.Errorf("Failed to add metadata to tarball %q: %w", targetTarball, err)
|
||||
}
|
||||
} else {
|
||||
if vm {
|
||||
@@ -134,14 +133,14 @@ func (l *LXDImage) Build(unified bool, compression string, vm bool) error {
|
||||
compression, "-b", "1M", "-no-progress", "-no-recovery")
|
||||
}
|
||||
if err != nil {
|
||||
return errors.WithMessage(err, "Failed to create squashfs or copy image")
|
||||
return fmt.Errorf("Failed to create squashfs or copy image: %w", err)
|
||||
}
|
||||
|
||||
// Create metadata tarball.
|
||||
err = shared.Pack(filepath.Join(l.targetDir, "lxd.tar"), compression,
|
||||
l.cacheDir, paths...)
|
||||
if err != nil {
|
||||
return errors.WithMessage(err, "Failed to create metadata tarball")
|
||||
return fmt.Errorf("Failed to create metadata tarball: %w", err)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -162,13 +161,13 @@ func (l *LXDImage) createMetadata() error {
|
||||
l.Metadata.Properties["description"], err = shared.RenderTemplate(
|
||||
l.definition.Image.Description, l.definition)
|
||||
if err != nil {
|
||||
return errors.WithMessage(err, "Failed to render template")
|
||||
return fmt.Errorf("Failed to render template: %w", err)
|
||||
}
|
||||
|
||||
l.Metadata.Properties["name"], err = shared.RenderTemplate(
|
||||
l.definition.Image.Name, l.definition)
|
||||
if err != nil {
|
||||
return errors.WithMessage(err, "Failed to render template")
|
||||
return fmt.Errorf("Failed to render template: %w", err)
|
||||
}
|
||||
|
||||
l.Metadata.ExpiryDate = shared.GetExpiryDate(time.Now(),
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
package managers
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
|
||||
"github.com/lxc/distrobuilder/shared"
|
||||
"github.com/pkg/errors"
|
||||
)
|
||||
|
||||
type apk struct {
|
||||
@@ -46,13 +46,13 @@ func (m *apk) manageRepository(repoAction shared.DefinitionPackagesRepository) e
|
||||
|
||||
f, err := os.OpenFile(repoFile, os.O_WRONLY|os.O_APPEND, 0644)
|
||||
if err != nil {
|
||||
return errors.WithMessagef(err, "Failed to open %q", repoFile)
|
||||
return fmt.Errorf("Failed to open %q: %w", repoFile, err)
|
||||
}
|
||||
defer f.Close()
|
||||
|
||||
_, err = f.WriteString(repoAction.URL + "\n")
|
||||
if err != nil {
|
||||
return errors.WithMessage(err, "Failed to write string to file")
|
||||
return fmt.Errorf("Failed to write string to file: %w", err)
|
||||
}
|
||||
|
||||
return nil
|
||||
|
||||
@@ -10,7 +10,6 @@ import (
|
||||
"strings"
|
||||
|
||||
lxd "github.com/lxc/lxd/shared"
|
||||
"github.com/pkg/errors"
|
||||
|
||||
"github.com/lxc/distrobuilder/shared"
|
||||
)
|
||||
@@ -69,49 +68,49 @@ func (m *apt) manageRepository(repoAction shared.DefinitionPackagesRepository) e
|
||||
if !lxd.PathExists(filepath.Dir(targetFile)) {
|
||||
err := os.MkdirAll(filepath.Dir(targetFile), 0755)
|
||||
if err != nil {
|
||||
return errors.WithMessagef(err, "Failed to create directory %q", filepath.Dir(targetFile))
|
||||
return fmt.Errorf("Failed to create directory %q: %w", filepath.Dir(targetFile), err)
|
||||
}
|
||||
}
|
||||
|
||||
f, err := os.OpenFile(targetFile, os.O_CREATE|os.O_RDWR, 0644)
|
||||
if err != nil {
|
||||
return errors.WithMessagef(err, "Failed to open file %q", targetFile)
|
||||
return fmt.Errorf("Failed to open file %q: %w", targetFile, err)
|
||||
}
|
||||
defer f.Close()
|
||||
|
||||
content, err := ioutil.ReadAll(f)
|
||||
if err != nil {
|
||||
return errors.WithMessagef(err, "Failed to read from file %q", targetFile)
|
||||
return fmt.Errorf("Failed to read from file %q: %w", targetFile, err)
|
||||
}
|
||||
|
||||
// Truncate file if it's not generated by distrobuilder
|
||||
if !strings.HasPrefix(string(content), "# Generated by distrobuilder\n") {
|
||||
err = f.Truncate(0)
|
||||
if err != nil {
|
||||
return errors.WithMessagef(err, "Failed to truncate %q", targetFile)
|
||||
return fmt.Errorf("Failed to truncate %q: %w", targetFile, err)
|
||||
}
|
||||
|
||||
_, err = f.Seek(0, 0)
|
||||
if err != nil {
|
||||
return errors.WithMessagef(err, "Failed to seek on file %q", targetFile)
|
||||
return fmt.Errorf("Failed to seek on file %q: %w", targetFile, err)
|
||||
}
|
||||
|
||||
_, err = f.WriteString("# Generated by distrobuilder\n")
|
||||
if err != nil {
|
||||
return errors.WithMessagef(err, "Failed to write to file %q", targetFile)
|
||||
return fmt.Errorf("Failed to write to file %q: %w", targetFile, err)
|
||||
}
|
||||
}
|
||||
|
||||
_, err = f.WriteString(repoAction.URL)
|
||||
if err != nil {
|
||||
return errors.WithMessagef(err, "Failed to write to file %q", targetFile)
|
||||
return fmt.Errorf("Failed to write to file %q: %w", targetFile, err)
|
||||
}
|
||||
|
||||
// Append final new line if missing
|
||||
if !strings.HasSuffix(repoAction.URL, "\n") {
|
||||
_, err = f.WriteString("\n")
|
||||
if err != nil {
|
||||
return errors.WithMessagef(err, "Failed to write to file %q", targetFile)
|
||||
return fmt.Errorf("Failed to write to file %q: %w", targetFile, err)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -124,14 +123,14 @@ func (m *apt) manageRepository(repoAction shared.DefinitionPackagesRepository) e
|
||||
// If only key ID is provided, we need gpg to be installed early.
|
||||
_, err := lxd.RunCommand("gpg", "--recv-keys", repoAction.Key)
|
||||
if err != nil {
|
||||
return errors.WithMessage(err, "Failed to receive GPG keys")
|
||||
return fmt.Errorf("Failed to receive GPG keys: %w", err)
|
||||
}
|
||||
|
||||
var buf bytes.Buffer
|
||||
|
||||
err = lxd.RunCommandWithFds(nil, &buf, "gpg", "--export", "--armor", repoAction.Key)
|
||||
if err != nil {
|
||||
return errors.WithMessage(err, "Failed to export GPG keys")
|
||||
return fmt.Errorf("Failed to export GPG keys: %w", err)
|
||||
}
|
||||
|
||||
reader = &buf
|
||||
@@ -141,13 +140,13 @@ func (m *apt) manageRepository(repoAction shared.DefinitionPackagesRepository) e
|
||||
|
||||
f, err := os.Create(signatureFilePath)
|
||||
if err != nil {
|
||||
return errors.WithMessagef(err, "Failed to create file %q", signatureFilePath)
|
||||
return fmt.Errorf("Failed to create file %q: %w", signatureFilePath, err)
|
||||
}
|
||||
defer f.Close()
|
||||
|
||||
_, err = io.Copy(f, reader)
|
||||
if err != nil {
|
||||
return errors.WithMessage(err, "Failed to copy file")
|
||||
return fmt.Errorf("Failed to copy file: %w", err)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
package managers
|
||||
|
||||
import (
|
||||
"github.com/pkg/errors"
|
||||
"errors"
|
||||
|
||||
"github.com/lxc/distrobuilder/shared"
|
||||
)
|
||||
|
||||
@@ -1,12 +1,13 @@
|
||||
package managers
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
|
||||
lxd "github.com/lxc/lxd/shared"
|
||||
"github.com/pkg/errors"
|
||||
|
||||
"github.com/lxc/distrobuilder/shared"
|
||||
)
|
||||
@@ -66,20 +67,20 @@ func (m *luet) manageRepository(repoAction shared.DefinitionPackagesRepository)
|
||||
if !lxd.PathExists(filepath.Dir(targetFile)) {
|
||||
err := os.MkdirAll(filepath.Dir(targetFile), 0755)
|
||||
if err != nil {
|
||||
return errors.WithMessagef(err, "Failed to create directory %q", filepath.Dir(targetFile))
|
||||
return fmt.Errorf("Failed to create directory %q: %w", filepath.Dir(targetFile), err)
|
||||
}
|
||||
}
|
||||
|
||||
f, err := os.OpenFile(targetFile, os.O_CREATE|os.O_WRONLY, 0644)
|
||||
if err != nil {
|
||||
return errors.WithMessagef(err, "Failed to open file %q", targetFile)
|
||||
return fmt.Errorf("Failed to open file %q: %w", targetFile, err)
|
||||
}
|
||||
defer f.Close()
|
||||
|
||||
// NOTE: repo.URL is not an URL but the content of the file.
|
||||
_, err = f.WriteString(repoAction.URL)
|
||||
if err != nil {
|
||||
return errors.WithMessagef(err, "Failed to write string to %q", targetFile)
|
||||
return fmt.Errorf("Failed to write string to %q: %w", targetFile, err)
|
||||
}
|
||||
|
||||
return nil
|
||||
|
||||
@@ -1,9 +1,10 @@
|
||||
package managers
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
"github.com/pkg/errors"
|
||||
"go.uber.org/zap"
|
||||
|
||||
"github.com/lxc/distrobuilder/shared"
|
||||
@@ -83,7 +84,7 @@ func Load(managerName string, logger *zap.SugaredLogger, definition shared.Defin
|
||||
|
||||
err := d.load()
|
||||
if err != nil {
|
||||
return nil, errors.WithMessagef(err, "Failed to load manager %q", managerName)
|
||||
return nil, fmt.Errorf("Failed to load manager %q: %w", managerName, err)
|
||||
}
|
||||
|
||||
return &Manager{def: definition, mgr: d}, nil
|
||||
@@ -109,20 +110,20 @@ func (m *Manager) ManagePackages(imageTarget shared.ImageTarget) error {
|
||||
|
||||
err := m.mgr.refresh()
|
||||
if err != nil {
|
||||
return errors.WithMessage(err, "Failed to refresh")
|
||||
return fmt.Errorf("Failed to refresh: %w", err)
|
||||
}
|
||||
|
||||
if m.def.Packages.Update {
|
||||
err = m.mgr.update()
|
||||
if err != nil {
|
||||
return errors.WithMessage(err, "Failed to update")
|
||||
return fmt.Errorf("Failed to update: %w", err)
|
||||
}
|
||||
|
||||
// Run post update hook
|
||||
for _, action := range m.def.GetRunnableActions("post-update", imageTarget) {
|
||||
err = shared.RunScript(action.Action)
|
||||
if err != nil {
|
||||
return errors.WithMessage(err, "Failed to run post-update")
|
||||
return fmt.Errorf("Failed to run post-update: %w", err)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -134,14 +135,14 @@ func (m *Manager) ManagePackages(imageTarget shared.ImageTarget) error {
|
||||
err = m.mgr.remove(set.Packages, set.Flags)
|
||||
}
|
||||
if err != nil {
|
||||
return errors.WithMessagef(err, "Failed to %s packages", set.Action)
|
||||
return fmt.Errorf("Failed to %s packages: %w", set.Action, err)
|
||||
}
|
||||
}
|
||||
|
||||
if m.def.Packages.Cleanup {
|
||||
err = m.mgr.clean()
|
||||
if err != nil {
|
||||
return errors.WithMessage(err, "Failed to clean up packages")
|
||||
return fmt.Errorf("Failed to clean up packages: %w", err)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -164,18 +165,18 @@ func (m *Manager) ManageRepositories(imageTarget shared.ImageTarget) error {
|
||||
// Run template on repo.URL
|
||||
repo.URL, err = shared.RenderTemplate(repo.URL, m.def)
|
||||
if err != nil {
|
||||
return errors.WithMessage(err, "Failed to render template")
|
||||
return fmt.Errorf("Failed to render template: %w", err)
|
||||
}
|
||||
|
||||
// Run template on repo.Key
|
||||
repo.Key, err = shared.RenderTemplate(repo.Key, m.def)
|
||||
if err != nil {
|
||||
return errors.WithMessage(err, "Failed to render template")
|
||||
return fmt.Errorf("Failed to render template: %w", err)
|
||||
}
|
||||
|
||||
err = m.mgr.manageRepository(repo)
|
||||
if err != nil {
|
||||
return errors.WithMessagef(err, "Error for repository %s", repo.Name)
|
||||
return fmt.Errorf("Error for repository %s: %w", repo.Name, err)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
package managers
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"runtime"
|
||||
|
||||
lxd "github.com/lxc/lxd/shared"
|
||||
"github.com/pkg/errors"
|
||||
|
||||
"github.com/lxc/distrobuilder/shared"
|
||||
)
|
||||
@@ -19,12 +19,12 @@ type pacman struct {
|
||||
func (m *pacman) load() error {
|
||||
err := m.setMirrorlist()
|
||||
if err != nil {
|
||||
return errors.WithMessage(err, "Failed to set mirrorlist")
|
||||
return fmt.Errorf("Failed to set mirrorlist: %w", err)
|
||||
}
|
||||
|
||||
err = m.setupTrustedKeys()
|
||||
if err != nil {
|
||||
return errors.WithMessage(err, "Failed to setup trusted keys")
|
||||
return fmt.Errorf("Failed to setup trusted keys: %w", err)
|
||||
}
|
||||
|
||||
m.commands = managerCommands{
|
||||
@@ -67,7 +67,7 @@ func (m *pacman) load() error {
|
||||
return nil
|
||||
}
|
||||
|
||||
return errors.WithMessagef(err, "Failed to list directory '%s'", path)
|
||||
return fmt.Errorf("Failed to list directory '%s': %w", path, err)
|
||||
}
|
||||
|
||||
// Individually wipe all entries.
|
||||
@@ -75,7 +75,7 @@ func (m *pacman) load() error {
|
||||
entryPath := filepath.Join(path, entry.Name())
|
||||
err := os.RemoveAll(entryPath)
|
||||
if err != nil && !os.IsNotExist(err) {
|
||||
return errors.WithMessagef(err, "Failed to remove '%s'", entryPath)
|
||||
return fmt.Errorf("Failed to remove '%s': %w", entryPath, err)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -96,7 +96,7 @@ func (m *pacman) setupTrustedKeys() error {
|
||||
|
||||
err = shared.RunCommand("pacman-key", "--init")
|
||||
if err != nil {
|
||||
return errors.WithMessage(err, "Error initializing with pacman-key")
|
||||
return fmt.Errorf("Error initializing with pacman-key: %w", err)
|
||||
}
|
||||
|
||||
var keyring string
|
||||
@@ -109,7 +109,7 @@ func (m *pacman) setupTrustedKeys() error {
|
||||
|
||||
err = shared.RunCommand("pacman-key", "--populate", keyring)
|
||||
if err != nil {
|
||||
return errors.WithMessage(err, "Error populating with pacman-key")
|
||||
return fmt.Errorf("Error populating with pacman-key: %w", err)
|
||||
}
|
||||
|
||||
return nil
|
||||
@@ -118,7 +118,7 @@ func (m *pacman) setupTrustedKeys() error {
|
||||
func (m *pacman) setMirrorlist() error {
|
||||
f, err := os.Create(filepath.Join("etc", "pacman.d", "mirrorlist"))
|
||||
if err != nil {
|
||||
return errors.WithMessagef(err, "Failed to create file %q", filepath.Join("etc", "pacman.d", "mirrorlist"))
|
||||
return fmt.Errorf("Failed to create file %q: %w", filepath.Join("etc", "pacman.d", "mirrorlist"), err)
|
||||
}
|
||||
defer f.Close()
|
||||
|
||||
@@ -132,7 +132,7 @@ func (m *pacman) setMirrorlist() error {
|
||||
|
||||
_, err = f.WriteString(mirror)
|
||||
if err != nil {
|
||||
return errors.WithMessagef(err, "Failed to write to %q", filepath.Join("etc", "pacman.d", "mirrorlist"))
|
||||
return fmt.Errorf("Failed to write to %q: %w", filepath.Join("etc", "pacman.d", "mirrorlist"), err)
|
||||
}
|
||||
|
||||
return nil
|
||||
|
||||
@@ -9,7 +9,6 @@ import (
|
||||
"strings"
|
||||
|
||||
lxd "github.com/lxc/lxd/shared"
|
||||
"github.com/pkg/errors"
|
||||
|
||||
"github.com/lxc/distrobuilder/shared"
|
||||
)
|
||||
@@ -77,26 +76,26 @@ func yumManageRepository(repoAction shared.DefinitionPackagesRepository) error {
|
||||
if !lxd.PathExists(filepath.Dir(targetFile)) {
|
||||
err := os.MkdirAll(filepath.Dir(targetFile), 0755)
|
||||
if err != nil {
|
||||
return errors.WithMessagef(err, "Failed to create directory %q", filepath.Dir(targetFile))
|
||||
return fmt.Errorf("Failed to create directory %q: %w", filepath.Dir(targetFile), err)
|
||||
}
|
||||
}
|
||||
|
||||
f, err := os.Create(targetFile)
|
||||
if err != nil {
|
||||
return errors.WithMessagef(err, "Failed to create file %q", targetFile)
|
||||
return fmt.Errorf("Failed to create file %q: %w", targetFile, err)
|
||||
}
|
||||
defer f.Close()
|
||||
|
||||
_, err = f.WriteString(repoAction.URL)
|
||||
if err != nil {
|
||||
return errors.WithMessagef(err, "Failed to write to file %q", targetFile)
|
||||
return fmt.Errorf("Failed to write to file %q: %w", targetFile, err)
|
||||
}
|
||||
|
||||
// Append final new line if missing
|
||||
if !strings.HasSuffix(repoAction.URL, "\n") {
|
||||
_, err = f.WriteString("\n")
|
||||
if err != nil {
|
||||
return errors.WithMessagef(err, "Failed to write to file %q", targetFile)
|
||||
return fmt.Errorf("Failed to write to file %q: %w", targetFile, err)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
package managers
|
||||
|
||||
import (
|
||||
"github.com/pkg/errors"
|
||||
"errors"
|
||||
|
||||
"github.com/lxc/distrobuilder/shared"
|
||||
)
|
||||
|
||||
@@ -9,7 +9,6 @@ import (
|
||||
"strconv"
|
||||
|
||||
lxd "github.com/lxc/lxd/shared"
|
||||
"github.com/pkg/errors"
|
||||
"golang.org/x/sys/unix"
|
||||
)
|
||||
|
||||
@@ -30,7 +29,7 @@ func setupMounts(rootfs string, mounts []ChrootMount) error {
|
||||
// Create a temporary mount path
|
||||
err := os.MkdirAll(filepath.Join(rootfs, ".distrobuilder"), 0700)
|
||||
if err != nil {
|
||||
return errors.WithMessagef(err, "Failed to create directory %q", filepath.Join(rootfs, ".distrobuilder"))
|
||||
return fmt.Errorf("Failed to create directory %q: %w", filepath.Join(rootfs, ".distrobuilder"), err)
|
||||
}
|
||||
|
||||
for i, mount := range mounts {
|
||||
@@ -41,12 +40,12 @@ func setupMounts(rootfs string, mounts []ChrootMount) error {
|
||||
if mount.IsDir {
|
||||
err := os.MkdirAll(tmpTarget, 0755)
|
||||
if err != nil {
|
||||
return errors.WithMessagef(err, "Failed to create directory %q", tmpTarget)
|
||||
return fmt.Errorf("Failed to create directory %q: %w", tmpTarget, err)
|
||||
}
|
||||
} else {
|
||||
f, err := os.Create(tmpTarget)
|
||||
if err != nil {
|
||||
return errors.WithMessagef(err, "Failed to create file %q", tmpTarget)
|
||||
return fmt.Errorf("Failed to create file %q: %w", tmpTarget, err)
|
||||
}
|
||||
f.Close()
|
||||
}
|
||||
@@ -54,7 +53,7 @@ func setupMounts(rootfs string, mounts []ChrootMount) error {
|
||||
// Mount to the temporary path
|
||||
err := unix.Mount(mount.Source, tmpTarget, mount.FSType, mount.Flags, mount.Data)
|
||||
if err != nil {
|
||||
return errors.WithMessagef(err, "Failed to mount '%s'", mount.Source)
|
||||
return fmt.Errorf("Failed to mount '%s': %w", mount.Source, err)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -96,14 +95,14 @@ func moveMounts(mounts []ChrootMount) error {
|
||||
// Get information on current target
|
||||
fi, err := os.Lstat(targetDir)
|
||||
if err != nil {
|
||||
return errors.WithMessagef(err, "Failed to stat directory %q", targetDir)
|
||||
return fmt.Errorf("Failed to stat directory %q: %w", targetDir, err)
|
||||
}
|
||||
|
||||
// If a symlink, resolve it
|
||||
if fi.Mode()&os.ModeSymlink != 0 {
|
||||
newTarget, err := os.Readlink(targetDir)
|
||||
if err != nil {
|
||||
return errors.WithMessagef(err, "Failed to get destination of %q", targetDir)
|
||||
return fmt.Errorf("Failed to get destination of %q: %w", targetDir, err)
|
||||
}
|
||||
|
||||
targetDir = newTarget
|
||||
@@ -113,19 +112,19 @@ func moveMounts(mounts []ChrootMount) error {
|
||||
// Create parent paths if missing
|
||||
err := os.MkdirAll(targetDir, 0755)
|
||||
if err != nil {
|
||||
return errors.WithMessagef(err, "Failed to create directory %q", targetDir)
|
||||
return fmt.Errorf("Failed to create directory %q: %w", targetDir, err)
|
||||
}
|
||||
|
||||
// Create target path
|
||||
if mount.IsDir {
|
||||
err = os.MkdirAll(target, 0755)
|
||||
if err != nil {
|
||||
return errors.WithMessagef(err, "Failed to create directory %q", target)
|
||||
return fmt.Errorf("Failed to create directory %q: %w", target, err)
|
||||
}
|
||||
} else {
|
||||
f, err := os.Create(target)
|
||||
if err != nil {
|
||||
return errors.WithMessagef(err, "Failed to create file %q", target)
|
||||
return fmt.Errorf("Failed to create file %q: %w", target, err)
|
||||
}
|
||||
f.Close()
|
||||
}
|
||||
@@ -133,14 +132,14 @@ func moveMounts(mounts []ChrootMount) error {
|
||||
// Move the mount to its destination
|
||||
err = unix.Mount(tmpSource, target, "", unix.MS_MOVE, "")
|
||||
if err != nil {
|
||||
return errors.WithMessagef(err, "Failed to mount '%s'", mount.Source)
|
||||
return fmt.Errorf("Failed to mount '%s': %w", mount.Source, err)
|
||||
}
|
||||
}
|
||||
|
||||
// Cleanup our temporary path
|
||||
err := os.RemoveAll(filepath.Join("/", ".distrobuilder"))
|
||||
if err != nil {
|
||||
return errors.WithMessagef(err, "Failed to remove directory %q", filepath.Join("/", ".distrobuilder"))
|
||||
return fmt.Errorf("Failed to remove directory %q: %w", filepath.Join("/", ".distrobuilder"), err)
|
||||
}
|
||||
|
||||
return nil
|
||||
@@ -151,12 +150,12 @@ func killChrootProcesses(rootfs string) error {
|
||||
// List all files under /proc
|
||||
proc, err := os.Open(filepath.Join(rootfs, "proc"))
|
||||
if err != nil {
|
||||
return errors.WithMessagef(err, "Failed to open file %q", filepath.Join(rootfs, "proc"))
|
||||
return fmt.Errorf("Failed to open file %q: %w", filepath.Join(rootfs, "proc"), err)
|
||||
}
|
||||
|
||||
dirs, err := proc.Readdirnames(0)
|
||||
if err != nil {
|
||||
return errors.WithMessagef(err, "Failed to read directory content of %q", filepath.Join(rootfs, "proc"))
|
||||
return fmt.Errorf("Failed to read directory content of %q: %w", filepath.Join(rootfs, "proc"), err)
|
||||
}
|
||||
|
||||
// Get all processes and kill them
|
||||
@@ -180,7 +179,7 @@ func SetupChroot(rootfs string, envs DefinitionEnv, m []ChrootMount) (func() err
|
||||
// Mount the rootfs
|
||||
err := unix.Mount(rootfs, rootfs, "", unix.MS_BIND, "")
|
||||
if err != nil {
|
||||
return nil, errors.WithMessagef(err, "Failed to mount '%s'", rootfs)
|
||||
return nil, fmt.Errorf("Failed to mount '%s': %w", rootfs, err)
|
||||
}
|
||||
|
||||
// Setup all other needed mounts
|
||||
@@ -212,7 +211,7 @@ func SetupChroot(rootfs string, envs DefinitionEnv, m []ChrootMount) (func() err
|
||||
err = setupMounts(rootfs, mounts)
|
||||
}
|
||||
if err != nil {
|
||||
return nil, errors.WithMessage(err, "Failed to mount filesystems")
|
||||
return nil, fmt.Errorf("Failed to mount filesystems: %w", err)
|
||||
}
|
||||
|
||||
// Chroot into the container's rootfs
|
||||
@@ -236,13 +235,13 @@ func SetupChroot(rootfs string, envs DefinitionEnv, m []ChrootMount) (func() err
|
||||
// Populate /dev directory instead of bind mounting it from the host
|
||||
err = populateDev()
|
||||
if err != nil {
|
||||
return nil, errors.WithMessage(err, "Failed to populate /dev")
|
||||
return nil, fmt.Errorf("Failed to populate /dev: %w", err)
|
||||
}
|
||||
|
||||
// Change permission for /dev/shm
|
||||
err = unix.Chmod("/dev/shm", 01777)
|
||||
if err != nil {
|
||||
return nil, errors.WithMessage(err, "Failed to chmod /dev/shm")
|
||||
return nil, fmt.Errorf("Failed to chmod /dev/shm: %w", err)
|
||||
}
|
||||
|
||||
var env Environment
|
||||
@@ -308,7 +307,7 @@ exit 101
|
||||
if policyCleanup {
|
||||
err = os.Remove("/usr/sbin/policy-rc.d")
|
||||
if err != nil {
|
||||
return errors.WithMessagef(err, "Failed to remove %q", "/usr/sbin/policy-rc.d")
|
||||
return fmt.Errorf("Failed to remove %q: %w", "/usr/sbin/policy-rc.d", err)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -318,17 +317,17 @@ exit 101
|
||||
// Switch back to the host rootfs
|
||||
err = root.Chdir()
|
||||
if err != nil {
|
||||
return errors.WithMessage(err, "Failed to chdir")
|
||||
return fmt.Errorf("Failed to chdir: %w", err)
|
||||
}
|
||||
|
||||
err = unix.Chroot(".")
|
||||
if err != nil {
|
||||
return errors.WithMessage(err, "Failed to chroot")
|
||||
return fmt.Errorf("Failed to chroot: %w", err)
|
||||
}
|
||||
|
||||
err = unix.Chdir(cwd)
|
||||
if err != nil {
|
||||
return errors.WithMessage(err, "Failed to chdir")
|
||||
return fmt.Errorf("Failed to chdir: %w", err)
|
||||
}
|
||||
|
||||
// This will kill all processes in the chroot and allow to cleanly
|
||||
@@ -343,7 +342,7 @@ exit 101
|
||||
// Wipe $rootfs/dev
|
||||
err := os.RemoveAll(devPath)
|
||||
if err != nil {
|
||||
return errors.WithMessagef(err, "Failed to remove directory %q", devPath)
|
||||
return fmt.Errorf("Failed to remove directory %q: %w", devPath, err)
|
||||
}
|
||||
|
||||
ActiveChroots[rootfs] = nil
|
||||
@@ -381,14 +380,14 @@ func populateDev() error {
|
||||
|
||||
err := unix.Mknod(d.Path, d.Mode, int(dev))
|
||||
if err != nil {
|
||||
return errors.WithMessagef(err, "Failed to create %q", d.Path)
|
||||
return fmt.Errorf("Failed to create %q: %w", d.Path, err)
|
||||
}
|
||||
|
||||
// For some odd reason, unix.Mknod will not set the mode correctly.
|
||||
// This fixes that.
|
||||
err = unix.Chmod(d.Path, d.Mode)
|
||||
if err != nil {
|
||||
return errors.WithMessagef(err, "Failed to chmod %q", d.Path)
|
||||
return fmt.Errorf("Failed to chmod %q: %w", d.Path, err)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -405,7 +404,7 @@ func populateDev() error {
|
||||
for _, l := range symlinks {
|
||||
err := os.Symlink(l.Target, l.Symlink)
|
||||
if err != nil {
|
||||
return errors.WithMessagef(err, "Failed to create link %q -> %q", l.Symlink, l.Target)
|
||||
return fmt.Errorf("Failed to create link %q -> %q: %w", l.Symlink, l.Target, err)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
package shared
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"reflect"
|
||||
"strconv"
|
||||
"strings"
|
||||
@@ -8,7 +10,6 @@ import (
|
||||
|
||||
"github.com/lxc/lxd/shared"
|
||||
lxdarch "github.com/lxc/lxd/shared/osarch"
|
||||
"github.com/pkg/errors"
|
||||
)
|
||||
|
||||
// ImageTarget represents the image target.
|
||||
@@ -235,25 +236,25 @@ func (d *Definition) SetValue(key string, value string) error {
|
||||
// Walk through the definition and find the field with the given key
|
||||
field, err := getFieldByTag(reflect.ValueOf(d).Elem(), reflect.TypeOf(d).Elem(), key)
|
||||
if err != nil {
|
||||
return errors.WithMessage(err, "Failed to get field by tag")
|
||||
return fmt.Errorf("Failed to get field by tag: %w", err)
|
||||
}
|
||||
|
||||
// Fail if the field cannot be set
|
||||
if !field.CanSet() {
|
||||
return errors.Errorf("Cannot set value for %s", key)
|
||||
return fmt.Errorf("Cannot set value for %s", key)
|
||||
}
|
||||
|
||||
switch field.Kind() {
|
||||
case reflect.Bool:
|
||||
v, err := strconv.ParseBool(value)
|
||||
if err != nil {
|
||||
return errors.WithMessagef(err, "Failed to parse bool %q", value)
|
||||
return fmt.Errorf("Failed to parse bool %q: %w", value, err)
|
||||
}
|
||||
field.SetBool(v)
|
||||
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
|
||||
v, err := strconv.ParseInt(value, 10, 64)
|
||||
if err != nil {
|
||||
return errors.WithMessagef(err, "Failed to parse int %q", value)
|
||||
return fmt.Errorf("Failed to parse int %q: %w", value, err)
|
||||
}
|
||||
field.SetInt(v)
|
||||
case reflect.String:
|
||||
@@ -261,11 +262,11 @@ func (d *Definition) SetValue(key string, value string) error {
|
||||
case reflect.Uint, reflect.Uintptr, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
|
||||
v, err := strconv.ParseUint(value, 10, 64)
|
||||
if err != nil {
|
||||
return errors.WithMessagef(err, "Failed to parse uint %q", value)
|
||||
return fmt.Errorf("Failed to parse uint %q: %w", value, err)
|
||||
}
|
||||
field.SetUint(v)
|
||||
default:
|
||||
return errors.Errorf("Unsupported type '%s'", field.Kind())
|
||||
return fmt.Errorf("Unsupported type '%s'", field.Kind())
|
||||
}
|
||||
|
||||
return nil
|
||||
@@ -343,7 +344,7 @@ func (d *Definition) Validate() error {
|
||||
"rockylinux-http",
|
||||
}
|
||||
if !shared.StringInSlice(strings.TrimSpace(d.Source.Downloader), validDownloaders) {
|
||||
return errors.Errorf("source.downloader must be one of %v", validDownloaders)
|
||||
return fmt.Errorf("source.downloader must be one of %v", validDownloaders)
|
||||
}
|
||||
|
||||
if d.Packages.Manager != "" {
|
||||
@@ -362,7 +363,7 @@ func (d *Definition) Validate() error {
|
||||
"luet",
|
||||
}
|
||||
if !shared.StringInSlice(strings.TrimSpace(d.Packages.Manager), validManagers) {
|
||||
return errors.Errorf("packages.manager must be one of %v", validManagers)
|
||||
return fmt.Errorf("packages.manager must be one of %v", validManagers)
|
||||
}
|
||||
|
||||
if d.Packages.CustomManager != nil {
|
||||
@@ -409,7 +410,7 @@ func (d *Definition) Validate() error {
|
||||
|
||||
for _, file := range d.Files {
|
||||
if !shared.StringInSlice(strings.TrimSpace(file.Generator), validGenerators) {
|
||||
return errors.Errorf("files.*.generator must be one of %v", validGenerators)
|
||||
return fmt.Errorf("files.*.generator must be one of %v", validGenerators)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -429,7 +430,7 @@ func (d *Definition) Validate() error {
|
||||
architectureMap := strings.TrimSpace(d.Mappings.ArchitectureMap)
|
||||
if architectureMap != "" {
|
||||
if !shared.StringInSlice(architectureMap, validMappings) {
|
||||
return errors.Errorf("mappings.architecture_map must be one of %v", validMappings)
|
||||
return fmt.Errorf("mappings.architecture_map must be one of %v", validMappings)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -442,7 +443,7 @@ func (d *Definition) Validate() error {
|
||||
|
||||
for _, action := range d.Actions {
|
||||
if !shared.StringInSlice(action.Trigger, validTriggers) {
|
||||
return errors.Errorf("actions.*.trigger must be one of %v", validTriggers)
|
||||
return fmt.Errorf("actions.*.trigger must be one of %v", validTriggers)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -453,14 +454,14 @@ func (d *Definition) Validate() error {
|
||||
|
||||
for _, set := range d.Packages.Sets {
|
||||
if !shared.StringInSlice(set.Action, validPackageActions) {
|
||||
return errors.Errorf("packages.*.set.*.action must be one of %v", validPackageActions)
|
||||
return fmt.Errorf("packages.*.set.*.action must be one of %v", validPackageActions)
|
||||
}
|
||||
}
|
||||
|
||||
// Mapped architecture (distro name)
|
||||
archMapped, err := d.getMappedArchitecture()
|
||||
if err != nil {
|
||||
return errors.WithMessage(err, "Failed to get mapped architecture")
|
||||
return fmt.Errorf("Failed to get mapped architecture: %w", err)
|
||||
}
|
||||
|
||||
d.Image.ArchitectureMapped = archMapped
|
||||
@@ -468,19 +469,19 @@ func (d *Definition) Validate() error {
|
||||
// Kernel architecture and personality
|
||||
archID, err := lxdarch.ArchitectureId(d.Image.Architecture)
|
||||
if err != nil {
|
||||
return errors.WithMessage(err, "Failed to get architecture ID")
|
||||
return fmt.Errorf("Failed to get architecture ID: %w", err)
|
||||
}
|
||||
|
||||
archName, err := lxdarch.ArchitectureName(archID)
|
||||
if err != nil {
|
||||
return errors.WithMessage(err, "Failed to get architecture name")
|
||||
return fmt.Errorf("Failed to get architecture name: %w", err)
|
||||
}
|
||||
|
||||
d.Image.ArchitectureKernel = archName
|
||||
|
||||
archPersonality, err := lxdarch.ArchitecturePersonality(archID)
|
||||
if err != nil {
|
||||
return errors.WithMessage(err, "Failed to get architecture personality")
|
||||
return fmt.Errorf("Failed to get architecture personality: %w", err)
|
||||
}
|
||||
|
||||
d.Image.ArchitecturePersonality = archPersonality
|
||||
@@ -536,7 +537,7 @@ func (d *Definition) getMappedArchitecture() (string, error) {
|
||||
var err error
|
||||
arch, err = GetArch(d.Mappings.ArchitectureMap, d.Image.Architecture)
|
||||
if err != nil {
|
||||
return "", errors.WithMessage(err, "Failed to translate the architecture name")
|
||||
return "", fmt.Errorf("Failed to translate the architecture name: %w", err)
|
||||
}
|
||||
} else if len(d.Mappings.Architectures) > 0 {
|
||||
// Translate the architecture using a user specified mapping
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package shared
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"hash"
|
||||
"io"
|
||||
@@ -12,7 +13,6 @@ import (
|
||||
|
||||
lxd "github.com/lxc/lxd/shared"
|
||||
"github.com/lxc/lxd/shared/ioprogress"
|
||||
"github.com/pkg/errors"
|
||||
)
|
||||
|
||||
// DownloadHash downloads a file. If a checksum file is provided, it will try and
|
||||
@@ -42,7 +42,7 @@ func DownloadHash(def DefinitionImage, file, checksum string, hashFunc hash.Hash
|
||||
|
||||
hashes, err = downloadChecksum(targetDir, checksum, file, hashFunc, hashLen)
|
||||
if err != nil {
|
||||
return "", errors.WithMessage(err, "Error while downloading checksum")
|
||||
return "", fmt.Errorf("Error while downloading checksum: %w", err)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -78,7 +78,7 @@ func DownloadHash(def DefinitionImage, file, checksum string, hashFunc hash.Hash
|
||||
}
|
||||
|
||||
if hash == "" {
|
||||
return "", errors.Errorf("Hash mismatch for %s: %s != %v", imagePath, result, hashes)
|
||||
return "", fmt.Errorf("Hash mismatch for %s: %s != %v", imagePath, result, hashes)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
package shared
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/lxc/lxd/shared/osarch"
|
||||
"github.com/pkg/errors"
|
||||
)
|
||||
|
||||
var alpineLinuxArchitectureNames = map[int]string{
|
||||
@@ -87,7 +88,7 @@ func GetArch(distro, arch string) (string, error) {
|
||||
|
||||
archMap, ok := distroArchitecture[distro]
|
||||
if !ok {
|
||||
return "unknown", errors.Errorf("Architecture map isn't supported: %s", distro)
|
||||
return "unknown", fmt.Errorf("Architecture map isn't supported: %s", distro)
|
||||
}
|
||||
|
||||
archID, err := osarch.ArchitectureId(arch)
|
||||
|
||||
@@ -16,7 +16,6 @@ import (
|
||||
"time"
|
||||
|
||||
lxd "github.com/lxc/lxd/shared"
|
||||
"github.com/pkg/errors"
|
||||
"golang.org/x/sys/unix"
|
||||
"gopkg.in/flosch/pongo2.v3"
|
||||
yaml "gopkg.in/yaml.v2"
|
||||
@@ -37,19 +36,19 @@ func Copy(src, dest string) error {
|
||||
|
||||
srcFile, err := os.Open(src)
|
||||
if err != nil {
|
||||
return errors.WithMessagef(err, "Failed to open file %q", src)
|
||||
return fmt.Errorf("Failed to open file %q: %w", src, err)
|
||||
}
|
||||
defer srcFile.Close()
|
||||
|
||||
destFile, err := os.Create(dest)
|
||||
if err != nil {
|
||||
return errors.WithMessagef(err, "Failed to create file %q", dest)
|
||||
return fmt.Errorf("Failed to create file %q: %w", dest, err)
|
||||
}
|
||||
defer destFile.Close()
|
||||
|
||||
_, err = io.Copy(destFile, srcFile)
|
||||
if err != nil {
|
||||
return errors.WithMessage(err, "Failed to copy file")
|
||||
return fmt.Errorf("Failed to copy file: %w", err)
|
||||
}
|
||||
|
||||
return destFile.Sync()
|
||||
@@ -74,13 +73,13 @@ func RunCommand(name string, arg ...string) error {
|
||||
func RunScript(content string) error {
|
||||
fd, err := unix.MemfdCreate("tmp", 0)
|
||||
if err != nil {
|
||||
return errors.WithMessage(err, "Failed to create memfd")
|
||||
return fmt.Errorf("Failed to create memfd: %w", err)
|
||||
}
|
||||
defer unix.Close(fd)
|
||||
|
||||
_, err = unix.Write(int(fd), []byte(content))
|
||||
if err != nil {
|
||||
return errors.WithMessage(err, "Failed to write to memfd")
|
||||
return fmt.Errorf("Failed to write to memfd: %w", err)
|
||||
}
|
||||
|
||||
fdPath := fmt.Sprintf("/proc/self/fd/%d", fd)
|
||||
@@ -101,7 +100,7 @@ func GetSignedContent(signedFile string, keys []string, keyserver string) ([]byt
|
||||
out, err := exec.Command("gpg", "--homedir", gpgDir, "--keyring", keyring,
|
||||
"--decrypt", signedFile).Output()
|
||||
if err != nil {
|
||||
return nil, errors.WithMessagef(err, "Failed to get file content: %s", out)
|
||||
return nil, fmt.Errorf("Failed to get file content: %s: %w", out, err)
|
||||
}
|
||||
|
||||
return out, nil
|
||||
@@ -120,13 +119,13 @@ func VerifyFile(signedFile, signatureFile string, keys []string, keyserver strin
|
||||
out, err := lxd.RunCommand("gpg", "--homedir", gpgDir, "--keyring", keyring,
|
||||
"--verify", signatureFile, signedFile)
|
||||
if err != nil {
|
||||
return false, errors.WithMessagef(err, "Failed to verify: %s", out)
|
||||
return false, fmt.Errorf("Failed to verify: %s: %w", out, err)
|
||||
}
|
||||
} else {
|
||||
out, err := lxd.RunCommand("gpg", "--homedir", gpgDir, "--keyring", keyring,
|
||||
"--verify", signedFile)
|
||||
if err != nil {
|
||||
return false, errors.WithMessagef(err, "Failed to verify: %s", out)
|
||||
return false, fmt.Errorf("Failed to verify: %s: %w", out, err)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -159,7 +158,7 @@ func recvGPGKeys(gpgDir string, keyserver string, keys []string) (bool, error) {
|
||||
|
||||
err := cmd.Run()
|
||||
if err != nil {
|
||||
return false, errors.Errorf("Failed to run: %s: %s", strings.Join(cmd.Args, " "), strings.TrimSpace(buffer.String()))
|
||||
return false, fmt.Errorf("Failed to run: %s: %s", strings.Join(cmd.Args, " "), strings.TrimSpace(buffer.String()))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -202,7 +201,7 @@ func recvGPGKeys(gpgDir string, keyserver string, keys []string) (bool, error) {
|
||||
}
|
||||
}
|
||||
|
||||
return false, errors.Errorf("Failed to import keys: %s", strings.Join(missingKeys, " "))
|
||||
return false, fmt.Errorf("Failed to import keys: %s", strings.Join(missingKeys, " "))
|
||||
}
|
||||
|
||||
return true, nil
|
||||
@@ -212,7 +211,7 @@ func recvGPGKeys(gpgDir string, keyserver string, keys []string) (bool, error) {
|
||||
func CreateGPGKeyring(keyserver string, keys []string) (string, error) {
|
||||
gpgDir, err := ioutil.TempDir(os.TempDir(), "distrobuilder.")
|
||||
if err != nil {
|
||||
return "", errors.WithMessage(err, "Failed to create gpg directory")
|
||||
return "", fmt.Errorf("Failed to create gpg directory: %w", err)
|
||||
}
|
||||
|
||||
err = os.MkdirAll(gpgDir, 0700)
|
||||
@@ -240,7 +239,7 @@ func CreateGPGKeyring(keyserver string, keys []string) (string, error) {
|
||||
filepath.Join(gpgDir, "distrobuilder.gpg"))
|
||||
if err != nil {
|
||||
os.RemoveAll(gpgDir)
|
||||
return "", errors.WithMessagef(err, "Failed to export keyring: %s", out)
|
||||
return "", fmt.Errorf("Failed to export keyring: %s: %w", out, err)
|
||||
}
|
||||
|
||||
return filepath.Join(gpgDir, "distrobuilder.gpg"), nil
|
||||
@@ -252,7 +251,7 @@ func Pack(filename, compression, path string, args ...string) error {
|
||||
if err != nil {
|
||||
// Clean up incomplete tarball
|
||||
os.Remove(filename)
|
||||
return errors.WithMessage(err, "Failed to create tarball")
|
||||
return fmt.Errorf("Failed to create tarball: %w", err)
|
||||
}
|
||||
|
||||
return compressTarball(filename, compression)
|
||||
@@ -262,7 +261,7 @@ func Pack(filename, compression, path string, args ...string) error {
|
||||
func PackUpdate(filename, compression, path string, args ...string) error {
|
||||
err := RunCommand("tar", append([]string{"--xattrs", "-uf", filename, "-C", path}, args...)...)
|
||||
if err != nil {
|
||||
return errors.WithMessage(err, "Failed to update tarball")
|
||||
return fmt.Errorf("Failed to update tarball: %w", err)
|
||||
}
|
||||
|
||||
return compressTarball(filename, compression)
|
||||
@@ -278,7 +277,7 @@ func compressTarball(filename, compression string) error {
|
||||
case "bzip2", "xz", "lzip", "lzma", "gzip":
|
||||
err := RunCommand(compression, "-f", filename)
|
||||
if err != nil {
|
||||
return errors.WithMessagef(err, "Failed to compress tarball %q", filename)
|
||||
return fmt.Errorf("Failed to compress tarball %q: %w", filename, err)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -460,7 +459,7 @@ func getChecksum(fname string, hashLen int, r io.Reader) []string {
|
||||
func RsyncLocal(src string, dest string) error {
|
||||
err := RunCommand("rsync", "-aHASX", "--devices", src, dest)
|
||||
if err != nil {
|
||||
return errors.WithMessagef(err, "Failed to copy %q to %q", src, dest)
|
||||
return fmt.Errorf("Failed to copy %q to %q: %w", src, dest, err)
|
||||
}
|
||||
|
||||
return nil
|
||||
|
||||
@@ -2,6 +2,7 @@ package sources
|
||||
|
||||
import (
|
||||
"crypto/sha256"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"net/http"
|
||||
@@ -12,8 +13,6 @@ import (
|
||||
"regexp"
|
||||
"strings"
|
||||
|
||||
"github.com/pkg/errors"
|
||||
|
||||
"github.com/lxc/distrobuilder/shared"
|
||||
)
|
||||
|
||||
@@ -36,7 +35,7 @@ func (s *almalinux) Run() error {
|
||||
s.fname, err = s.getRelease(s.definition.Source.URL, s.definition.Image.Release,
|
||||
s.definition.Source.Variant, s.definition.Image.ArchitectureMapped)
|
||||
if err != nil {
|
||||
return errors.WithMessage(err, "Failed to get release")
|
||||
return fmt.Errorf("Failed to get release: %w", err)
|
||||
}
|
||||
|
||||
fpath := shared.GetTargetDir(s.definition.Image)
|
||||
@@ -56,7 +55,7 @@ func (s *almalinux) Run() error {
|
||||
|
||||
url, err := url.Parse(baseURL)
|
||||
if err != nil {
|
||||
return errors.WithMessagef(err, "Failed to parse URL %q", baseURL)
|
||||
return fmt.Errorf("Failed to parse URL %q: %w", baseURL, err)
|
||||
}
|
||||
|
||||
checksumFile := ""
|
||||
@@ -79,7 +78,7 @@ func (s *almalinux) Run() error {
|
||||
|
||||
fpath, err := shared.DownloadHash(s.definition.Image, baseURL+checksumFile, "", nil)
|
||||
if err != nil {
|
||||
return errors.WithMessagef(err, "Failed to download %q", baseURL+checksumFile)
|
||||
return fmt.Errorf("Failed to download %q: %w", baseURL+checksumFile, err)
|
||||
}
|
||||
|
||||
// Only verify file if possible.
|
||||
@@ -87,10 +86,10 @@ func (s *almalinux) Run() error {
|
||||
valid, err := shared.VerifyFile(filepath.Join(fpath, checksumFile), "",
|
||||
s.definition.Source.Keys, s.definition.Source.Keyserver)
|
||||
if err != nil {
|
||||
return errors.WithMessagef(err, "Failed to verify %q", checksumFile)
|
||||
return fmt.Errorf("Failed to verify %q: %w", checksumFile, err)
|
||||
}
|
||||
if !valid {
|
||||
return errors.Errorf("Invalid signature for %q", filepath.Join(fpath, checksumFile))
|
||||
return fmt.Errorf("Invalid signature for %q", filepath.Join(fpath, checksumFile))
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -98,7 +97,7 @@ func (s *almalinux) Run() error {
|
||||
|
||||
_, err = shared.DownloadHash(s.definition.Image, baseURL+s.fname, checksumFile, sha256.New())
|
||||
if err != nil {
|
||||
return errors.WithMessagef(err, "Failed to download %q", baseURL+s.fname)
|
||||
return fmt.Errorf("Failed to download %q: %w", baseURL+s.fname, err)
|
||||
}
|
||||
|
||||
if strings.HasSuffix(s.fname, ".raw.xz") || strings.HasSuffix(s.fname, ".raw") {
|
||||
@@ -125,7 +124,7 @@ func (s *almalinux) rawRunner() error {
|
||||
rm -rf /rootfs/var/cache/yum
|
||||
`, s.majorVersion))
|
||||
if err != nil {
|
||||
return errors.WithMessage(err, "Failed to run script")
|
||||
return fmt.Errorf("Failed to run script: %w", err)
|
||||
}
|
||||
|
||||
return nil
|
||||
@@ -252,7 +251,7 @@ yum ${yum_args} --installroot=/rootfs -y --releasever=%s --skip-broken install $
|
||||
rm -rf /rootfs/var/cache/yum
|
||||
`, gpgKeysPath, s.majorVersion))
|
||||
if err != nil {
|
||||
return errors.WithMessage(err, "Failed to run script")
|
||||
return fmt.Errorf("Failed to run script: %w", err)
|
||||
}
|
||||
|
||||
return nil
|
||||
@@ -263,13 +262,13 @@ func (s *almalinux) getRelease(URL, release, variant, arch string) (string, erro
|
||||
|
||||
resp, err := http.Get(fullURL)
|
||||
if err != nil {
|
||||
return "", errors.WithMessagef(err, "Failed to GET %q", fullURL)
|
||||
return "", fmt.Errorf("Failed to GET %q: %w", fullURL, err)
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
|
||||
body, err := ioutil.ReadAll(resp.Body)
|
||||
if err != nil {
|
||||
return "", errors.WithMessage(err, "Failed to read body")
|
||||
return "", fmt.Errorf("Failed to read body: %w", err)
|
||||
}
|
||||
|
||||
re := s.getRegexes(arch, variant, release)
|
||||
|
||||
@@ -2,6 +2,7 @@ package sources
|
||||
|
||||
import (
|
||||
"crypto/sha256"
|
||||
"errors"
|
||||
"fmt"
|
||||
"net/url"
|
||||
"os"
|
||||
@@ -9,7 +10,6 @@ import (
|
||||
"strings"
|
||||
|
||||
lxd "github.com/lxc/lxd/shared"
|
||||
"github.com/pkg/errors"
|
||||
|
||||
"github.com/lxc/distrobuilder/shared"
|
||||
)
|
||||
@@ -38,7 +38,7 @@ func (s *alpineLinux) Run() error {
|
||||
} else if len(releaseField) == 3 {
|
||||
releaseShort = fmt.Sprintf("v%s.%s", releaseField[0], releaseField[1])
|
||||
} else {
|
||||
return errors.Errorf("Bad Alpine release: %s", releaseFull)
|
||||
return fmt.Errorf("Bad Alpine release: %s", releaseFull)
|
||||
}
|
||||
|
||||
fname := fmt.Sprintf("alpine-minirootfs-%s-%s.tar.gz", releaseFull, s.definition.Image.ArchitectureMapped)
|
||||
@@ -47,7 +47,7 @@ func (s *alpineLinux) Run() error {
|
||||
|
||||
url, err := url.Parse(tarball)
|
||||
if err != nil {
|
||||
return errors.WithMessagef(err, "Failed to parse URL %q", tarball)
|
||||
return fmt.Errorf("Failed to parse URL %q: %w", tarball, err)
|
||||
}
|
||||
|
||||
if !s.definition.Source.SkipVerification && url.Scheme != "https" &&
|
||||
@@ -63,7 +63,7 @@ func (s *alpineLinux) Run() error {
|
||||
fpath, err = shared.DownloadHash(s.definition.Image, tarball, tarball+".sha256", sha256.New())
|
||||
}
|
||||
if err != nil {
|
||||
return errors.WithMessagef(err, "Failed to download %q", tarball)
|
||||
return fmt.Errorf("Failed to download %q: %w", tarball, err)
|
||||
}
|
||||
|
||||
// Force gpg checks when using http
|
||||
@@ -75,10 +75,10 @@ func (s *alpineLinux) Run() error {
|
||||
s.definition.Source.Keys,
|
||||
s.definition.Source.Keyserver)
|
||||
if err != nil {
|
||||
return errors.WithMessagef(err, "Failed to download %q", tarball+".asc")
|
||||
return fmt.Errorf("Failed to download %q: %w", tarball+".asc", err)
|
||||
}
|
||||
if !valid {
|
||||
return errors.Errorf("Invalid signature for %q", filepath.Join(fpath, fname))
|
||||
return fmt.Errorf("Invalid signature for %q", filepath.Join(fpath, fname))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -87,7 +87,7 @@ func (s *alpineLinux) Run() error {
|
||||
// Unpack
|
||||
err = lxd.Unpack(filepath.Join(fpath, fname), s.rootfsDir, false, false, nil)
|
||||
if err != nil {
|
||||
return errors.WithMessagef(err, "Failed to unpack %q", fname)
|
||||
return fmt.Errorf("Failed to unpack %q: %w", fname, err)
|
||||
}
|
||||
|
||||
// Handle edge builds
|
||||
@@ -95,19 +95,19 @@ func (s *alpineLinux) Run() error {
|
||||
// Upgrade to edge
|
||||
exitChroot, err := shared.SetupChroot(s.rootfsDir, s.definition.Environment, nil)
|
||||
if err != nil {
|
||||
return errors.WithMessage(err, "Failed to set up chroot")
|
||||
return fmt.Errorf("Failed to set up chroot: %w", err)
|
||||
}
|
||||
|
||||
err = shared.RunCommand("sed", "-i", "-e", "s/v[[:digit:]]\\.[[:digit:]]\\+/edge/g", "/etc/apk/repositories")
|
||||
if err != nil {
|
||||
exitChroot()
|
||||
return errors.WithMessage(err, "Failed to edit apk repositories")
|
||||
return fmt.Errorf("Failed to edit apk repositories: %w", err)
|
||||
}
|
||||
|
||||
err = shared.RunCommand("apk", "upgrade", "--update-cache", "--available")
|
||||
if err != nil {
|
||||
exitChroot()
|
||||
return errors.WithMessage(err, "Failed to upgrade edge build")
|
||||
return fmt.Errorf("Failed to upgrade edge build: %w", err)
|
||||
}
|
||||
|
||||
exitChroot()
|
||||
@@ -116,7 +116,7 @@ func (s *alpineLinux) Run() error {
|
||||
// Fix bad permissions in Alpine tarballs
|
||||
err = os.Chmod(s.rootfsDir, 0755)
|
||||
if err != nil {
|
||||
return errors.WithMessagef(err, "Failed to chmod %q", s.rootfsDir)
|
||||
return fmt.Errorf("Failed to chmod %q: %w", s.rootfsDir, err)
|
||||
}
|
||||
|
||||
return nil
|
||||
|
||||
@@ -2,13 +2,13 @@ package sources
|
||||
|
||||
import (
|
||||
"crypto/sha256"
|
||||
"errors"
|
||||
"fmt"
|
||||
"net/url"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
|
||||
lxd "github.com/lxc/lxd/shared"
|
||||
"github.com/pkg/errors"
|
||||
|
||||
"github.com/lxc/distrobuilder/shared"
|
||||
)
|
||||
@@ -28,7 +28,7 @@ func (s *altLinux) Run() error {
|
||||
|
||||
url, err := url.Parse(baseURL)
|
||||
if err != nil {
|
||||
return errors.WithMessagef(err, "Failed to parse URL %q", baseURL)
|
||||
return fmt.Errorf("Failed to parse URL %q: %w", baseURL, err)
|
||||
}
|
||||
|
||||
checksumFile := ""
|
||||
@@ -39,12 +39,12 @@ func (s *altLinux) Run() error {
|
||||
|
||||
fpath, err := shared.DownloadHash(s.definition.Image, checksumFile+".gpg", "", nil)
|
||||
if err != nil {
|
||||
return errors.WithMessagef(err, "Failed to download %q", checksumFile+".gpg")
|
||||
return fmt.Errorf("Failed to download %q: %w", checksumFile+".gpg", err)
|
||||
}
|
||||
|
||||
_, err = shared.DownloadHash(s.definition.Image, checksumFile, "", nil)
|
||||
if err != nil {
|
||||
return errors.WithMessagef(err, "Failed to download %q", checksumFile)
|
||||
return fmt.Errorf("Failed to download %q: %w", checksumFile, err)
|
||||
}
|
||||
|
||||
valid, err := shared.VerifyFile(
|
||||
@@ -53,10 +53,10 @@ func (s *altLinux) Run() error {
|
||||
s.definition.Source.Keys,
|
||||
s.definition.Source.Keyserver)
|
||||
if err != nil {
|
||||
return errors.WithMessage(err, "Failed to verify file")
|
||||
return fmt.Errorf("Failed to verify file: %w", err)
|
||||
}
|
||||
if !valid {
|
||||
return errors.Errorf("Invalid signature for %q", "SHA256SUMS")
|
||||
return fmt.Errorf("Invalid signature for %q", "SHA256SUMS")
|
||||
}
|
||||
} else {
|
||||
// Force gpg checks when using http
|
||||
@@ -68,7 +68,7 @@ func (s *altLinux) Run() error {
|
||||
|
||||
fpath, err := shared.DownloadHash(s.definition.Image, baseURL+fname, checksumFile, sha256.New())
|
||||
if err != nil {
|
||||
return errors.WithMessagef(err, "Failed to download %q", baseURL+fname)
|
||||
return fmt.Errorf("Failed to download %q: %w", baseURL+fname, err)
|
||||
}
|
||||
|
||||
s.logger.Infow("Unpacking image", "file", filepath.Join(fpath, fname))
|
||||
@@ -76,7 +76,7 @@ func (s *altLinux) Run() error {
|
||||
// Unpack
|
||||
err = lxd.Unpack(filepath.Join(fpath, fname), s.rootfsDir, false, false, nil)
|
||||
if err != nil {
|
||||
return errors.WithMessagef(err, "Failed to unpack %q", fname)
|
||||
return fmt.Errorf("Failed to unpack %q: %w", fname, err)
|
||||
}
|
||||
|
||||
return nil
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package sources
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"net/http"
|
||||
@@ -10,7 +11,6 @@ import (
|
||||
"strings"
|
||||
|
||||
lxd "github.com/lxc/lxd/shared"
|
||||
"github.com/pkg/errors"
|
||||
|
||||
"github.com/lxc/distrobuilder/shared"
|
||||
)
|
||||
@@ -30,7 +30,7 @@ func (s *apertis) Run() error {
|
||||
|
||||
resp, err := http.Head(baseURL)
|
||||
if err != nil {
|
||||
return errors.WithMessagef(err, "Failed to HEAD %q", baseURL)
|
||||
return fmt.Errorf("Failed to HEAD %q: %w", baseURL, err)
|
||||
}
|
||||
|
||||
if resp.StatusCode == http.StatusNotFound {
|
||||
@@ -42,7 +42,7 @@ func (s *apertis) Run() error {
|
||||
} else {
|
||||
exactRelease, err = s.getLatestRelease(baseURL, release)
|
||||
if err != nil {
|
||||
return errors.WithMessage(err, "Failed to get latest release")
|
||||
return fmt.Errorf("Failed to get latest release: %w", err)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -53,7 +53,7 @@ func (s *apertis) Run() error {
|
||||
|
||||
url, err := url.Parse(baseURL)
|
||||
if err != nil {
|
||||
return errors.WithMessagef(err, "Failed to parse %q", baseURL)
|
||||
return fmt.Errorf("Failed to parse %q: %w", baseURL, err)
|
||||
}
|
||||
|
||||
// Force gpg checks when using http
|
||||
@@ -63,7 +63,7 @@ func (s *apertis) Run() error {
|
||||
|
||||
fpath, err := shared.DownloadHash(s.definition.Image, baseURL+fname, "", nil)
|
||||
if err != nil {
|
||||
return errors.WithMessagef(err, "Failed to download %q", baseURL+fname)
|
||||
return fmt.Errorf("Failed to download %q: %w", baseURL+fname, err)
|
||||
}
|
||||
|
||||
s.logger.Infow("Unpacking image", "file", filepath.Join(fpath, fname))
|
||||
@@ -71,7 +71,7 @@ func (s *apertis) Run() error {
|
||||
// Unpack
|
||||
err = lxd.Unpack(filepath.Join(fpath, fname), s.rootfsDir, false, false, nil)
|
||||
if err != nil {
|
||||
return errors.WithMessagef(err, "Failed to unpack %q", fname)
|
||||
return fmt.Errorf("Failed to unpack %q: %w", fname, err)
|
||||
}
|
||||
|
||||
return nil
|
||||
@@ -80,13 +80,13 @@ func (s *apertis) Run() error {
|
||||
func (s *apertis) getLatestRelease(baseURL, release string) (string, error) {
|
||||
resp, err := http.Get(baseURL)
|
||||
if err != nil {
|
||||
return "", errors.WithMessagef(err, "Failed to GET %q", baseURL)
|
||||
return "", fmt.Errorf("Failed to GET %q: %w", baseURL, err)
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
|
||||
body, err := ioutil.ReadAll(resp.Body)
|
||||
if err != nil {
|
||||
return "", errors.WithMessage(err, "Failed to ready body")
|
||||
return "", fmt.Errorf("Failed to ready body: %w", err)
|
||||
}
|
||||
|
||||
regex := regexp.MustCompile(fmt.Sprintf(">(%s\\.\\d+)/<", release))
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package sources
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"net/url"
|
||||
"os"
|
||||
@@ -11,7 +12,6 @@ import (
|
||||
"strings"
|
||||
|
||||
"github.com/lxc/distrobuilder/shared"
|
||||
"github.com/pkg/errors"
|
||||
|
||||
lxd "github.com/lxc/lxd/shared"
|
||||
"gopkg.in/antchfx/htmlquery.v1"
|
||||
@@ -33,7 +33,7 @@ func (s *archlinux) Run() error {
|
||||
// Get latest release
|
||||
release, err = s.getLatestRelease(s.definition.Source.URL, s.definition.Image.ArchitectureMapped)
|
||||
if err != nil {
|
||||
return errors.WithMessage(err, "Failed to get latest release")
|
||||
return fmt.Errorf("Failed to get latest release: %w", err)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -53,7 +53,7 @@ func (s *archlinux) Run() error {
|
||||
|
||||
url, err := url.Parse(tarball)
|
||||
if err != nil {
|
||||
return errors.WithMessagef(err, "Failed to parse URL %q", tarball)
|
||||
return fmt.Errorf("Failed to parse URL %q: %w", tarball, err)
|
||||
}
|
||||
|
||||
if !s.definition.Source.SkipVerification && url.Scheme != "https" &&
|
||||
@@ -63,7 +63,7 @@ func (s *archlinux) Run() error {
|
||||
|
||||
fpath, err := shared.DownloadHash(s.definition.Image, tarball, "", nil)
|
||||
if err != nil {
|
||||
return errors.WithMessagef(err, "Failed to download %q", tarball)
|
||||
return fmt.Errorf("Failed to download %q: %w", tarball, err)
|
||||
}
|
||||
|
||||
// Force gpg checks when using http
|
||||
@@ -76,10 +76,10 @@ func (s *archlinux) Run() error {
|
||||
s.definition.Source.Keys,
|
||||
s.definition.Source.Keyserver)
|
||||
if err != nil {
|
||||
return errors.WithMessagef(err, "Failed to verify %q", fname)
|
||||
return fmt.Errorf("Failed to verify %q: %w", fname, err)
|
||||
}
|
||||
if !valid {
|
||||
return errors.Errorf("Invalid signature for %q", fname)
|
||||
return fmt.Errorf("Invalid signature for %q", fname)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -88,7 +88,7 @@ func (s *archlinux) Run() error {
|
||||
// Unpack
|
||||
err = lxd.Unpack(filepath.Join(fpath, fname), s.rootfsDir, false, false, nil)
|
||||
if err != nil {
|
||||
return errors.WithMessagef(err, "Failed to unpack file %q", filepath.Join(fpath, fname))
|
||||
return fmt.Errorf("Failed to unpack file %q: %w", filepath.Join(fpath, fname), err)
|
||||
}
|
||||
|
||||
// Move everything inside 'root.<architecture>' (which was is the tarball) to its
|
||||
@@ -96,13 +96,13 @@ func (s *archlinux) Run() error {
|
||||
files, err := filepath.Glob(fmt.Sprintf("%s/*", filepath.Join(s.rootfsDir,
|
||||
"root."+s.definition.Image.ArchitectureMapped)))
|
||||
if err != nil {
|
||||
return errors.WithMessage(err, "Failed to get files")
|
||||
return fmt.Errorf("Failed to get files: %w", err)
|
||||
}
|
||||
|
||||
for _, file := range files {
|
||||
err = os.Rename(file, filepath.Join(s.rootfsDir, path.Base(file)))
|
||||
if err != nil {
|
||||
return errors.WithMessagef(err, "Failed to rename file %q", file)
|
||||
return fmt.Errorf("Failed to rename file %q: %w", file, err)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -110,7 +110,7 @@ func (s *archlinux) Run() error {
|
||||
|
||||
err = os.RemoveAll(path)
|
||||
if err != nil {
|
||||
return errors.WithMessagef(err, "Failed to remove %q", path)
|
||||
return fmt.Errorf("Failed to remove %q: %w", path, err)
|
||||
}
|
||||
|
||||
return nil
|
||||
@@ -119,7 +119,7 @@ func (s *archlinux) Run() error {
|
||||
func (s *archlinux) getLatestRelease(URL string, arch string) (string, error) {
|
||||
doc, err := htmlquery.LoadURL(URL)
|
||||
if err != nil {
|
||||
return "", errors.WithMessagef(err, "Failed to load URL %q", URL)
|
||||
return "", fmt.Errorf("Failed to load URL %q: %w", URL, err)
|
||||
}
|
||||
|
||||
re := regexp.MustCompile(`^\d{4}\.\d{2}\.\d{2}/?$`)
|
||||
|
||||
@@ -9,7 +9,6 @@ import (
|
||||
"path/filepath"
|
||||
|
||||
lxd "github.com/lxc/lxd/shared"
|
||||
"github.com/pkg/errors"
|
||||
|
||||
"github.com/lxc/distrobuilder/shared"
|
||||
)
|
||||
@@ -35,14 +34,14 @@ func (s *busybox) Run() error {
|
||||
fpath, err = shared.DownloadHash(s.definition.Image, tarball, tarball+".sha256", sha256.New())
|
||||
}
|
||||
if err != nil {
|
||||
return errors.WithMessagef(err, "Failed to download %q", tarball)
|
||||
return fmt.Errorf("Failed to download %q: %w", tarball, err)
|
||||
}
|
||||
|
||||
sourceDir := filepath.Join(s.cacheDir, "src")
|
||||
|
||||
err = os.MkdirAll(sourceDir, 0755)
|
||||
if err != nil {
|
||||
return errors.WithMessagef(err, "Failed to create directory %q", sourceDir)
|
||||
return fmt.Errorf("Failed to create directory %q: %w", sourceDir, err)
|
||||
}
|
||||
|
||||
s.logger.Infow("Unpacking image", "file", filepath.Join(fpath, fname))
|
||||
@@ -50,7 +49,7 @@ func (s *busybox) Run() error {
|
||||
// Unpack
|
||||
err = lxd.Unpack(filepath.Join(fpath, fname), sourceDir, false, false, nil)
|
||||
if err != nil {
|
||||
return errors.WithMessagef(err, "Failed to unpack %q", fname)
|
||||
return fmt.Errorf("Failed to unpack %q: %w", fname, err)
|
||||
}
|
||||
|
||||
sourceDir = filepath.Join(sourceDir, fmt.Sprintf("busybox-%s", s.definition.Image.Release))
|
||||
@@ -73,14 +72,14 @@ mkdir -p "${rootfs_dir}/bin"
|
||||
mv ${source_dir}/busybox "${rootfs_dir}/bin/busybox"
|
||||
`, sourceDir, s.rootfsDir))
|
||||
if err != nil {
|
||||
return errors.WithMessage(err, "Failed to build busybox")
|
||||
return fmt.Errorf("Failed to build busybox: %w", err)
|
||||
}
|
||||
|
||||
var buf bytes.Buffer
|
||||
|
||||
err = lxd.RunCommandWithFds(os.Stdin, &buf, filepath.Join(s.rootfsDir, "bin", "busybox"), "--list-full")
|
||||
if err != nil {
|
||||
return errors.WithMessage(err, "Failed to install busybox")
|
||||
return fmt.Errorf("Failed to install busybox: %w", err)
|
||||
}
|
||||
|
||||
scanner := bufio.NewScanner(&buf)
|
||||
@@ -96,21 +95,21 @@ mv ${source_dir}/busybox "${rootfs_dir}/bin/busybox"
|
||||
|
||||
err = os.MkdirAll(filepath.Dir(path), 0755)
|
||||
if err != nil {
|
||||
return errors.WithMessagef(err, "Failed to create directory %q", filepath.Dir(path))
|
||||
return fmt.Errorf("Failed to create directory %q: %w", filepath.Dir(path), err)
|
||||
}
|
||||
|
||||
s.logger.Debugf("Creating symlink %q -> %q", path, "/bin/busybox")
|
||||
|
||||
err = os.Symlink("/bin/busybox", path)
|
||||
if err != nil {
|
||||
return errors.WithMessagef(err, "Failed to create symlink %q -> /bin/busybox", path)
|
||||
return fmt.Errorf("Failed to create symlink %q -> /bin/busybox: %w", path, err)
|
||||
}
|
||||
}
|
||||
|
||||
for _, path := range []string{"dev", "mnt", "proc", "root", "sys", "tmp"} {
|
||||
err := os.Mkdir(filepath.Join(s.rootfsDir, path), 0755)
|
||||
if err != nil {
|
||||
return errors.WithMessagef(err, "Failed to create directory %q", filepath.Join(s.rootfsDir, path))
|
||||
return fmt.Errorf("Failed to create directory %q: %w", filepath.Join(s.rootfsDir, path), err)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -2,6 +2,7 @@ package sources
|
||||
|
||||
import (
|
||||
"crypto/sha256"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"net/http"
|
||||
@@ -12,8 +13,6 @@ import (
|
||||
"regexp"
|
||||
"strings"
|
||||
|
||||
"github.com/pkg/errors"
|
||||
|
||||
"github.com/lxc/distrobuilder/shared"
|
||||
)
|
||||
|
||||
@@ -39,7 +38,7 @@ func (s *centOS) Run() error {
|
||||
s.fname, err = s.getRelease(s.definition.Source.URL, s.definition.Image.Release,
|
||||
s.definition.Source.Variant, s.definition.Image.ArchitectureMapped)
|
||||
if err != nil {
|
||||
return errors.WithMessage(err, "Failed to get release")
|
||||
return fmt.Errorf("Failed to get release: %w", err)
|
||||
}
|
||||
|
||||
fpath := shared.GetTargetDir(s.definition.Image)
|
||||
@@ -54,7 +53,7 @@ func (s *centOS) Run() error {
|
||||
|
||||
err = s.unpackRaw(tarball, s.rootfsDir, s.rawRunner)
|
||||
if err != nil {
|
||||
return errors.WithMessagef(err, "Failed to unpack %q", tarball)
|
||||
return fmt.Errorf("Failed to unpack %q: %w", tarball, err)
|
||||
}
|
||||
|
||||
return nil
|
||||
@@ -63,7 +62,7 @@ func (s *centOS) Run() error {
|
||||
|
||||
url, err := url.Parse(baseURL)
|
||||
if err != nil {
|
||||
return errors.WithMessagef(err, "Failed to parse URL %q", baseURL)
|
||||
return fmt.Errorf("Failed to parse URL %q: %w", baseURL, err)
|
||||
}
|
||||
|
||||
checksumFile := ""
|
||||
@@ -86,7 +85,7 @@ func (s *centOS) Run() error {
|
||||
|
||||
fpath, err := shared.DownloadHash(s.definition.Image, baseURL+checksumFile, "", nil)
|
||||
if err != nil {
|
||||
return errors.WithMessagef(err, "Failed to download %q", baseURL+checksumFile)
|
||||
return fmt.Errorf("Failed to download %q: %w", baseURL+checksumFile, err)
|
||||
}
|
||||
|
||||
// Only verify file if possible.
|
||||
@@ -94,10 +93,10 @@ func (s *centOS) Run() error {
|
||||
valid, err := shared.VerifyFile(filepath.Join(fpath, checksumFile), "",
|
||||
s.definition.Source.Keys, s.definition.Source.Keyserver)
|
||||
if err != nil {
|
||||
return errors.WithMessagef(err, "Failed to verify %q", checksumFile)
|
||||
return fmt.Errorf("Failed to verify %q: %w", checksumFile, err)
|
||||
}
|
||||
if !valid {
|
||||
return errors.Errorf("Invalid signature for %q", checksumFile)
|
||||
return fmt.Errorf("Invalid signature for %q", checksumFile)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -105,7 +104,7 @@ func (s *centOS) Run() error {
|
||||
|
||||
_, err = shared.DownloadHash(s.definition.Image, baseURL+s.fname, checksumFile, sha256.New())
|
||||
if err != nil {
|
||||
return errors.WithMessagef(err, "Failed to download %q", baseURL+s.fname)
|
||||
return fmt.Errorf("Failed to download %q: %w", baseURL+s.fname, err)
|
||||
}
|
||||
|
||||
source := filepath.Join(fpath, s.fname)
|
||||
@@ -118,7 +117,7 @@ func (s *centOS) Run() error {
|
||||
err = s.unpackISO(source, s.rootfsDir, s.isoRunner)
|
||||
}
|
||||
if err != nil {
|
||||
return errors.WithMessagef(err, "Failed to unpack %q", source)
|
||||
return fmt.Errorf("Failed to unpack %q: %w", source, err)
|
||||
}
|
||||
|
||||
return nil
|
||||
@@ -151,7 +150,7 @@ if [ -e /rootfs/etc/yum.repos.d/CentOS-armhfp-kernel.repo ]; then
|
||||
fi
|
||||
`, s.majorVersion))
|
||||
if err != nil {
|
||||
return errors.WithMessage(err, "Failed to run script")
|
||||
return fmt.Errorf("Failed to run script: %w", err)
|
||||
}
|
||||
|
||||
return nil
|
||||
@@ -338,7 +337,7 @@ yum ${yum_args} --installroot=/rootfs -y --releasever=%s --skip-broken install $
|
||||
rm -rf /rootfs/var/cache/yum
|
||||
`, gpgKeysPath, s.majorVersion))
|
||||
if err != nil {
|
||||
return errors.WithMessage(err, "Failed to run script")
|
||||
return fmt.Errorf("Failed to run script: %w", err)
|
||||
}
|
||||
|
||||
return nil
|
||||
@@ -350,13 +349,13 @@ func (s *centOS) getRelease(URL, release, variant, arch string) (string, error)
|
||||
|
||||
resp, err := http.Get(u)
|
||||
if err != nil {
|
||||
return "", errors.WithMessagef(err, "Failed to get URL %q", u)
|
||||
return "", fmt.Errorf("Failed to get URL %q: %w", u, err)
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
|
||||
body, err := ioutil.ReadAll(resp.Body)
|
||||
if err != nil {
|
||||
return "", errors.WithMessage(err, "Failed to read body")
|
||||
return "", fmt.Errorf("Failed to read body: %w", err)
|
||||
}
|
||||
|
||||
if len(releaseFields) == 3 && !strings.Contains(URL, "vault.centos.org") {
|
||||
|
||||
@@ -8,7 +8,6 @@ import (
|
||||
"strings"
|
||||
|
||||
lxd "github.com/lxc/lxd/shared"
|
||||
"github.com/pkg/errors"
|
||||
|
||||
"github.com/lxc/distrobuilder/shared"
|
||||
)
|
||||
@@ -49,7 +48,7 @@ func (s *debootstrap) Run() error {
|
||||
if len(s.definition.Source.Keys) > 0 {
|
||||
keyring, err := shared.CreateGPGKeyring(s.definition.Source.Keyserver, s.definition.Source.Keys)
|
||||
if err != nil {
|
||||
return errors.WithMessage(err, "Failed to create GPG keyring")
|
||||
return fmt.Errorf("Failed to create GPG keyring: %w", err)
|
||||
}
|
||||
defer os.RemoveAll(path.Dir(keyring))
|
||||
|
||||
@@ -75,7 +74,7 @@ func (s *debootstrap) Run() error {
|
||||
if !lxd.PathExists(scriptPath) && s.definition.Source.SameAs != "" {
|
||||
err := os.Symlink(s.definition.Source.SameAs, scriptPath)
|
||||
if err != nil {
|
||||
return errors.WithMessage(err, "Failed to create symlink")
|
||||
return fmt.Errorf("Failed to create symlink: %w", err)
|
||||
}
|
||||
|
||||
defer os.Remove(scriptPath)
|
||||
@@ -83,7 +82,7 @@ func (s *debootstrap) Run() error {
|
||||
|
||||
err := shared.RunCommand("debootstrap", args...)
|
||||
if err != nil {
|
||||
return errors.WithMessage(err, `Failed to run "debootstrap"`)
|
||||
return fmt.Errorf(`Failed to run "debootstrap": %w`, err)
|
||||
}
|
||||
|
||||
return nil
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
package sources
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
"path/filepath"
|
||||
|
||||
dcapi "github.com/mudler/docker-companion/api"
|
||||
"github.com/pkg/errors"
|
||||
)
|
||||
|
||||
type docker struct {
|
||||
@@ -16,7 +16,7 @@ type docker struct {
|
||||
func (s *docker) Run() error {
|
||||
absRootfsDir, err := filepath.Abs(s.rootfsDir)
|
||||
if err != nil {
|
||||
return errors.WithMessagef(err, "Failed to get absolute path of %s", s.rootfsDir)
|
||||
return fmt.Errorf("Failed to get absolute path of %s: %w", s.rootfsDir, err)
|
||||
}
|
||||
|
||||
// If DOCKER_REGISTRY_BASE is not set it's used default https://registry-1.docker.io
|
||||
@@ -27,7 +27,7 @@ func (s *docker) Run() error {
|
||||
KeepLayers: false,
|
||||
})
|
||||
if err != nil {
|
||||
return errors.WithMessage(err, "Failed to download an unpack image")
|
||||
return fmt.Errorf("Failed to download an unpack image: %w", err)
|
||||
}
|
||||
|
||||
return nil
|
||||
|
||||
@@ -2,6 +2,7 @@ package sources
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"net/http"
|
||||
@@ -11,7 +12,6 @@ import (
|
||||
"sort"
|
||||
|
||||
lxd "github.com/lxc/lxd/shared"
|
||||
"github.com/pkg/errors"
|
||||
|
||||
"github.com/lxc/distrobuilder/shared"
|
||||
)
|
||||
@@ -28,7 +28,7 @@ func (s *fedora) Run() error {
|
||||
// Get latest build
|
||||
build, err := s.getLatestBuild(baseURL, s.definition.Image.Release)
|
||||
if err != nil {
|
||||
return errors.WithMessage(err, "Failed to get latest build")
|
||||
return fmt.Errorf("Failed to get latest build: %w", err)
|
||||
}
|
||||
|
||||
fname := fmt.Sprintf("Fedora-Container-Base-%s-%s.%s.tar.xz",
|
||||
@@ -39,7 +39,7 @@ func (s *fedora) Run() error {
|
||||
|
||||
fpath, err := shared.DownloadHash(s.definition.Image, sourceURL, "", nil)
|
||||
if err != nil {
|
||||
return errors.WithMessagef(err, "Failed to download %q", sourceURL)
|
||||
return fmt.Errorf("Failed to download %q: %w", sourceURL, err)
|
||||
}
|
||||
|
||||
s.logger.Infow("Unpacking image", "file", filepath.Join(fpath, fname))
|
||||
@@ -47,7 +47,7 @@ func (s *fedora) Run() error {
|
||||
// Unpack the base image
|
||||
err = lxd.Unpack(filepath.Join(fpath, fname), s.rootfsDir, false, false, nil)
|
||||
if err != nil {
|
||||
return errors.WithMessagef(err, "Failed to unpack %q", filepath.Join(fpath, fname))
|
||||
return fmt.Errorf("Failed to unpack %q: %w", filepath.Join(fpath, fname), err)
|
||||
}
|
||||
|
||||
s.logger.Info("Unpacking layers")
|
||||
@@ -55,7 +55,7 @@ func (s *fedora) Run() error {
|
||||
// Unpack the rest of the image (/bin, /sbin, /usr, etc.)
|
||||
err = s.unpackLayers(s.rootfsDir)
|
||||
if err != nil {
|
||||
return errors.WithMessage(err, "Failed to unpack")
|
||||
return fmt.Errorf("Failed to unpack: %w", err)
|
||||
}
|
||||
|
||||
return nil
|
||||
@@ -65,13 +65,13 @@ func (s *fedora) unpackLayers(rootfsDir string) error {
|
||||
// Read manifest file which contains the path to the layers
|
||||
file, err := os.Open(filepath.Join(rootfsDir, "manifest.json"))
|
||||
if err != nil {
|
||||
return errors.WithMessagef(err, "Failed to open %q", filepath.Join(rootfsDir, "manifest.json"))
|
||||
return fmt.Errorf("Failed to open %q: %w", filepath.Join(rootfsDir, "manifest.json"), err)
|
||||
}
|
||||
defer file.Close()
|
||||
|
||||
data, err := ioutil.ReadAll(file)
|
||||
if err != nil {
|
||||
return errors.WithMessagef(err, "Failed to read file %q", file.Name())
|
||||
return fmt.Errorf("Failed to read file %q: %w", file.Name(), err)
|
||||
}
|
||||
|
||||
// Structure of the manifest excluding RepoTags
|
||||
@@ -82,7 +82,7 @@ func (s *fedora) unpackLayers(rootfsDir string) error {
|
||||
|
||||
err = json.Unmarshal(data, &manifests)
|
||||
if err != nil {
|
||||
return errors.WithMessage(err, "Failed to unmarshal JSON data")
|
||||
return fmt.Errorf("Failed to unmarshal JSON data: %w", err)
|
||||
}
|
||||
|
||||
pathsToRemove := []string{
|
||||
@@ -98,7 +98,7 @@ func (s *fedora) unpackLayers(rootfsDir string) error {
|
||||
|
||||
err := lxd.Unpack(filepath.Join(rootfsDir, layer), rootfsDir, false, false, nil)
|
||||
if err != nil {
|
||||
return errors.WithMessagef(err, "Failed to unpack %q", filepath.Join(rootfsDir, layer))
|
||||
return fmt.Errorf("Failed to unpack %q: %w", filepath.Join(rootfsDir, layer), err)
|
||||
}
|
||||
|
||||
pathsToRemove = append(pathsToRemove,
|
||||
@@ -111,14 +111,14 @@ func (s *fedora) unpackLayers(rootfsDir string) error {
|
||||
// Clean up /tmp since there are unnecessary files there
|
||||
files, err := filepath.Glob(filepath.Join(rootfsDir, "tmp", "*"))
|
||||
if err != nil {
|
||||
return errors.WithMessage(err, "Failed to find matching files")
|
||||
return fmt.Errorf("Failed to find matching files: %w", err)
|
||||
}
|
||||
pathsToRemove = append(pathsToRemove, files...)
|
||||
|
||||
// Clean up /root since there are unnecessary files there
|
||||
files, err = filepath.Glob(filepath.Join(rootfsDir, "root", "*"))
|
||||
if err != nil {
|
||||
return errors.WithMessage(err, "Failed to find matching files")
|
||||
return fmt.Errorf("Failed to find matching files: %w", err)
|
||||
}
|
||||
pathsToRemove = append(pathsToRemove, files...)
|
||||
|
||||
@@ -132,13 +132,13 @@ func (s *fedora) unpackLayers(rootfsDir string) error {
|
||||
func (s *fedora) getLatestBuild(URL, release string) (string, error) {
|
||||
resp, err := http.Get(fmt.Sprintf("%s/%s", URL, release))
|
||||
if err != nil {
|
||||
return "", errors.WithMessagef(err, "Failed to GET %q", fmt.Sprintf("%s/%s", URL, release))
|
||||
return "", fmt.Errorf("Failed to GET %q: %w", fmt.Sprintf("%s/%s", URL, release), err)
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
|
||||
content, err := ioutil.ReadAll(resp.Body)
|
||||
if err != nil {
|
||||
return "", errors.WithMessage(err, "Failed to read body")
|
||||
return "", fmt.Errorf("Failed to read body: %w", err)
|
||||
}
|
||||
|
||||
// Builds are formatted in one of two ways:
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package sources
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"net/http"
|
||||
"net/url"
|
||||
@@ -10,7 +11,6 @@ import (
|
||||
"strings"
|
||||
|
||||
lxd "github.com/lxc/lxd/shared"
|
||||
"github.com/pkg/errors"
|
||||
"gopkg.in/antchfx/htmlquery.v1"
|
||||
|
||||
"github.com/lxc/distrobuilder/shared"
|
||||
@@ -39,7 +39,7 @@ func (s *funtoo) Run() error {
|
||||
|
||||
releaseDates, err := s.getReleaseDates(baseURL)
|
||||
if err != nil {
|
||||
return errors.WithMessage(err, "Failed to get release dates")
|
||||
return fmt.Errorf("Failed to get release dates: %w", err)
|
||||
}
|
||||
|
||||
var fname string
|
||||
@@ -52,7 +52,7 @@ func (s *funtoo) Run() error {
|
||||
|
||||
resp, err := http.Head(tarball)
|
||||
if err != nil {
|
||||
return errors.WithMessagef(err, "Failed to call HEAD on %q", tarball)
|
||||
return fmt.Errorf("Failed to call HEAD on %q: %w", tarball, err)
|
||||
}
|
||||
|
||||
if resp.StatusCode == http.StatusNotFound {
|
||||
@@ -64,7 +64,7 @@ func (s *funtoo) Run() error {
|
||||
|
||||
url, err := url.Parse(tarball)
|
||||
if err != nil {
|
||||
return errors.WithMessagef(err, "Failed to parse URL %q", tarball)
|
||||
return fmt.Errorf("Failed to parse URL %q: %w", tarball, err)
|
||||
}
|
||||
|
||||
if !s.definition.Source.SkipVerification && url.Scheme != "https" &&
|
||||
@@ -76,14 +76,14 @@ func (s *funtoo) Run() error {
|
||||
|
||||
fpath, err = shared.DownloadHash(s.definition.Image, tarball, "", nil)
|
||||
if err != nil {
|
||||
return errors.WithMessagef(err, "Failed to download %q", tarball)
|
||||
return fmt.Errorf("Failed to download %q: %w", tarball, err)
|
||||
}
|
||||
|
||||
// Force gpg checks when using http
|
||||
if !s.definition.Source.SkipVerification && url.Scheme != "https" {
|
||||
_, err = shared.DownloadHash(s.definition.Image, tarball+".gpg", "", nil)
|
||||
if err != nil {
|
||||
return errors.WithMessagef(err, "Failed to download %q", tarball+".gpg")
|
||||
return fmt.Errorf("Failed to download %q: %w", tarball+".gpg", err)
|
||||
}
|
||||
|
||||
valid, err := shared.VerifyFile(
|
||||
@@ -92,10 +92,10 @@ func (s *funtoo) Run() error {
|
||||
s.definition.Source.Keys,
|
||||
s.definition.Source.Keyserver)
|
||||
if err != nil {
|
||||
return errors.WithMessage(err, "Failed to verify file")
|
||||
return fmt.Errorf("Failed to verify file: %w", err)
|
||||
}
|
||||
if !valid {
|
||||
return errors.Errorf("Invalid signature for %q", filepath.Join(fpath, fname))
|
||||
return fmt.Errorf("Invalid signature for %q", filepath.Join(fpath, fname))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -104,7 +104,7 @@ func (s *funtoo) Run() error {
|
||||
// Unpack
|
||||
err = lxd.Unpack(filepath.Join(fpath, fname), s.rootfsDir, false, false, nil)
|
||||
if err != nil {
|
||||
return errors.WithMessagef(err, "Failed to unpack %q", filepath.Join(fpath, fname))
|
||||
return fmt.Errorf("Failed to unpack %q: %w", filepath.Join(fpath, fname), err)
|
||||
}
|
||||
|
||||
return nil
|
||||
@@ -113,7 +113,7 @@ func (s *funtoo) Run() error {
|
||||
func (s *funtoo) getReleaseDates(URL string) ([]string, error) {
|
||||
doc, err := htmlquery.LoadURL(URL)
|
||||
if err != nil {
|
||||
return nil, errors.WithMessagef(err, "Failed to load URL %q", URL)
|
||||
return nil, fmt.Errorf("Failed to load URL %q: %w", URL, err)
|
||||
}
|
||||
|
||||
re := regexp.MustCompile(`^\d{4}\-\d{2}\-\d{2}/?$`)
|
||||
|
||||
@@ -2,6 +2,7 @@ package sources
|
||||
|
||||
import (
|
||||
"crypto/sha512"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"net/http"
|
||||
@@ -11,7 +12,6 @@ import (
|
||||
"strings"
|
||||
|
||||
lxd "github.com/lxc/lxd/shared"
|
||||
"github.com/pkg/errors"
|
||||
|
||||
"github.com/lxc/distrobuilder/shared"
|
||||
)
|
||||
@@ -47,14 +47,14 @@ func (s *gentoo) Run() error {
|
||||
|
||||
fname, err := s.getLatestBuild(baseURL, s.definition.Image.ArchitectureMapped, s.definition.Source.Variant)
|
||||
if err != nil {
|
||||
return errors.WithMessage(err, "Failed to get latest build")
|
||||
return fmt.Errorf("Failed to get latest build: %w", err)
|
||||
}
|
||||
|
||||
tarball := fmt.Sprintf("%s/%s", baseURL, fname)
|
||||
|
||||
url, err := url.Parse(tarball)
|
||||
if err != nil {
|
||||
return errors.WithMessagef(err, "Failed to parse %q", tarball)
|
||||
return fmt.Errorf("Failed to parse %q: %w", tarball, err)
|
||||
}
|
||||
|
||||
if !s.definition.Source.SkipVerification && url.Scheme != "https" &&
|
||||
@@ -70,14 +70,14 @@ func (s *gentoo) Run() error {
|
||||
fpath, err = shared.DownloadHash(s.definition.Image, tarball, tarball+".DIGESTS", sha512.New())
|
||||
}
|
||||
if err != nil {
|
||||
return errors.WithMessagef(err, "Failed to download %q", tarball)
|
||||
return fmt.Errorf("Failed to download %q: %w", tarball, err)
|
||||
}
|
||||
|
||||
// Force gpg checks when using http
|
||||
if !s.definition.Source.SkipVerification && url.Scheme != "https" {
|
||||
_, err = shared.DownloadHash(s.definition.Image, tarball+".DIGESTS.asc", "", nil)
|
||||
if err != nil {
|
||||
return errors.WithMessagef(err, "Failed to download %q", tarball+".DIGESTS.asc")
|
||||
return fmt.Errorf("Failed to download %q: %w", tarball+".DIGESTS.asc", err)
|
||||
}
|
||||
|
||||
valid, err := shared.VerifyFile(
|
||||
@@ -86,10 +86,10 @@ func (s *gentoo) Run() error {
|
||||
s.definition.Source.Keys,
|
||||
s.definition.Source.Keyserver)
|
||||
if err != nil {
|
||||
return errors.WithMessagef(err, "Failed to verify %q", filepath.Join(fpath, fname+".DIGESTS.asc"))
|
||||
return fmt.Errorf("Failed to verify %q: %w", filepath.Join(fpath, fname+".DIGESTS.asc"), err)
|
||||
}
|
||||
if !valid {
|
||||
return errors.Errorf("Failed to verify %q", fname+".DIGESTS.asc")
|
||||
return fmt.Errorf("Failed to verify %q", fname+".DIGESTS.asc")
|
||||
}
|
||||
}
|
||||
|
||||
@@ -98,7 +98,7 @@ func (s *gentoo) Run() error {
|
||||
// Unpack
|
||||
err = lxd.Unpack(filepath.Join(fpath, fname), s.rootfsDir, false, false, nil)
|
||||
if err != nil {
|
||||
return errors.WithMessagef(err, "Failed to unpack %q", filepath.Join(fpath, fname))
|
||||
return fmt.Errorf("Failed to unpack %q: %w", filepath.Join(fpath, fname), err)
|
||||
}
|
||||
|
||||
return nil
|
||||
@@ -107,13 +107,13 @@ func (s *gentoo) Run() error {
|
||||
func (s *gentoo) getLatestBuild(baseURL, arch, variant string) (string, error) {
|
||||
resp, err := http.Get(baseURL)
|
||||
if err != nil {
|
||||
return "", errors.WithMessagef(err, "Failed to GET %q", baseURL)
|
||||
return "", fmt.Errorf("Failed to GET %q: %w", baseURL, err)
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
|
||||
body, err := ioutil.ReadAll(resp.Body)
|
||||
if err != nil {
|
||||
return "", errors.WithMessage(err, "Failed to read body")
|
||||
return "", fmt.Errorf("Failed to read body: %w", err)
|
||||
}
|
||||
|
||||
var regex *regexp.Regexp
|
||||
|
||||
@@ -2,6 +2,7 @@ package sources
|
||||
|
||||
import (
|
||||
"crypto/sha256"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
@@ -15,7 +16,6 @@ import (
|
||||
"strings"
|
||||
|
||||
lxd "github.com/lxc/lxd/shared"
|
||||
"github.com/pkg/errors"
|
||||
"gopkg.in/antchfx/htmlquery.v1"
|
||||
|
||||
"github.com/lxc/distrobuilder/shared"
|
||||
@@ -37,35 +37,35 @@ func (s *opensuse) Run() error {
|
||||
tarballPath, err := s.getPathToTarball(s.definition.Source.URL, s.definition.Image.Release,
|
||||
s.definition.Image.ArchitectureMapped)
|
||||
if err != nil {
|
||||
return errors.WithMessage(err, "Failed to get tarball path")
|
||||
return fmt.Errorf("Failed to get tarball path: %w", err)
|
||||
}
|
||||
|
||||
resp, err := http.Head(tarballPath)
|
||||
if err != nil {
|
||||
return errors.WithMessagef(err, "Failed to HEAD %q", tarballPath)
|
||||
return fmt.Errorf("Failed to HEAD %q: %w", tarballPath, err)
|
||||
}
|
||||
|
||||
baseURL, fname = path.Split(resp.Request.URL.String())
|
||||
|
||||
url, err := url.Parse(fmt.Sprintf("%s%s", baseURL, fname))
|
||||
if err != nil {
|
||||
return errors.WithMessagef(err, "Failed to parse %q", fmt.Sprintf("%s%s", baseURL, fname))
|
||||
return fmt.Errorf("Failed to parse %q: %w", fmt.Sprintf("%s%s", baseURL, fname), err)
|
||||
}
|
||||
|
||||
fpath, err := shared.DownloadHash(s.definition.Image, url.String(), "", nil)
|
||||
if err != nil {
|
||||
return errors.WithMessagef(err, "Failed to download %q", url.String())
|
||||
return fmt.Errorf("Failed to download %q: %w", url.String(), err)
|
||||
}
|
||||
|
||||
_, err = shared.DownloadHash(s.definition.Image, url.String()+".sha256", "", nil)
|
||||
if err != nil {
|
||||
return errors.WithMessagef(err, "Failed to download %q", url.String()+".sha256")
|
||||
return fmt.Errorf("Failed to download %q: %w", url.String()+".sha256", err)
|
||||
}
|
||||
|
||||
if !s.definition.Source.SkipVerification {
|
||||
err = s.verifyTarball(filepath.Join(fpath, fname), s.definition)
|
||||
if err != nil {
|
||||
return errors.WithMessagef(err, "Failed to verify %q", filepath.Join(fpath, fname))
|
||||
return fmt.Errorf("Failed to verify %q: %w", filepath.Join(fpath, fname), err)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -74,7 +74,7 @@ func (s *opensuse) Run() error {
|
||||
// Unpack
|
||||
err = lxd.Unpack(filepath.Join(fpath, fname), s.rootfsDir, false, false, nil)
|
||||
if err != nil {
|
||||
return errors.WithMessagef(err, "Failed to unpack %q", filepath.Join(fpath, fname))
|
||||
return fmt.Errorf("Failed to unpack %q: %w", filepath.Join(fpath, fname), err)
|
||||
}
|
||||
|
||||
return nil
|
||||
@@ -93,12 +93,12 @@ func (s *opensuse) verifyTarball(imagePath string, definition shared.Definition)
|
||||
checksum, err = ioutil.ReadFile(checksumPath)
|
||||
}
|
||||
if err != nil {
|
||||
return errors.WithMessage(err, "Failed to read checksum file")
|
||||
return fmt.Errorf("Failed to read checksum file: %w", err)
|
||||
}
|
||||
|
||||
image, err := os.Open(imagePath)
|
||||
if err != nil {
|
||||
return errors.WithMessagef(err, "Failed to open %q", imagePath)
|
||||
return fmt.Errorf("Failed to open %q: %w", imagePath, err)
|
||||
}
|
||||
defer image.Close()
|
||||
|
||||
@@ -106,14 +106,14 @@ func (s *opensuse) verifyTarball(imagePath string, definition shared.Definition)
|
||||
|
||||
_, err = io.Copy(hash, image)
|
||||
if err != nil {
|
||||
return errors.WithMessage(err, "Failed to copy tarball content")
|
||||
return fmt.Errorf("Failed to copy tarball content: %w", err)
|
||||
}
|
||||
|
||||
result := fmt.Sprintf("%x", hash.Sum(nil))
|
||||
checksumStr := strings.TrimSpace(strings.Split(string(checksum), " ")[0])
|
||||
|
||||
if result != checksumStr {
|
||||
return errors.Errorf("Hash mismatch for %s: %s != %s", imagePath, result, checksumStr)
|
||||
return fmt.Errorf("Hash mismatch for %s: %s != %s", imagePath, result, checksumStr)
|
||||
}
|
||||
|
||||
return nil
|
||||
@@ -122,7 +122,7 @@ func (s *opensuse) verifyTarball(imagePath string, definition shared.Definition)
|
||||
func (s *opensuse) getPathToTarball(baseURL string, release string, arch string) (string, error) {
|
||||
u, err := url.Parse(baseURL)
|
||||
if err != nil {
|
||||
return "", errors.WithMessagef(err, "Failed to parse URL %q", baseURL)
|
||||
return "", fmt.Errorf("Failed to parse URL %q: %w", baseURL, err)
|
||||
}
|
||||
|
||||
u.Path = path.Join(u.Path, "repositories", "Virtualization:", "containers:", "images:")
|
||||
@@ -140,12 +140,12 @@ func (s *opensuse) getPathToTarball(baseURL string, release string, arch string)
|
||||
case "s390x":
|
||||
u.Path = path.Join(u.Path, "container_zSystems")
|
||||
default:
|
||||
return "", errors.Errorf("Unsupported architecture %q", arch)
|
||||
return "", fmt.Errorf("Unsupported architecture %q", arch)
|
||||
}
|
||||
|
||||
tarballName, err := s.getTarballName(u, "tumbleweed", arch)
|
||||
if err != nil {
|
||||
return "", errors.WithMessage(err, "Failed to get tarball name")
|
||||
return "", fmt.Errorf("Failed to get tarball name: %w", err)
|
||||
}
|
||||
|
||||
u.Path = path.Join(u.Path, tarballName)
|
||||
@@ -165,7 +165,7 @@ func (s *opensuse) getPathToTarball(baseURL string, release string, arch string)
|
||||
|
||||
tarballName, err := s.getTarballName(u, "leap", arch)
|
||||
if err != nil {
|
||||
return "", errors.WithMessage(err, "Failed to get tarball name")
|
||||
return "", fmt.Errorf("Failed to get tarball name: %w", err)
|
||||
}
|
||||
|
||||
u.Path = path.Join(u.Path, tarballName)
|
||||
@@ -177,7 +177,7 @@ func (s *opensuse) getPathToTarball(baseURL string, release string, arch string)
|
||||
func (s *opensuse) getTarballName(u *url.URL, release, arch string) (string, error) {
|
||||
doc, err := htmlquery.LoadURL(u.String())
|
||||
if err != nil {
|
||||
return "", errors.WithMessagef(err, "Failed to load URL %q", u.String())
|
||||
return "", fmt.Errorf("Failed to load URL %q: %w", u.String(), err)
|
||||
}
|
||||
|
||||
if doc == nil {
|
||||
|
||||
@@ -3,6 +3,7 @@ package sources
|
||||
import (
|
||||
"bufio"
|
||||
"crypto/sha256"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"net/http"
|
||||
@@ -13,7 +14,6 @@ import (
|
||||
"strings"
|
||||
|
||||
lxd "github.com/lxc/lxd/shared"
|
||||
"github.com/pkg/errors"
|
||||
|
||||
"github.com/lxc/distrobuilder/shared"
|
||||
)
|
||||
@@ -51,7 +51,7 @@ func (s *openwrt) Run() error {
|
||||
|
||||
matched, err := regexp.MatchString(`^\d+\.\d+$`, release)
|
||||
if err != nil {
|
||||
return errors.WithMessage(err, "Failed to match release")
|
||||
return fmt.Errorf("Failed to match release: %w", err)
|
||||
}
|
||||
|
||||
if matched {
|
||||
@@ -59,7 +59,7 @@ func (s *openwrt) Run() error {
|
||||
// out the latest service release of the form '18.06.0'.
|
||||
release, err = s.getLatestServiceRelease(baseURL, release)
|
||||
if err != nil {
|
||||
return errors.WithMessage(err, "Failed to get latest service release")
|
||||
return fmt.Errorf("Failed to get latest service release: %w", err)
|
||||
}
|
||||
|
||||
releaseInFilename = strings.ToLower(release) + "-"
|
||||
@@ -102,7 +102,7 @@ func (s *openwrt) Run() error {
|
||||
|
||||
resp, err := http.Head(baseURL)
|
||||
if err != nil {
|
||||
return errors.WithMessagef(err, "Failed to HEAD %q", baseURL)
|
||||
return fmt.Errorf("Failed to HEAD %q: %w", baseURL, err)
|
||||
}
|
||||
|
||||
// Use fallback image "generic"
|
||||
@@ -114,7 +114,7 @@ func (s *openwrt) Run() error {
|
||||
|
||||
url, err := url.Parse(baseURL)
|
||||
if err != nil {
|
||||
return errors.WithMessagef(err, "Failed to parse %q", baseURL)
|
||||
return fmt.Errorf("Failed to parse %q: %w", baseURL, err)
|
||||
}
|
||||
|
||||
checksumFile := ""
|
||||
@@ -123,7 +123,7 @@ func (s *openwrt) Run() error {
|
||||
checksumFile = baseURL + "sha256sums"
|
||||
_, err := shared.DownloadHash(s.definition.Image, checksumFile, "", nil)
|
||||
if err != nil {
|
||||
return errors.WithMessagef(err, "Failed to download %q", checksumFile)
|
||||
return fmt.Errorf("Failed to download %q: %w", checksumFile, err)
|
||||
}
|
||||
} else {
|
||||
// Force gpg checks when using http
|
||||
@@ -135,24 +135,24 @@ func (s *openwrt) Run() error {
|
||||
|
||||
fpath, err := shared.DownloadHash(s.definition.Image, baseURL+fname, checksumFile, sha256.New())
|
||||
if err != nil {
|
||||
return errors.WithMessagef(err, "Failed to download %q", baseURL+fname)
|
||||
return fmt.Errorf("Failed to download %q: %w", baseURL+fname, err)
|
||||
}
|
||||
|
||||
sdk, err := s.getSDK(baseURL, release)
|
||||
if err != nil {
|
||||
return errors.WithMessage(err, "Failed to get SDK")
|
||||
return fmt.Errorf("Failed to get SDK: %w", err)
|
||||
}
|
||||
|
||||
_, err = shared.DownloadHash(s.definition.Image, baseURL+sdk, checksumFile, sha256.New())
|
||||
if err != nil {
|
||||
return errors.WithMessagef(err, "Failed to download %q", baseURL+sdk)
|
||||
return fmt.Errorf("Failed to download %q: %w", baseURL+sdk, err)
|
||||
}
|
||||
|
||||
lxdOpenWrtTarball := "https://github.com/mikma/lxd-openwrt/archive/master.tar.gz"
|
||||
|
||||
_, err = shared.DownloadHash(s.definition.Image, lxdOpenWrtTarball, "", sha256.New())
|
||||
if err != nil {
|
||||
return errors.WithMessagef(err, "Failed to download %q", lxdOpenWrtTarball)
|
||||
return fmt.Errorf("Failed to download %q: %w", lxdOpenWrtTarball, err)
|
||||
}
|
||||
|
||||
tempScriptsDir := filepath.Join(s.cacheDir, "fixes", "lxd-openwrt-master")
|
||||
@@ -160,12 +160,12 @@ func (s *openwrt) Run() error {
|
||||
|
||||
err = os.MkdirAll(tempSDKDir, 0755)
|
||||
if err != nil {
|
||||
return errors.WithMessagef(err, "Failed to create directory %q", tempSDKDir)
|
||||
return fmt.Errorf("Failed to create directory %q: %w", tempSDKDir, err)
|
||||
}
|
||||
|
||||
err = os.MkdirAll(tempScriptsDir, 0755)
|
||||
if err != nil {
|
||||
return errors.WithMessagef(err, "Failed to create directory %q", tempScriptsDir)
|
||||
return fmt.Errorf("Failed to create directory %q: %w", tempScriptsDir, err)
|
||||
}
|
||||
|
||||
s.logger.Infow("Unpacking image", "file", filepath.Join(fpath, fname))
|
||||
@@ -173,26 +173,26 @@ func (s *openwrt) Run() error {
|
||||
// Unpack
|
||||
err = lxd.Unpack(filepath.Join(fpath, fname), s.rootfsDir, false, false, nil)
|
||||
if err != nil {
|
||||
return errors.WithMessagef(err, "Failed to unpack %q", filepath.Join(fpath, fname))
|
||||
return fmt.Errorf("Failed to unpack %q: %w", filepath.Join(fpath, fname), err)
|
||||
}
|
||||
|
||||
s.logger.Infow("Unpacking repository tarball", "file", filepath.Join(fpath, "master.tar.gz"))
|
||||
|
||||
err = lxd.Unpack(filepath.Join(fpath, "master.tar.gz"), filepath.Join(s.cacheDir, "fixes"), false, false, nil)
|
||||
if err != nil {
|
||||
return errors.WithMessagef(err, "Failed to unpack %q", filepath.Join(fpath, "master.tar.gz"))
|
||||
return fmt.Errorf("Failed to unpack %q: %w", filepath.Join(fpath, "master.tar.gz"), err)
|
||||
}
|
||||
|
||||
s.logger.Infow("Unpacking sdk", "file", filepath.Join(fpath, sdk))
|
||||
|
||||
err = lxd.Unpack(filepath.Join(fpath, sdk), tempSDKDir, false, false, nil)
|
||||
if err != nil {
|
||||
return errors.WithMessagef(err, "Failed to unpack %q", filepath.Join(fpath, sdk))
|
||||
return fmt.Errorf("Failed to unpack %q: %w", filepath.Join(fpath, sdk), err)
|
||||
}
|
||||
|
||||
currentDir, err := os.Getwd()
|
||||
if err != nil {
|
||||
return errors.WithMessage(err, "Failed to get current working directory")
|
||||
return fmt.Errorf("Failed to get current working directory: %w", err)
|
||||
}
|
||||
defer os.Chdir(currentDir)
|
||||
|
||||
@@ -219,12 +219,12 @@ func (s *openwrt) Run() error {
|
||||
|
||||
err = os.Chdir(tempScriptsDir)
|
||||
if err != nil {
|
||||
return errors.WithMessagef(err, "Failed to change the current working directory to %q", tempScriptsDir)
|
||||
return fmt.Errorf("Failed to change the current working directory to %q: %w", tempScriptsDir, err)
|
||||
}
|
||||
|
||||
f, err := os.Open("build.sh")
|
||||
if err != nil {
|
||||
return errors.WithMessage(err, `Failed to open "build.sh"`)
|
||||
return fmt.Errorf(`Failed to open "build.sh": %w`, err)
|
||||
}
|
||||
|
||||
var newContent strings.Builder
|
||||
@@ -256,12 +256,12 @@ func (s *openwrt) Run() error {
|
||||
|
||||
err = ioutil.WriteFile("build.sh", []byte(newContent.String()), 0755)
|
||||
if err != nil {
|
||||
return errors.WithMessage(err, `Failed to write to build.sh"`)
|
||||
return fmt.Errorf(`Failed to write to build.sh": %w`, err)
|
||||
}
|
||||
|
||||
f, err = os.Open("scripts/build_rootfs.sh")
|
||||
if err != nil {
|
||||
return errors.WithMessage(err, `Failed to open "scripts/build_rootfs.sh"`)
|
||||
return fmt.Errorf(`Failed to open "scripts/build_rootfs.sh": %w`, err)
|
||||
}
|
||||
|
||||
newContent.Reset()
|
||||
@@ -294,12 +294,12 @@ func (s *openwrt) Run() error {
|
||||
|
||||
err = ioutil.WriteFile("scripts/build_rootfs.sh", []byte(newContent.String()), 0755)
|
||||
if err != nil {
|
||||
return errors.WithMessage(err, `Failed to write to "scripts/build_rootfs.sh"`)
|
||||
return fmt.Errorf(`Failed to write to "scripts/build_rootfs.sh": %w`, err)
|
||||
}
|
||||
|
||||
_, err = lxd.RunCommand("sh", "build.sh")
|
||||
if err != nil {
|
||||
return errors.WithMessage(err, `Failed to run "build.sh"`)
|
||||
return fmt.Errorf(`Failed to run "build.sh": %w`, err)
|
||||
}
|
||||
|
||||
return nil
|
||||
@@ -308,13 +308,13 @@ func (s *openwrt) Run() error {
|
||||
func (s *openwrt) getLatestServiceRelease(baseURL, release string) (string, error) {
|
||||
resp, err := http.Get(baseURL)
|
||||
if err != nil {
|
||||
return "", errors.WithMessagef(err, "Failed to GET %q", baseURL)
|
||||
return "", fmt.Errorf("Failed to GET %q: %w", baseURL, err)
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
|
||||
body, err := ioutil.ReadAll(resp.Body)
|
||||
if err != nil {
|
||||
return "", errors.WithMessage(err, "Failed to ready body")
|
||||
return "", fmt.Errorf("Failed to ready body: %w", err)
|
||||
}
|
||||
|
||||
regex := regexp.MustCompile(fmt.Sprintf(">(%s\\.\\d+)<", release))
|
||||
@@ -330,13 +330,13 @@ func (s *openwrt) getLatestServiceRelease(baseURL, release string) (string, erro
|
||||
func (s *openwrt) getSDK(baseURL, release string) (string, error) {
|
||||
resp, err := http.Get(baseURL)
|
||||
if err != nil {
|
||||
return "", errors.WithMessagef(err, "Failed to GET %q", baseURL)
|
||||
return "", fmt.Errorf("Failed to GET %q: %w", baseURL, err)
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
|
||||
body, err := ioutil.ReadAll(resp.Body)
|
||||
if err != nil {
|
||||
return "", errors.WithMessage(err, "Failed to read body")
|
||||
return "", fmt.Errorf("Failed to read body: %w", err)
|
||||
}
|
||||
|
||||
if release == "snapshot" {
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package sources
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"net/http"
|
||||
"os"
|
||||
@@ -9,7 +10,6 @@ import (
|
||||
"strings"
|
||||
|
||||
lxd "github.com/lxc/lxd/shared"
|
||||
"github.com/pkg/errors"
|
||||
"golang.org/x/sys/unix"
|
||||
"gopkg.in/antchfx/htmlquery.v1"
|
||||
|
||||
@@ -32,7 +32,7 @@ func (s *oraclelinux) Run() error {
|
||||
|
||||
updates, err := s.getUpdates(baseURL)
|
||||
if err != nil {
|
||||
return errors.WithMessage(err, "Failed to get updates")
|
||||
return fmt.Errorf("Failed to get updates: %w", err)
|
||||
}
|
||||
|
||||
var latestUpdate string
|
||||
@@ -65,14 +65,14 @@ func (s *oraclelinux) Run() error {
|
||||
|
||||
fpath, err := shared.DownloadHash(s.definition.Image, source, "", nil)
|
||||
if err != nil {
|
||||
return errors.WithMessagef(err, "Failed to download %q", source)
|
||||
return fmt.Errorf("Failed to download %q: %w", source, err)
|
||||
}
|
||||
|
||||
s.logger.Infow("Unpacking ISO", "file", filepath.Join(fpath, fname))
|
||||
|
||||
err = s.unpackISO(latestUpdate[1:], filepath.Join(fpath, fname), s.rootfsDir)
|
||||
if err != nil {
|
||||
return errors.WithMessage(err, "Failed to unpack ISO")
|
||||
return fmt.Errorf("Failed to unpack ISO: %w", err)
|
||||
}
|
||||
|
||||
return nil
|
||||
@@ -87,14 +87,14 @@ func (s *oraclelinux) unpackISO(latestUpdate, filePath, rootfsDir string) error
|
||||
for _, dir := range []string{isoDir, squashfsDir, roRootDir} {
|
||||
err := os.MkdirAll(dir, 0755)
|
||||
if err != nil {
|
||||
return errors.WithMessagef(err, "Failed to create %q", dir)
|
||||
return fmt.Errorf("Failed to create %q: %w", dir, err)
|
||||
}
|
||||
}
|
||||
|
||||
// this is easier than doing the whole loop thing ourselves
|
||||
err := shared.RunCommand("mount", "-o", "ro", filePath, isoDir)
|
||||
if err != nil {
|
||||
return errors.WithMessagef(err, "Failed to mount %q", filePath)
|
||||
return fmt.Errorf("Failed to mount %q: %w", filePath, err)
|
||||
}
|
||||
defer unix.Unmount(isoDir, 0)
|
||||
|
||||
@@ -106,7 +106,7 @@ func (s *oraclelinux) unpackISO(latestUpdate, filePath, rootfsDir string) error
|
||||
// mount squashfs.img
|
||||
err = shared.RunCommand("mount", "-o", "ro", squashfsImage, squashfsDir)
|
||||
if err != nil {
|
||||
return errors.WithMessagef(err, "Failed to mount %q", squashfsImage)
|
||||
return fmt.Errorf("Failed to mount %q: %w", squashfsImage, err)
|
||||
}
|
||||
defer unix.Unmount(squashfsDir, 0)
|
||||
|
||||
@@ -119,14 +119,14 @@ func (s *oraclelinux) unpackISO(latestUpdate, filePath, rootfsDir string) error
|
||||
// itself
|
||||
err = os.RemoveAll(rootfsDir)
|
||||
if err != nil {
|
||||
return errors.WithMessagef(err, "Failed to remove %q", rootfsDir)
|
||||
return fmt.Errorf("Failed to remove %q: %w", rootfsDir, err)
|
||||
}
|
||||
|
||||
s.logger.Infow("Unpacking root image", "file", rootfsImage)
|
||||
|
||||
err = s.unpackRootfsImage(rootfsImage, tempRootDir)
|
||||
if err != nil {
|
||||
return errors.WithMessagef(err, "Failed to unpack %q", rootfsImage)
|
||||
return fmt.Errorf("Failed to unpack %q: %w", rootfsImage, err)
|
||||
}
|
||||
|
||||
// Determine rpm and yum packages
|
||||
@@ -134,7 +134,7 @@ func (s *oraclelinux) unpackISO(latestUpdate, filePath, rootfsDir string) error
|
||||
|
||||
doc, err := htmlquery.LoadURL(fmt.Sprintf("%s/index.html", baseURL))
|
||||
if err != nil {
|
||||
return errors.WithMessagef(err, "Failed to load URL %q", fmt.Sprintf("%s/index.html", baseURL))
|
||||
return fmt.Errorf("Failed to load URL %q: %w", fmt.Sprintf("%s/index.html", baseURL), err)
|
||||
}
|
||||
|
||||
regexRpm := regexp.MustCompile(`^getPackage/rpm-\d+.+\.rpm$`)
|
||||
@@ -169,13 +169,13 @@ func (s *oraclelinux) unpackISO(latestUpdate, filePath, rootfsDir string) error
|
||||
for _, elem := range array {
|
||||
f, err := os.Create(elem[0])
|
||||
if err != nil {
|
||||
return errors.WithMessagef(err, "Failed to create file %q", elem[0])
|
||||
return fmt.Errorf("Failed to create file %q: %w", elem[0], err)
|
||||
}
|
||||
defer f.Close()
|
||||
|
||||
_, err = lxd.DownloadFileHash(http.DefaultClient, "", nil, nil, elem[0], elem[1], "", nil, f)
|
||||
if err != nil {
|
||||
return errors.WithMessagef(err, "Failed to download %q", elem[1])
|
||||
return fmt.Errorf("Failed to download %q: %w", elem[1], err)
|
||||
}
|
||||
f.Close()
|
||||
}
|
||||
@@ -184,13 +184,13 @@ func (s *oraclelinux) unpackISO(latestUpdate, filePath, rootfsDir string) error
|
||||
// Setup the mounts and chroot into the rootfs
|
||||
exitChroot, err := shared.SetupChroot(tempRootDir, shared.DefinitionEnv{}, nil)
|
||||
if err != nil {
|
||||
return errors.WithMessage(err, "Failed to setup chroot")
|
||||
return fmt.Errorf("Failed to setup chroot: %w", err)
|
||||
}
|
||||
|
||||
if !lxd.PathExists("/bin") && lxd.PathExists("/usr/bin") {
|
||||
err = os.Symlink("/usr/bin", "/bin")
|
||||
if err != nil {
|
||||
return errors.WithMessage(err, "Failed to create /bin symlink")
|
||||
return fmt.Errorf("Failed to create /bin symlink: %w", err)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -261,14 +261,14 @@ EOF
|
||||
`, s.majorVersion, s.architecture))
|
||||
if err != nil {
|
||||
exitChroot()
|
||||
return errors.WithMessage(err, "Failed to run script")
|
||||
return fmt.Errorf("Failed to run script: %w", err)
|
||||
}
|
||||
|
||||
exitChroot()
|
||||
|
||||
err = shared.RsyncLocal(tempRootDir+"/rootfs/", rootfsDir)
|
||||
if err != nil {
|
||||
return errors.WithMessage(err, `Failed to run "rsync"`)
|
||||
return fmt.Errorf(`Failed to run "rsync": %w`, err)
|
||||
}
|
||||
|
||||
return nil
|
||||
@@ -282,12 +282,12 @@ func (s *oraclelinux) getISO(URL string, architecture string) (string, error) {
|
||||
} else if architecture == "aarch64" {
|
||||
re = regexp.MustCompile(fmt.Sprintf("%s-boot-uek(-\\d{8})?.iso", architecture))
|
||||
} else {
|
||||
return "", errors.Errorf("Unsupported architecture %q", architecture)
|
||||
return "", fmt.Errorf("Unsupported architecture %q", architecture)
|
||||
}
|
||||
|
||||
doc, err := htmlquery.LoadURL(URL)
|
||||
if err != nil {
|
||||
return "", errors.WithMessagef(err, "Failed to load URL %q", URL)
|
||||
return "", fmt.Errorf("Failed to load URL %q: %w", URL, err)
|
||||
}
|
||||
|
||||
var isos []string
|
||||
@@ -310,7 +310,7 @@ func (s *oraclelinux) getUpdates(URL string) ([]string, error) {
|
||||
|
||||
doc, err := htmlquery.LoadURL(URL)
|
||||
if err != nil {
|
||||
return nil, errors.WithMessagef(err, "Failed to load URL %q", URL)
|
||||
return nil, fmt.Errorf("Failed to load URL %q: %w", URL, err)
|
||||
}
|
||||
|
||||
var updates []string
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package sources
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"net/url"
|
||||
"path"
|
||||
@@ -9,7 +10,6 @@ import (
|
||||
"strings"
|
||||
|
||||
lxd "github.com/lxc/lxd/shared"
|
||||
"github.com/pkg/errors"
|
||||
"gopkg.in/antchfx/htmlquery.v1"
|
||||
|
||||
"github.com/lxc/distrobuilder/shared"
|
||||
@@ -25,12 +25,12 @@ func (s *plamolinux) Run() error {
|
||||
|
||||
release, err := strconv.Atoi(releaseStr)
|
||||
if err != nil {
|
||||
return errors.WithMessagef(err, "Failed to convert %q", releaseStr)
|
||||
return fmt.Errorf("Failed to convert %q: %w", releaseStr, err)
|
||||
}
|
||||
|
||||
u, err := url.Parse(s.definition.Source.URL)
|
||||
if err != nil {
|
||||
return errors.WithMessagef(err, "Failed to parse %q", s.definition.Source.URL)
|
||||
return fmt.Errorf("Failed to parse %q: %w", s.definition.Source.URL, err)
|
||||
}
|
||||
|
||||
mirrorPath := path.Join(u.Path, fmt.Sprintf("Plamo-%s.x", releaseStr),
|
||||
@@ -51,7 +51,7 @@ func (s *plamolinux) Run() error {
|
||||
|
||||
pkgDir, err = s.downloadFiles(s.definition.Image, u.String(), ignoredPkgs)
|
||||
if err != nil {
|
||||
return errors.WithMessage(err, "Failed to download packages")
|
||||
return fmt.Errorf("Failed to download packages: %w", err)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -66,7 +66,7 @@ func (s *plamolinux) Run() error {
|
||||
|
||||
matches, err := filepath.Glob(filepath.Join(pkgDir, fmt.Sprintf("%s-*.t*z*", pkgTool)))
|
||||
if err != nil {
|
||||
return errors.WithMessage(err, "Failed to match pattern")
|
||||
return fmt.Errorf("Failed to match pattern: %w", err)
|
||||
}
|
||||
|
||||
if len(matches) == 0 {
|
||||
@@ -77,12 +77,12 @@ func (s *plamolinux) Run() error {
|
||||
|
||||
err = shared.RunCommand("tar", "-pxf", matches[0], "-C", pkgDir, "sbin/")
|
||||
if err != nil {
|
||||
return errors.WithMessagef(err, "Failed to unpack %q", matches[0])
|
||||
return fmt.Errorf("Failed to unpack %q: %w", matches[0], err)
|
||||
}
|
||||
|
||||
rootfsDirAbs, err := filepath.Abs(s.rootfsDir)
|
||||
if err != nil {
|
||||
return errors.WithMessage(err, "Failed to get absolute path")
|
||||
return fmt.Errorf("Failed to get absolute path: %w", err)
|
||||
}
|
||||
|
||||
err = shared.RunScript(fmt.Sprintf(`#!/bin/sh
|
||||
@@ -127,7 +127,7 @@ for pkg in $(ls -cr ${PKG_DIR}/*.t*z*); do
|
||||
done
|
||||
`, pkgDir, rootfsDirAbs))
|
||||
if err != nil {
|
||||
return errors.WithMessage(err, "Failed to run script")
|
||||
return fmt.Errorf("Failed to run script: %w", err)
|
||||
}
|
||||
|
||||
return nil
|
||||
@@ -136,7 +136,7 @@ done
|
||||
func (s *plamolinux) downloadFiles(def shared.DefinitionImage, URL string, ignoredPkgs []string) (string, error) {
|
||||
doc, err := htmlquery.LoadURL(URL)
|
||||
if err != nil {
|
||||
return "", errors.WithMessagef(err, "Failed to load URL %q", URL)
|
||||
return "", fmt.Errorf("Failed to load URL %q: %w", URL, err)
|
||||
}
|
||||
|
||||
if doc == nil {
|
||||
@@ -159,13 +159,13 @@ func (s *plamolinux) downloadFiles(def shared.DefinitionImage, URL string, ignor
|
||||
// package
|
||||
dir, err = shared.DownloadHash(def, fmt.Sprintf("%s/%s", URL, target), "", nil)
|
||||
if err != nil {
|
||||
return "", errors.WithMessagef(err, "Failed to download %q", fmt.Sprintf("%s/%s", URL, target))
|
||||
return "", fmt.Errorf("Failed to download %q: %w", fmt.Sprintf("%s/%s", URL, target), err)
|
||||
}
|
||||
} else if strings.HasSuffix(target, ".txz/") || strings.HasSuffix(target, ".tzst/") {
|
||||
// directory
|
||||
u, err := url.Parse(URL)
|
||||
if err != nil {
|
||||
return "", errors.WithMessagef(err, "Failed to parse %q", URL)
|
||||
return "", fmt.Errorf("Failed to parse %q: %w", URL, err)
|
||||
}
|
||||
|
||||
u.Path = path.Join(u.Path, target)
|
||||
|
||||
@@ -11,7 +11,6 @@ import (
|
||||
|
||||
"github.com/lxc/distrobuilder/shared"
|
||||
lxd "github.com/lxc/lxd/shared"
|
||||
"github.com/pkg/errors"
|
||||
"golang.org/x/sys/unix"
|
||||
)
|
||||
|
||||
@@ -28,14 +27,14 @@ func (c *commonRHEL) unpackISO(filePath, rootfsDir string, scriptRunner func(str
|
||||
for _, dir := range []string{isoDir, squashfsDir, roRootDir} {
|
||||
err := os.MkdirAll(dir, 0755)
|
||||
if err != nil {
|
||||
return errors.WithMessagef(err, "Failed to create directory %q", dir)
|
||||
return fmt.Errorf("Failed to create directory %q: %w", dir, err)
|
||||
}
|
||||
}
|
||||
|
||||
// this is easier than doing the whole loop thing ourselves
|
||||
err := shared.RunCommand("mount", "-o", "ro", filePath, isoDir)
|
||||
if err != nil {
|
||||
return errors.WithMessagef(err, "Failed to mount %q", filePath)
|
||||
return fmt.Errorf("Failed to mount %q: %w", filePath, err)
|
||||
}
|
||||
defer unix.Unmount(isoDir, 0)
|
||||
|
||||
@@ -46,7 +45,7 @@ func (c *commonRHEL) unpackISO(filePath, rootfsDir string, scriptRunner func(str
|
||||
// mount squashfs.img
|
||||
err = shared.RunCommand("mount", "-o", "ro", squashfsImage, squashfsDir)
|
||||
if err != nil {
|
||||
return errors.WithMessagef(err, "Failed to mount %q", squashfsImage)
|
||||
return fmt.Errorf("Failed to mount %q: %w", squashfsImage, err)
|
||||
}
|
||||
defer unix.Unmount(squashfsDir, 0)
|
||||
|
||||
@@ -59,14 +58,14 @@ func (c *commonRHEL) unpackISO(filePath, rootfsDir string, scriptRunner func(str
|
||||
// itself
|
||||
err = os.RemoveAll(rootfsDir)
|
||||
if err != nil {
|
||||
return errors.WithMessagef(err, "Failed to remove directory %q", rootfsDir)
|
||||
return fmt.Errorf("Failed to remove directory %q: %w", rootfsDir, err)
|
||||
}
|
||||
|
||||
c.logger.Infow("Unpacking root image", "file", rootfsImage)
|
||||
|
||||
err = c.unpackRootfsImage(rootfsImage, tempRootDir)
|
||||
if err != nil {
|
||||
return errors.WithMessagef(err, "Failed to unpack %q", rootfsImage)
|
||||
return fmt.Errorf("Failed to unpack %q: %w", rootfsImage, err)
|
||||
}
|
||||
|
||||
gpgKeysPath := ""
|
||||
@@ -85,24 +84,24 @@ func (c *commonRHEL) unpackISO(filePath, rootfsDir string, scriptRunner func(str
|
||||
// Create cdrom repo for yum
|
||||
err = os.MkdirAll(filepath.Join(tempRootDir, "mnt", "cdrom"), 0755)
|
||||
if err != nil {
|
||||
return errors.WithMessagef(err, "Failed to create directory %q", filepath.Join(tempRootDir, "mnt", "cdrom"))
|
||||
return fmt.Errorf("Failed to create directory %q: %w", filepath.Join(tempRootDir, "mnt", "cdrom"), err)
|
||||
}
|
||||
|
||||
// Copy repo relevant files to the cdrom
|
||||
err = shared.RsyncLocal(packagesDir, filepath.Join(tempRootDir, "mnt", "cdrom"))
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "Failed to copy Packages")
|
||||
return fmt.Errorf("Failed to copy Packages: %w", err)
|
||||
}
|
||||
|
||||
err = shared.RsyncLocal(repodataDir, filepath.Join(tempRootDir, "mnt", "cdrom"))
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "Failed to copy repodata")
|
||||
return fmt.Errorf("Failed to copy repodata: %w", err)
|
||||
}
|
||||
|
||||
// Find all relevant GPG keys
|
||||
gpgKeys, err := filepath.Glob(filepath.Join(isoDir, "RPM-GPG-KEY-*"))
|
||||
if err != nil {
|
||||
return errors.WithMessage(err, "Failed to match gpg keys")
|
||||
return fmt.Errorf("Failed to match gpg keys: %w", err)
|
||||
}
|
||||
|
||||
// Copy the keys to the cdrom
|
||||
@@ -115,7 +114,7 @@ func (c *commonRHEL) unpackISO(filePath, rootfsDir string, scriptRunner func(str
|
||||
|
||||
err = shared.RsyncLocal(key, filepath.Join(tempRootDir, "mnt", "cdrom"))
|
||||
if err != nil {
|
||||
return errors.WithMessage(err, `Failed to run "rsync"`)
|
||||
return fmt.Errorf(`Failed to run "rsync": %w`, err)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -123,20 +122,20 @@ func (c *commonRHEL) unpackISO(filePath, rootfsDir string, scriptRunner func(str
|
||||
// Setup the mounts and chroot into the rootfs
|
||||
exitChroot, err := shared.SetupChroot(tempRootDir, shared.DefinitionEnv{}, nil)
|
||||
if err != nil {
|
||||
return errors.WithMessage(err, "Failed to setup chroot")
|
||||
return fmt.Errorf("Failed to setup chroot: %w", err)
|
||||
}
|
||||
|
||||
err = scriptRunner(gpgKeysPath)
|
||||
if err != nil {
|
||||
exitChroot()
|
||||
return errors.WithMessage(err, "Failed to run script")
|
||||
return fmt.Errorf("Failed to run script: %w", err)
|
||||
}
|
||||
|
||||
exitChroot()
|
||||
|
||||
err = shared.RsyncLocal(tempRootDir+"/rootfs/", rootfsDir)
|
||||
if err != nil {
|
||||
return errors.WithMessage(err, `Failed to run "rsync"`)
|
||||
return fmt.Errorf(`Failed to run "rsync": %w`, err)
|
||||
}
|
||||
|
||||
return nil
|
||||
@@ -145,13 +144,13 @@ func (c *commonRHEL) unpackISO(filePath, rootfsDir string, scriptRunner func(str
|
||||
func (c *commonRHEL) unpackRootfsImage(imageFile string, target string) error {
|
||||
installDir, err := ioutil.TempDir(c.cacheDir, "temp_")
|
||||
if err != nil {
|
||||
return errors.WithMessage(err, "Failed to create temporary directory")
|
||||
return fmt.Errorf("Failed to create temporary directory: %w", err)
|
||||
}
|
||||
defer os.RemoveAll(installDir)
|
||||
|
||||
err = shared.RunCommand("mount", "-o", "ro", imageFile, installDir)
|
||||
if err != nil {
|
||||
return errors.WithMessagef(err, "Failed to mount %q", imageFile)
|
||||
return fmt.Errorf("Failed to mount %q: %w", imageFile, err)
|
||||
}
|
||||
defer unix.Unmount(installDir, 0)
|
||||
|
||||
@@ -161,13 +160,13 @@ func (c *commonRHEL) unpackRootfsImage(imageFile string, target string) error {
|
||||
if lxd.PathExists(rootfsFile) {
|
||||
rootfsDir, err = ioutil.TempDir(c.cacheDir, "temp_")
|
||||
if err != nil {
|
||||
return errors.WithMessage(err, "Failed to create temporary directory")
|
||||
return fmt.Errorf("Failed to create temporary directory: %w", err)
|
||||
}
|
||||
defer os.RemoveAll(rootfsDir)
|
||||
|
||||
err = shared.RunCommand("mount", "-o", "ro", rootfsFile, rootfsDir)
|
||||
if err != nil {
|
||||
return errors.WithMessagef(err, "Failed to mount %q", rootfsFile)
|
||||
return fmt.Errorf("Failed to mount %q: %w", rootfsFile, err)
|
||||
}
|
||||
defer unix.Unmount(rootfsDir, 0)
|
||||
}
|
||||
@@ -176,7 +175,7 @@ func (c *commonRHEL) unpackRootfsImage(imageFile string, target string) error {
|
||||
// directory in order to create the minimal rootfs.
|
||||
err = shared.RsyncLocal(rootfsDir+"/", target)
|
||||
if err != nil {
|
||||
return errors.WithMessage(err, `Failed to run "rsync"`)
|
||||
return fmt.Errorf(`Failed to run "rsync": %w`, err)
|
||||
}
|
||||
|
||||
return nil
|
||||
@@ -188,14 +187,14 @@ func (c *commonRHEL) unpackRaw(filePath, rootfsDir string, scriptRunner func() e
|
||||
|
||||
err := os.MkdirAll(roRootDir, 0755)
|
||||
if err != nil {
|
||||
return errors.WithMessagef(err, "Failed to create directory %q", roRootDir)
|
||||
return fmt.Errorf("Failed to create directory %q: %w", roRootDir, err)
|
||||
}
|
||||
|
||||
if strings.HasSuffix(filePath, ".raw.xz") {
|
||||
// Uncompress raw image
|
||||
err := shared.RunCommand("unxz", filePath)
|
||||
if err != nil {
|
||||
return errors.WithMessage(err, `Failed to run "unxz"`)
|
||||
return fmt.Errorf(`Failed to run "unxz": %w`, err)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -206,7 +205,7 @@ func (c *commonRHEL) unpackRaw(filePath, rootfsDir string, scriptRunner func() e
|
||||
|
||||
err = lxd.RunCommandWithFds(nil, &buf, "fdisk", "-l", "-o", "Start", rawFilePath)
|
||||
if err != nil {
|
||||
return errors.WithMessage(err, `Failed to run "fdisk"`)
|
||||
return fmt.Errorf(`Failed to run "fdisk": %w`, err)
|
||||
}
|
||||
|
||||
output := strings.Split(buf.String(), "\n")
|
||||
@@ -214,14 +213,14 @@ func (c *commonRHEL) unpackRaw(filePath, rootfsDir string, scriptRunner func() e
|
||||
|
||||
offset, err := strconv.Atoi(offsetStr)
|
||||
if err != nil {
|
||||
return errors.WithMessagef(err, "Failed to convert %q", offsetStr)
|
||||
return fmt.Errorf("Failed to convert %q: %w", offsetStr, err)
|
||||
}
|
||||
|
||||
// Mount the partition read-only since we don't want to accidently modify it.
|
||||
err = shared.RunCommand("mount", "-o", fmt.Sprintf("ro,loop,offset=%d", offset*512),
|
||||
rawFilePath, roRootDir)
|
||||
if err != nil {
|
||||
return errors.WithMessagef(err, "Failed to mount %q", rawFilePath)
|
||||
return fmt.Errorf("Failed to mount %q: %w", rawFilePath, err)
|
||||
}
|
||||
defer unix.Unmount(roRootDir, 0)
|
||||
|
||||
@@ -229,26 +228,26 @@ func (c *commonRHEL) unpackRaw(filePath, rootfsDir string, scriptRunner func() e
|
||||
// directory in order to create the minimal rootfs.
|
||||
err = shared.RsyncLocal(roRootDir+"/", tempRootDir)
|
||||
if err != nil {
|
||||
return errors.WithMessagef(err, `Failed to run "rsync"`)
|
||||
return fmt.Errorf(`Failed to run "rsync": %w`, err)
|
||||
}
|
||||
|
||||
// Setup the mounts and chroot into the rootfs
|
||||
exitChroot, err := shared.SetupChroot(tempRootDir, shared.DefinitionEnv{}, nil)
|
||||
if err != nil {
|
||||
return errors.WithMessage(err, "Failed to setup chroot")
|
||||
return fmt.Errorf("Failed to setup chroot: %w", err)
|
||||
}
|
||||
|
||||
err = scriptRunner()
|
||||
if err != nil {
|
||||
exitChroot()
|
||||
return errors.WithMessage(err, "Failed to run script")
|
||||
return fmt.Errorf("Failed to run script: %w", err)
|
||||
}
|
||||
|
||||
exitChroot()
|
||||
|
||||
err = shared.RsyncLocal(tempRootDir+"/rootfs/", rootfsDir)
|
||||
if err != nil {
|
||||
return errors.WithMessage(err, `Failed to run "rsync"`)
|
||||
return fmt.Errorf(`Failed to run "rsync": %w`, err)
|
||||
}
|
||||
|
||||
return nil
|
||||
|
||||
@@ -2,6 +2,7 @@ package sources
|
||||
|
||||
import (
|
||||
"crypto/sha256"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"net/http"
|
||||
@@ -11,8 +12,6 @@ import (
|
||||
"regexp"
|
||||
"strings"
|
||||
|
||||
"github.com/pkg/errors"
|
||||
|
||||
"github.com/lxc/distrobuilder/shared"
|
||||
)
|
||||
|
||||
@@ -42,7 +41,7 @@ func (s *rockylinux) Run() error {
|
||||
|
||||
url, err := url.Parse(baseURL)
|
||||
if err != nil {
|
||||
return errors.WithMessagef(err, "Failed to parse URL %q", baseURL)
|
||||
return fmt.Errorf("Failed to parse URL %q: %w", baseURL, err)
|
||||
}
|
||||
|
||||
checksumFile := ""
|
||||
@@ -57,21 +56,21 @@ func (s *rockylinux) Run() error {
|
||||
|
||||
_, err := shared.DownloadHash(s.definition.Image, baseURL+checksumFile, "", nil)
|
||||
if err != nil {
|
||||
return errors.WithMessagef(err, "Failed to download %q", baseURL+checksumFile)
|
||||
return fmt.Errorf("Failed to download %q: %w", baseURL+checksumFile, err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
_, err = shared.DownloadHash(s.definition.Image, baseURL+s.fname, checksumFile, sha256.New())
|
||||
if err != nil {
|
||||
return errors.WithMessagef(err, "Failed to download %q", baseURL+s.fname)
|
||||
return fmt.Errorf("Failed to download %q: %w", baseURL+s.fname, err)
|
||||
}
|
||||
|
||||
s.logger.Infow("Unpacking ISO", "file", filepath.Join(fpath, s.fname))
|
||||
|
||||
err = s.unpackISO(filepath.Join(fpath, s.fname), s.rootfsDir, s.isoRunner)
|
||||
if err != nil {
|
||||
return errors.WithMessage(err, "Failed to unpack ISO")
|
||||
return fmt.Errorf("Failed to unpack ISO: %w", err)
|
||||
}
|
||||
|
||||
return nil
|
||||
@@ -158,7 +157,7 @@ yum ${yum_args} --installroot=/rootfs -y --releasever="${RELEASE}" --skip-broken
|
||||
rm -rf /rootfs/var/cache/yum
|
||||
`, gpgKeysPath, s.majorVersion))
|
||||
if err != nil {
|
||||
return errors.WithMessage(err, "Failed to run ISO script")
|
||||
return fmt.Errorf("Failed to run ISO script: %w", err)
|
||||
}
|
||||
|
||||
return nil
|
||||
@@ -169,13 +168,13 @@ func (s *rockylinux) getRelease(URL, release, variant, arch string) (string, err
|
||||
|
||||
resp, err := http.Get(u)
|
||||
if err != nil {
|
||||
return "", errors.WithMessagef(err, "Failed to GET %q", u)
|
||||
return "", fmt.Errorf("Failed to GET %q: %w", u, err)
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
|
||||
body, err := ioutil.ReadAll(resp.Body)
|
||||
if err != nil {
|
||||
return "", errors.WithMessage(err, "Failed to read body")
|
||||
return "", fmt.Errorf("Failed to read body: %w", err)
|
||||
}
|
||||
|
||||
re := s.getRegexes(arch, variant, release)
|
||||
|
||||
@@ -1,11 +1,10 @@
|
||||
package sources
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"path"
|
||||
"path/filepath"
|
||||
|
||||
"github.com/pkg/errors"
|
||||
|
||||
"github.com/lxc/distrobuilder/shared"
|
||||
lxd "github.com/lxc/lxd/shared"
|
||||
)
|
||||
@@ -18,7 +17,7 @@ type rootfs struct {
|
||||
func (s *rootfs) Run() error {
|
||||
fpath, err := shared.DownloadHash(s.definition.Image, s.definition.Source.URL, "", nil)
|
||||
if err != nil {
|
||||
return errors.WithMessagef(err, "Failed to download %q", s.definition.Source.URL)
|
||||
return fmt.Errorf("Failed to download %q: %w", s.definition.Source.URL, err)
|
||||
}
|
||||
|
||||
s.logger.Infow("Unpacking image", "file", filepath.Join(fpath, path.Base(s.definition.Source.URL)))
|
||||
@@ -26,7 +25,7 @@ func (s *rootfs) Run() error {
|
||||
// Unpack
|
||||
err = lxd.Unpack(filepath.Join(fpath, path.Base(s.definition.Source.URL)), s.rootfsDir, false, false, nil)
|
||||
if err != nil {
|
||||
return errors.WithMessagef(err, "Failed to unpack %q", filepath.Join(fpath, path.Base(s.definition.Source.URL)))
|
||||
return fmt.Errorf("Failed to unpack %q: %w", filepath.Join(fpath, path.Base(s.definition.Source.URL)), err)
|
||||
}
|
||||
|
||||
return nil
|
||||
|
||||
@@ -9,7 +9,6 @@ import (
|
||||
"path/filepath"
|
||||
|
||||
lxd "github.com/lxc/lxd/shared"
|
||||
"github.com/pkg/errors"
|
||||
|
||||
"github.com/lxc/distrobuilder/shared"
|
||||
)
|
||||
@@ -28,14 +27,14 @@ func (s *sabayon) Run() error {
|
||||
|
||||
resp, err := http.Head(tarballPath)
|
||||
if err != nil {
|
||||
return errors.WithMessagef(err, "Failed to HEAD %q", tarballPath)
|
||||
return fmt.Errorf("Failed to HEAD %q: %w", tarballPath, err)
|
||||
}
|
||||
|
||||
baseURL, fname = path.Split(resp.Request.URL.String())
|
||||
|
||||
url, err := url.Parse(fmt.Sprintf("%s/%s", baseURL, fname))
|
||||
if err != nil {
|
||||
return errors.WithMessagef(err, "Failed to parse URL %q", fmt.Sprintf("%s/%s", baseURL, fname))
|
||||
return fmt.Errorf("Failed to parse URL %q: %w", fmt.Sprintf("%s/%s", baseURL, fname), err)
|
||||
}
|
||||
|
||||
var fpath string
|
||||
@@ -47,7 +46,7 @@ func (s *sabayon) Run() error {
|
||||
fpath, err = shared.DownloadHash(s.definition.Image, url.String(), url.String()+".md5", md5.New())
|
||||
}
|
||||
if err != nil {
|
||||
return errors.WithMessagef(err, "Failed to download %q", url.String())
|
||||
return fmt.Errorf("Failed to download %q: %w", url.String(), err)
|
||||
}
|
||||
|
||||
s.logger.Infow("Unpacking image", "file", filepath.Join(fpath, fname))
|
||||
@@ -55,7 +54,7 @@ func (s *sabayon) Run() error {
|
||||
// Unpack
|
||||
err = lxd.Unpack(filepath.Join(fpath, fname), s.rootfsDir, false, false, nil)
|
||||
if err != nil {
|
||||
return errors.WithMessagef(err, "Failed to unpack %q", filepath.Join(fpath, fname))
|
||||
return fmt.Errorf("Failed to unpack %q: %w", filepath.Join(fpath, fname), err)
|
||||
}
|
||||
|
||||
return nil
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
package sources
|
||||
|
||||
import (
|
||||
"github.com/pkg/errors"
|
||||
"errors"
|
||||
|
||||
"go.uber.org/zap"
|
||||
|
||||
"github.com/lxc/distrobuilder/shared"
|
||||
|
||||
@@ -5,8 +5,6 @@ import (
|
||||
"path/filepath"
|
||||
"strings"
|
||||
|
||||
"github.com/pkg/errors"
|
||||
|
||||
"github.com/lxc/distrobuilder/shared"
|
||||
)
|
||||
|
||||
@@ -31,14 +29,14 @@ func (s *springdalelinux) Run() error {
|
||||
|
||||
_, err := shared.DownloadHash(s.definition.Image, baseURL+s.fname, "", nil)
|
||||
if err != nil {
|
||||
return errors.WithMessagef(err, "Error downloading %q", baseURL+s.fname)
|
||||
return fmt.Errorf("Error downloading %q: %w", baseURL+s.fname, err)
|
||||
}
|
||||
|
||||
s.logger.Infow("Unpacking ISO", "file", filepath.Join(fpath, s.fname))
|
||||
|
||||
err = s.unpackISO(filepath.Join(fpath, s.fname), s.rootfsDir, s.isoRunner)
|
||||
if err != nil {
|
||||
return errors.WithMessagef(err, "Failed to unpack %q", filepath.Join(fpath, s.fname))
|
||||
return fmt.Errorf("Failed to unpack %q: %w", filepath.Join(fpath, s.fname), err)
|
||||
}
|
||||
|
||||
return nil
|
||||
@@ -180,7 +178,7 @@ yum ${yum_args} --installroot=/rootfs -y --releasever=%s --skip-broken install $
|
||||
rm -rf /rootfs/var/cache/yum
|
||||
`, gpgKeysPath, s.majorVersion))
|
||||
if err != nil {
|
||||
return errors.WithMessage(err, "Failed to run ISO script")
|
||||
return fmt.Errorf("Failed to run ISO script: %w", err)
|
||||
}
|
||||
|
||||
return nil
|
||||
|
||||
@@ -2,6 +2,7 @@ package sources
|
||||
|
||||
import (
|
||||
"crypto/sha256"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
@@ -15,7 +16,6 @@ import (
|
||||
|
||||
"github.com/gobuffalo/packr/v2"
|
||||
lxd "github.com/lxc/lxd/shared"
|
||||
"github.com/pkg/errors"
|
||||
"golang.org/x/sys/unix"
|
||||
|
||||
"github.com/lxc/distrobuilder/shared"
|
||||
@@ -32,7 +32,7 @@ type ubuntu struct {
|
||||
func (s *ubuntu) Run() error {
|
||||
err := s.downloadImage(s.definition)
|
||||
if err != nil {
|
||||
return errors.WithMessage(err, "Failed to download image")
|
||||
return fmt.Errorf("Failed to download image: %w", err)
|
||||
}
|
||||
|
||||
switch strings.ToLower(s.definition.Source.Variant) {
|
||||
@@ -51,7 +51,7 @@ func (s *ubuntu) runCoreVariant(definition shared.Definition, rootfsDir string)
|
||||
if !lxd.PathExists(filepath.Join(s.fpath, strings.TrimSuffix(s.fname, ".xz"))) {
|
||||
err := shared.RunCommand("unxz", "-k", filepath.Join(s.fpath, s.fname))
|
||||
if err != nil {
|
||||
return errors.WithMessagef(err, `Failed to run "unxz"`)
|
||||
return fmt.Errorf(`Failed to run "unxz": %w`, err)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -60,14 +60,14 @@ func (s *ubuntu) runCoreVariant(definition shared.Definition, rootfsDir string)
|
||||
|
||||
output, err := lxd.RunCommand("fdisk", "-l", "-o", "Start", f)
|
||||
if err != nil {
|
||||
return errors.WithMessage(err, `Failed to run "fdisk"`)
|
||||
return fmt.Errorf(`Failed to run "fdisk": %w`, err)
|
||||
}
|
||||
|
||||
lines := strings.Split(output, "\n")
|
||||
|
||||
offset, err := strconv.Atoi(lines[len(lines)-2])
|
||||
if err != nil {
|
||||
return errors.WithMessagef(err, "Failed to convert %q", lines[len(lines)-2])
|
||||
return fmt.Errorf("Failed to convert %q: %w", lines[len(lines)-2], err)
|
||||
}
|
||||
|
||||
imageDir := filepath.Join(s.cacheDir, "image")
|
||||
@@ -77,19 +77,19 @@ func (s *ubuntu) runCoreVariant(definition shared.Definition, rootfsDir string)
|
||||
for _, d := range []string{imageDir, snapsDir, baseImageDir} {
|
||||
err = os.MkdirAll(d, 0755)
|
||||
if err != nil {
|
||||
return errors.WithMessagef(err, "Failed to create directory %q", d)
|
||||
return fmt.Errorf("Failed to create directory %q: %w", d, err)
|
||||
}
|
||||
}
|
||||
|
||||
err = shared.RunCommand("mount", "-o", fmt.Sprintf("loop,offset=%d", offset*512), f, imageDir)
|
||||
if err != nil {
|
||||
return errors.WithMessagef(err, "Failed to mount %q", fmt.Sprintf("loop,offset=%d", offset*512))
|
||||
return fmt.Errorf("Failed to mount %q: %w", fmt.Sprintf("loop,offset=%d", offset*512), err)
|
||||
}
|
||||
defer unix.Unmount(imageDir, 0)
|
||||
|
||||
err = shared.RsyncLocal(filepath.Join(imageDir, "system-data"), rootfsDir)
|
||||
if err != nil {
|
||||
return errors.WithMessage(err, `Failed to run "rsync"`)
|
||||
return fmt.Errorf(`Failed to run "rsync": %w`, err)
|
||||
}
|
||||
|
||||
// Create all the needed paths and links
|
||||
@@ -99,7 +99,7 @@ func (s *ubuntu) runCoreVariant(definition shared.Definition, rootfsDir string)
|
||||
for _, d := range dirs {
|
||||
err := os.Mkdir(filepath.Join(rootfsDir, d), 0755)
|
||||
if err != nil {
|
||||
return errors.WithMessagef(err, "Failed to create directory %q", filepath.Join(rootfsDir, d))
|
||||
return fmt.Errorf("Failed to create directory %q: %w", filepath.Join(rootfsDir, d), err)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -124,7 +124,7 @@ func (s *ubuntu) runCoreVariant(definition shared.Definition, rootfsDir string)
|
||||
for _, l := range links {
|
||||
err = os.Symlink(l.target, l.link)
|
||||
if err != nil {
|
||||
return errors.WithMessagef(err, "Failed to create symlink %q", l.link)
|
||||
return fmt.Errorf("Failed to create symlink %q: %w", l.link, err)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -133,22 +133,22 @@ func (s *ubuntu) runCoreVariant(definition shared.Definition, rootfsDir string)
|
||||
// Download the base Ubuntu image
|
||||
coreImage, err := getLatestCoreBaseImage("https://images.linuxcontainers.org/images", baseDistro, s.definition.Image.ArchitectureMapped)
|
||||
if err != nil {
|
||||
return errors.WithMessage(err, "Failed to get latest core base image")
|
||||
return fmt.Errorf("Failed to get latest core base image: %w", err)
|
||||
}
|
||||
|
||||
_, err = shared.DownloadHash(s.definition.Image, coreImage, "", sha256.New())
|
||||
if err != nil {
|
||||
return errors.WithMessagef(err, "Failed to download %q", coreImage)
|
||||
return fmt.Errorf("Failed to download %q: %w", coreImage, err)
|
||||
}
|
||||
|
||||
err = s.unpack(filepath.Join(s.fpath, "rootfs.tar.xz"), baseImageDir)
|
||||
if err != nil {
|
||||
return errors.WithMessagef(err, "Failed to unpack %q", filepath.Join(s.fpath, "rootfs.tar.xz"))
|
||||
return fmt.Errorf("Failed to unpack %q: %w", filepath.Join(s.fpath, "rootfs.tar.xz"), err)
|
||||
}
|
||||
|
||||
exitChroot, err := shared.SetupChroot(baseImageDir, shared.DefinitionEnv{}, nil)
|
||||
if err != nil {
|
||||
return errors.WithMessage(err, "Failed to create chroot")
|
||||
return fmt.Errorf("Failed to create chroot: %w", err)
|
||||
}
|
||||
|
||||
err = shared.RunScript(`#!/bin/sh
|
||||
@@ -157,36 +157,36 @@ func (s *ubuntu) runCoreVariant(definition shared.Definition, rootfsDir string)
|
||||
`)
|
||||
if err != nil {
|
||||
exitChroot()
|
||||
return errors.WithMessage(err, "Failed to run script")
|
||||
return fmt.Errorf("Failed to run script: %w", err)
|
||||
}
|
||||
|
||||
err = exitChroot()
|
||||
if err != nil {
|
||||
return errors.WithMessage(err, "Failed to exit chroot")
|
||||
return fmt.Errorf("Failed to exit chroot: %w", err)
|
||||
}
|
||||
|
||||
box := packr.New("ubuntu-core", "./data/ubuntu-core")
|
||||
|
||||
file, err := box.Resolve("init")
|
||||
if err != nil {
|
||||
return errors.WithMessage(err, `Failed to resolve "init"`)
|
||||
return fmt.Errorf(`Failed to resolve "init": %w`, err)
|
||||
}
|
||||
defer file.Close()
|
||||
|
||||
target, err := os.Create(filepath.Join(rootfsDir, "bin", "init"))
|
||||
if err != nil {
|
||||
return errors.WithMessagef(err, "Failed to create %q", filepath.Join(rootfsDir, "bin", "init"))
|
||||
return fmt.Errorf("Failed to create %q: %w", filepath.Join(rootfsDir, "bin", "init"), err)
|
||||
}
|
||||
defer target.Close()
|
||||
|
||||
_, err = io.Copy(target, file)
|
||||
if err != nil {
|
||||
return errors.WithMessagef(err, "Failed to copy %q to %q", file.Name(), target.Name())
|
||||
return fmt.Errorf("Failed to copy %q to %q: %w", file.Name(), target.Name(), err)
|
||||
}
|
||||
|
||||
err = target.Chmod(0755)
|
||||
if err != nil {
|
||||
return errors.WithMessagef(err, "Failed to chmod %q", target.Name())
|
||||
return fmt.Errorf("Failed to chmod %q: %w", target.Name(), err)
|
||||
}
|
||||
|
||||
// Copy system binaries
|
||||
@@ -220,12 +220,12 @@ func (s *ubuntu) runCoreVariant(definition shared.Definition, rootfsDir string)
|
||||
for _, b := range binaries {
|
||||
err := lxd.FileCopy(b.source, b.target)
|
||||
if err != nil {
|
||||
return errors.WithMessagef(err, "Failed to copy %q to %q", b.source, b.target)
|
||||
return fmt.Errorf("Failed to copy %q to %q: %w", b.source, b.target, err)
|
||||
}
|
||||
|
||||
err = os.Chmod(b.target, 0755)
|
||||
if err != nil {
|
||||
return errors.WithMessagef(err, "Failed to chmod %q", b.target)
|
||||
return fmt.Errorf("Failed to chmod %q: %w", b.target, err)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -246,7 +246,7 @@ func (s *ubuntu) runCoreVariant(definition shared.Definition, rootfsDir string)
|
||||
for _, p := range patterns {
|
||||
matches, err := filepath.Glob(filepath.Join(baseImageDir, p))
|
||||
if err != nil {
|
||||
return errors.WithMessage(err, "Failed to match pattern")
|
||||
return fmt.Errorf("Failed to match pattern: %w", err)
|
||||
}
|
||||
|
||||
if len(matches) != 1 {
|
||||
@@ -257,7 +257,7 @@ func (s *ubuntu) runCoreVariant(definition shared.Definition, rootfsDir string)
|
||||
|
||||
source, err := os.Readlink(matches[0])
|
||||
if err != nil {
|
||||
return errors.WithMessagef(err, "Failed to read link %q", matches[0])
|
||||
return fmt.Errorf("Failed to read link %q: %w", matches[0], err)
|
||||
}
|
||||
|
||||
// Build absolute path
|
||||
@@ -267,12 +267,12 @@ func (s *ubuntu) runCoreVariant(definition shared.Definition, rootfsDir string)
|
||||
|
||||
err = lxd.FileCopy(source, dest)
|
||||
if err != nil {
|
||||
return errors.WithMessagef(err, "Failed to copy %q to %q", source, dest)
|
||||
return fmt.Errorf("Failed to copy %q to %q: %w", source, dest, err)
|
||||
}
|
||||
|
||||
err = os.Chmod(dest, 0755)
|
||||
if err != nil {
|
||||
return errors.WithMessagef(err, "Failed to chmod %q", dest)
|
||||
return fmt.Errorf("Failed to chmod %q: %w", dest, err)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -296,19 +296,19 @@ func (s *ubuntu) downloadImage(definition shared.Definition) error {
|
||||
s.fname, err = getLatestRelease(baseURL,
|
||||
s.definition.Image.Release, s.definition.Image.ArchitectureMapped)
|
||||
if err != nil {
|
||||
return errors.WithMessage(err, "Failed to get latest release")
|
||||
return fmt.Errorf("Failed to get latest release: %w", err)
|
||||
}
|
||||
}
|
||||
case "core":
|
||||
baseURL = fmt.Sprintf("%s/%s/stable/current/", s.definition.Source.URL, s.definition.Image.Release)
|
||||
s.fname = fmt.Sprintf("ubuntu-core-%s-%s.img.xz", s.definition.Image.Release, s.definition.Image.ArchitectureMapped)
|
||||
default:
|
||||
return errors.Errorf("Unknown Ubuntu variant %q", s.definition.Image.Variant)
|
||||
return fmt.Errorf("Unknown Ubuntu variant %q", s.definition.Image.Variant)
|
||||
}
|
||||
|
||||
url, err := url.Parse(baseURL)
|
||||
if err != nil {
|
||||
return errors.WithMessagef(err, "Failed to parse URL %q", baseURL)
|
||||
return fmt.Errorf("Failed to parse URL %q: %w", baseURL, err)
|
||||
}
|
||||
|
||||
var fpath string
|
||||
@@ -323,12 +323,12 @@ func (s *ubuntu) downloadImage(definition shared.Definition) error {
|
||||
checksumFile = baseURL + "SHA256SUMS"
|
||||
fpath, err = shared.DownloadHash(s.definition.Image, baseURL+"SHA256SUMS.gpg", "", nil)
|
||||
if err != nil {
|
||||
return errors.WithMessagef(err, "Failed to download %q", baseURL+"SHA256SUMS.gpg")
|
||||
return fmt.Errorf("Failed to download %q: %w", baseURL+"SHA256SUMS.gpg", err)
|
||||
}
|
||||
|
||||
_, err = shared.DownloadHash(s.definition.Image, checksumFile, "", nil)
|
||||
if err != nil {
|
||||
return errors.WithMessagef(err, "Failed to download %q", checksumFile)
|
||||
return fmt.Errorf("Failed to download %q: %w", checksumFile, err)
|
||||
}
|
||||
|
||||
valid, err := shared.VerifyFile(
|
||||
@@ -337,7 +337,7 @@ func (s *ubuntu) downloadImage(definition shared.Definition) error {
|
||||
s.definition.Source.Keys,
|
||||
s.definition.Source.Keyserver)
|
||||
if err != nil {
|
||||
return errors.WithMessage(err, `Failed to verify "SHA256SUMS"`)
|
||||
return fmt.Errorf(`Failed to verify "SHA256SUMS": %w`, err)
|
||||
}
|
||||
if !valid {
|
||||
return errors.New(`Invalid signature for "SHA256SUMS"`)
|
||||
@@ -346,7 +346,7 @@ func (s *ubuntu) downloadImage(definition shared.Definition) error {
|
||||
|
||||
s.fpath, err = shared.DownloadHash(s.definition.Image, baseURL+s.fname, checksumFile, sha256.New())
|
||||
if err != nil {
|
||||
return errors.WithMessagef(err, "Failed to download %q", baseURL+s.fname)
|
||||
return fmt.Errorf("Failed to download %q: %w", baseURL+s.fname, err)
|
||||
}
|
||||
|
||||
return nil
|
||||
@@ -355,19 +355,19 @@ func (s *ubuntu) downloadImage(definition shared.Definition) error {
|
||||
func (s ubuntu) unpack(filePath, rootDir string) error {
|
||||
err := os.RemoveAll(rootDir)
|
||||
if err != nil {
|
||||
return errors.WithMessagef(err, "Failed to remove directory %q", rootDir)
|
||||
return fmt.Errorf("Failed to remove directory %q: %w", rootDir, err)
|
||||
}
|
||||
|
||||
err = os.MkdirAll(rootDir, 0755)
|
||||
if err != nil {
|
||||
return errors.WithMessagef(err, "Failed to create directory %q", rootDir)
|
||||
return fmt.Errorf("Failed to create directory %q: %w", rootDir, err)
|
||||
}
|
||||
|
||||
s.logger.Infow("Unpacking file", "file", filePath)
|
||||
|
||||
err = lxd.Unpack(filePath, rootDir, false, false, nil)
|
||||
if err != nil {
|
||||
return errors.WithMessagef(err, "Failed to unpack %q", filePath)
|
||||
return fmt.Errorf("Failed to unpack %q: %w", filePath, err)
|
||||
}
|
||||
|
||||
return nil
|
||||
@@ -376,13 +376,13 @@ func (s ubuntu) unpack(filePath, rootDir string) error {
|
||||
func getLatestRelease(baseURL, release, arch string) (string, error) {
|
||||
resp, err := http.Get(baseURL)
|
||||
if err != nil {
|
||||
return "", errors.WithMessagef(err, "Failed to GET %q", baseURL)
|
||||
return "", fmt.Errorf("Failed to GET %q: %w", baseURL, err)
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
|
||||
body, err := ioutil.ReadAll(resp.Body)
|
||||
if err != nil {
|
||||
return "", errors.WithMessage(err, "Failed to read body")
|
||||
return "", fmt.Errorf("Failed to read body: %w", err)
|
||||
}
|
||||
|
||||
regex := regexp.MustCompile(fmt.Sprintf("ubuntu-base-\\d{2}\\.\\d{2}(\\.\\d+)?-base-%s.tar.gz", arch))
|
||||
@@ -398,18 +398,18 @@ func getLatestRelease(baseURL, release, arch string) (string, error) {
|
||||
func getLatestCoreBaseImage(baseURL, release, arch string) (string, error) {
|
||||
u, err := url.Parse(fmt.Sprintf("%s/ubuntu/%s/%s/default", baseURL, release, arch))
|
||||
if err != nil {
|
||||
return "", errors.WithMessagef(err, "Failed to parse URL %q", fmt.Sprintf("%s/ubuntu/%s/%s/default", baseURL, release, arch))
|
||||
return "", fmt.Errorf("Failed to parse URL %q: %w", fmt.Sprintf("%s/ubuntu/%s/%s/default", baseURL, release, arch), err)
|
||||
}
|
||||
|
||||
resp, err := http.Get(u.String())
|
||||
if err != nil {
|
||||
return "", errors.WithMessagef(err, "Failed to GET %q", u.String())
|
||||
return "", fmt.Errorf("Failed to GET %q: %w", u.String(), err)
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
|
||||
body, err := ioutil.ReadAll(resp.Body)
|
||||
if err != nil {
|
||||
return "", errors.WithMessage(err, "Failed to read body")
|
||||
return "", fmt.Errorf("Failed to read body: %w", err)
|
||||
}
|
||||
|
||||
regex := regexp.MustCompile(`\d{8}_\d{2}:\d{2}`)
|
||||
|
||||
@@ -2,6 +2,7 @@ package sources
|
||||
|
||||
import (
|
||||
"crypto/sha256"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"net/http"
|
||||
@@ -11,7 +12,6 @@ import (
|
||||
"strings"
|
||||
|
||||
lxd "github.com/lxc/lxd/shared"
|
||||
"github.com/pkg/errors"
|
||||
|
||||
"github.com/lxc/distrobuilder/shared"
|
||||
)
|
||||
@@ -25,7 +25,7 @@ func (s *voidlinux) Run() error {
|
||||
baseURL := s.definition.Source.URL
|
||||
fname, err := s.getLatestBuild(baseURL, s.definition.Image.ArchitectureMapped, s.definition.Source.Variant)
|
||||
if err != nil {
|
||||
return errors.WithMessage(err, "Failed to get latest build")
|
||||
return fmt.Errorf("Failed to get latest build: %w", err)
|
||||
}
|
||||
|
||||
if fname == "" {
|
||||
@@ -38,7 +38,7 @@ func (s *voidlinux) Run() error {
|
||||
|
||||
url, err := url.Parse(tarball)
|
||||
if err != nil {
|
||||
return errors.WithMessagef(err, "Failed to parse URL %q", tarball)
|
||||
return fmt.Errorf("Failed to parse URL %q: %w", tarball, err)
|
||||
}
|
||||
|
||||
if !s.definition.Source.SkipVerification && url.Scheme != "https" &&
|
||||
@@ -54,19 +54,19 @@ func (s *voidlinux) Run() error {
|
||||
fpath, err = shared.DownloadHash(s.definition.Image, tarball, digests, sha256.New())
|
||||
}
|
||||
if err != nil {
|
||||
return errors.WithMessagef(err, "Failed to download %q", tarball)
|
||||
return fmt.Errorf("Failed to download %q: %w", tarball, err)
|
||||
}
|
||||
|
||||
// Force gpg checks when using http
|
||||
if !s.definition.Source.SkipVerification && url.Scheme != "https" {
|
||||
_, err = shared.DownloadHash(s.definition.Image, digests, "", nil)
|
||||
if err != nil {
|
||||
return errors.WithMessagef(err, "Failed to download %q", digests)
|
||||
return fmt.Errorf("Failed to download %q: %w", digests, err)
|
||||
}
|
||||
|
||||
_, err = shared.DownloadHash(s.definition.Image, signatures, "", nil)
|
||||
if err != nil {
|
||||
return errors.WithMessagef(err, "Failed to download %q", signatures)
|
||||
return fmt.Errorf("Failed to download %q: %w", signatures, err)
|
||||
}
|
||||
|
||||
valid, err := shared.VerifyFile(
|
||||
@@ -75,7 +75,7 @@ func (s *voidlinux) Run() error {
|
||||
s.definition.Source.Keys,
|
||||
s.definition.Source.Keyserver)
|
||||
if err != nil {
|
||||
return errors.WithMessagef(err, `Failed to verify "sha256sum.txt"`)
|
||||
return fmt.Errorf(`Failed to verify "sha256sum.txt": %w`, err)
|
||||
}
|
||||
if !valid {
|
||||
return errors.New(`Invalid signature for "sha256sum.txt"`)
|
||||
@@ -87,7 +87,7 @@ func (s *voidlinux) Run() error {
|
||||
// Unpack
|
||||
err = lxd.Unpack(filepath.Join(fpath, fname), s.rootfsDir, false, false, nil)
|
||||
if err != nil {
|
||||
return errors.WithMessagef(err, "Failed to unpack %q", filepath.Join(fpath, fname))
|
||||
return fmt.Errorf("Failed to unpack %q: %w", filepath.Join(fpath, fname), err)
|
||||
}
|
||||
|
||||
return nil
|
||||
@@ -96,13 +96,13 @@ func (s *voidlinux) Run() error {
|
||||
func (s *voidlinux) getLatestBuild(baseURL, arch, variant string) (string, error) {
|
||||
resp, err := http.Get(baseURL)
|
||||
if err != nil {
|
||||
return "", errors.WithMessagef(err, "Failed to GET %q", baseURL)
|
||||
return "", fmt.Errorf("Failed to GET %q: %w", baseURL, err)
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
|
||||
body, err := ioutil.ReadAll(resp.Body)
|
||||
if err != nil {
|
||||
return "", errors.WithMessage(err, "Failed to read body")
|
||||
return "", fmt.Errorf("Failed to read body: %w", err)
|
||||
}
|
||||
|
||||
// Look for .tar.xz
|
||||
|
||||
Reference in New Issue
Block a user