cos-dkms: Add pre/post action hooks
Also simplifies running the compile command since it follows the same
pattern.
BUG=b/349400483
TEST=presubmit
Change-Id: I1970e17b85cd8cd38d3a8c7062f038535b049dea
Reviewed-on: https://cos-review.googlesource.com/c/cos/tools/+/86300
Reviewed-by: Oleksandr Tymoshenko <ovt@google.com>
Cloud-Build: GCB Service account <228075978874@cloudbuild.gserviceaccount.com>
Tested-by: Kevin Berry <kpberry@google.com>
diff --git a/src/pkg/dkms/add.go b/src/pkg/dkms/add.go
index b71b6bd..2188a57 100644
--- a/src/pkg/dkms/add.go
+++ b/src/pkg/dkms/add.go
@@ -8,6 +8,7 @@
"cos.googlesource.com/cos/tools.git/src/pkg/fs"
"cos.googlesource.com/cos/tools.git/src/pkg/gcs"
+ "cos.googlesource.com/cos/tools.git/src/pkg/utils"
"github.com/golang/glog"
)
@@ -58,7 +59,22 @@
}
glog.Infof("symlinking package sources from %s to %s", sourceTreeSourceDir, dkmsTreeSourceDir)
- return os.Symlink(sourceTreeSourceDir, dkmsTreeSourceDir)
+ if err := os.Symlink(sourceTreeSourceDir, dkmsTreeSourceDir); err != nil {
+ return err
+ }
+
+ config, err := LoadConfig(pkg)
+ if err != nil {
+ return err
+ }
+
+ if config.PostAdd != "" {
+ if err := utils.RunCommandString(dkmsTreeSourceDir, config.PostAdd); err != nil {
+ return err
+ }
+ }
+
+ return nil
}
// CachedAdd adds a package to the DKMS source tree, downloading
diff --git a/src/pkg/dkms/build.go b/src/pkg/dkms/build.go
index df1e697..2b0baa6 100644
--- a/src/pkg/dkms/build.go
+++ b/src/pkg/dkms/build.go
@@ -50,6 +50,12 @@
return err
}
+ if config.PreBuild != "" {
+ if utils.RunCommandString(pkg.BuildDir(), config.PreBuild); err != nil {
+ return fmt.Errorf("failed to run pre-build script: %v", err)
+ }
+ }
+
if options.InstallBuildDependencies {
if err := InstallBuildDependencies(pkg); err != nil {
return err
@@ -81,10 +87,16 @@
makeCommand := fmt.Sprintf("%s %s", config.MakeCommand, makeVariables)
makeCommand = strings.Trim(makeCommand, " ")
- if err := Compile(buildDir, makeCommand); err != nil {
+ if err := utils.RunCommandString(buildDir, makeCommand); err != nil {
return fmt.Errorf("failed to compile modules: %v", err)
}
+ if config.PostBuild != "" {
+ if err := utils.RunCommandString(buildDir, config.PostBuild); err != nil {
+ return fmt.Errorf("failed to run post-build script: %v", err)
+ }
+ }
+
return nil
}
@@ -160,23 +172,6 @@
return nil
}
-// Compile compiles the sources in a directory using the given command.
-func Compile(dir string, makeCommand string) error {
- glog.Infof("compiling with command: %s", makeCommand)
- // not great, but this is more or less what standard DKMS does
- cmd := exec.Command("bash", "-c", makeCommand)
- cmd.Dir = dir
- out, err := cmd.CombinedOutput()
- if err == nil {
- glog.Info(string(out))
- } else {
- glog.Error(string(out))
- return err
- }
-
- return nil
-}
-
// InstallBuildDependencies downloads and installs the kernel headers and
// compiler toolchain for a package, if they are not already present.
func InstallBuildDependencies(pkg *Package) error {
diff --git a/src/pkg/dkms/build_test.go b/src/pkg/dkms/build_test.go
index a661d71..55754b0 100644
--- a/src/pkg/dkms/build_test.go
+++ b/src/pkg/dkms/build_test.go
@@ -177,21 +177,6 @@
}
}
-func TestCompile(t *testing.T) {
- buildDir := t.TempDir()
- if err := fs.CopyDir("testdata/source-tree/mymodule-1.0", buildDir, 0777); err != nil {
- t.Fatalf("%v", err)
- }
-
- if err := Compile(buildDir, "touch mymodule.ko"); err != nil {
- t.Fatalf("%v", err)
- }
-
- if !fs.IsFile(path.Join(buildDir, "mymodule.ko")) {
- t.Fatalf("expected mymodule.ko to exist after compile command was run")
- }
-}
-
func TestInstallBuildDependencies(t *testing.T) {
downloader := fakeDownloader{}
ctx := context.Background()
diff --git a/src/pkg/dkms/install.go b/src/pkg/dkms/install.go
index dfd3656..614da45 100644
--- a/src/pkg/dkms/install.go
+++ b/src/pkg/dkms/install.go
@@ -11,6 +11,7 @@
"cos.googlesource.com/cos/tools.git/src/pkg/fs"
"cos.googlesource.com/cos/tools.git/src/pkg/gcs"
+ "cos.googlesource.com/cos/tools.git/src/pkg/utils"
"github.com/golang/glog"
)
@@ -45,6 +46,12 @@
return err
}
+ if config.PreInstall != "" {
+ if utils.RunCommandString(pkg.BuildDir(), config.PreInstall); err != nil {
+ return fmt.Errorf("failed to run pre-install script: %v", err)
+ }
+ }
+
var modulesToInstall []Module
if options.ForceVersionOverride {
modulesToInstall = config.Modules
@@ -82,6 +89,12 @@
}
}
+ if config.PostInstall != "" {
+ if utils.RunCommandString(pkg.BuildDir(), config.PostInstall); err != nil {
+ return fmt.Errorf("failed to run post-install script: %v", err)
+ }
+ }
+
return nil
}
diff --git a/src/pkg/dkms/remove.go b/src/pkg/dkms/remove.go
index 9ba83f2..3e46dea 100644
--- a/src/pkg/dkms/remove.go
+++ b/src/pkg/dkms/remove.go
@@ -2,9 +2,11 @@
import (
"context"
+ "fmt"
"os"
"cos.googlesource.com/cos/tools.git/src/pkg/gcs"
+ "cos.googlesource.com/cos/tools.git/src/pkg/utils"
"github.com/golang/glog"
)
@@ -22,9 +24,26 @@
return nil
}
+ // We must load the config before the package is removed in order to use
+ // the correct post-remove script, if applicable
+ config, err := LoadConfig(pkg)
+ if err != nil {
+ return err
+ }
+
sourceDir := pkg.SourceDir()
glog.Info("removing package sources", sourceDir)
- return os.Remove(sourceDir)
+ if err := os.Remove(sourceDir); err != nil {
+ return fmt.Errorf("failed to remove package sources: %v", err)
+ }
+
+ if config.PostRemove != "" {
+ if err := utils.RunCommandString(sourceDir, config.PostRemove); err != nil {
+ return fmt.Errorf("failed to run post-remove script: %v", err)
+ }
+ }
+
+ return nil
}
// Remove removes a package from the local DKMS source tree and from the cache.
diff --git a/src/pkg/utils/shell.go b/src/pkg/utils/shell.go
index d137aa8..4d6aa90 100644
--- a/src/pkg/utils/shell.go
+++ b/src/pkg/utils/shell.go
@@ -3,13 +3,37 @@
import (
"bufio"
"fmt"
- "github.com/golang/glog"
"os"
"os/exec"
"regexp"
"strings"
+
+ "github.com/golang/glog"
)
+// RunCommandString runs a command string from a provided directory and logs
+// the combined stdout and stderr.
+// If there is no error, the output will be logged at Info level. If there is
+// an error, the output will be logged at Error level.
+func RunCommandString(dir string, command string) error {
+ glog.Info(fmt.Sprintf("running command: %s", command))
+ cmd := exec.Command("bash", "-c", command)
+ cmd.Dir = dir
+ out, err := cmd.CombinedOutput()
+ if err == nil {
+ if len(out) > 0 {
+ glog.Info(string(out))
+ }
+ } else {
+ if len(out) > 0 {
+ glog.Error(string(out))
+ }
+ return err
+ }
+
+ return nil
+}
+
// SourceFile sources a bash file and returns the shell variables as a map.
func SourceFile(file string) (map[string]string, error) {
contents, err := os.ReadFile(file)