blob: 1b199fc49be52e3c61215534b3dcf3f381d601ea [file] [edit]
package kernelmods
import (
"context"
"fmt"
"os"
"path/filepath"
"cos-extensions/tools/gcs"
"cos-extensions/tools/module"
"github.com/golang/glog"
)
var (
retrieveInstalledModules = module.RetrieveInstalledModules
retrieveLocalModulesInfo = module.RetrieveLocalModulesInfo
installModule = module.InstallModule
)
// DownloadModules takes in a list of module file names in a gcs path and copies them to the local directory.
// If recursive is set, it downloads all module files in a gcs path and its subdirectories.
func DownloadModules(ctx context.Context, cfg *gcs.GCSConfig, modFiles []string, localDir string, recursive bool) ([]string, error) {
var downloadedModules []string
var err error
if recursive {
modFiles, err = cfg.ListModules(ctx, recursive)
if err != nil {
return nil, fmt.Errorf("failed to recursively retrieve module files: %v", err)
}
}
for _, moduleFile := range modFiles {
modLocalPath, err := cfg.DownloadKernelModule(ctx, moduleFile, localDir)
if err != nil {
glog.Errorf("Failed to download module (%s) [skipping]: %v", moduleFile, err)
continue
}
downloadedModules = append(downloadedModules, modLocalPath)
glog.Infof("Successfully downloaded module (%s) to file path (%s) ", moduleFile, modLocalPath)
}
return downloadedModules, nil
}
// InstallModules takes in a list of module paths in a local directory and installs them to the kernel
// if they are not already installed.
func InstallModules(modulePaths []string, args []string) ([]string, error) {
var installedModules []string
installedModuleMap, err := retrieveInstalledModules(modulePaths)
if err != nil {
return installedModules, fmt.Errorf("failed to retrieve installed modules: %v", err)
}
for _, modulePath := range modulePaths {
// Skipping if module already installed
if _, ok := installedModuleMap[modulePath]; ok {
glog.Errorf("Failed to install module (%s) [skipping]: Module already installed.", modulePath)
continue
}
// Skipping if failed to install
err = installModule(modulePath, args)
if err != nil {
glog.Errorf("Failed to install module (%s) [skipping]: %v", modulePath, err)
continue
}
installedModules = append(installedModules, modulePath)
glog.Infof("Successfully installed module (%s) with args (%s) ", modulePath, args)
}
return installedModules, nil
}
// ListDownloadedModules lists all the compiled kernel module files
// in a local directory. Identifies module files as files with .ko
// extension.
// It returns a mapping of the module file paths to their name.
func ListDownloadedModules(localDir string, recursive bool) (map[string]string, error) {
var modPaths []string
modPaths, err := retrieveModulePaths(localDir, modPaths, recursive)
if err != nil {
return nil, fmt.Errorf("failed to retrieve module files from directory %s: %v", localDir, err)
}
modFileName := retrieveLocalModulesInfo(modPaths)
return modFileName, nil
}
// ListInstalledModules lists all the loaded kernel modules in a local directory.
// Identifies module files in the directory as files with .ko extension.
// Returns a mapping of the file paths of the loaded modules in the directory to their names.
func ListInstalledModules(localDir string, recursive bool) (map[string]string, error) {
var modPaths []string
modPaths, err := retrieveModulePaths(localDir, modPaths, recursive)
if err != nil {
return nil, fmt.Errorf("failed to retrieve module files from directory %s: %v", localDir, err)
}
installedModules, err := retrieveInstalledModules(modPaths)
if err != nil {
return nil, fmt.Errorf("failed to validate installation of module files %s: %v", modPaths, err)
}
return installedModules, nil
}
// retrieveModulePaths takes in a local directory and returns the
// path of all the modules in that directory. Identifies module files as files with .ko extension.
// If recursive is set, it returns the path of the modules in the subdirectories as well.
func retrieveModulePaths(localDir string, modulePaths []string, recursive bool) ([]string, error) {
if _, err := os.Stat(localDir); err != nil {
return nil, fmt.Errorf("failed to validate local directory (%s): %v", localDir, err)
}
contents, err := os.ReadDir(localDir)
if err != nil {
return nil, fmt.Errorf("failed to read from directory (%s): %v", localDir, err)
}
for _, content := range contents {
contentName := content.Name()
if recursive && content.IsDir() {
dir := filepath.Join(localDir, contentName)
modulePaths, err = retrieveModulePaths(dir, modulePaths, recursive)
if err != nil {
return nil, err
}
}
modPath := filepath.Join(localDir, contentName)
if filepath.Ext(contentName) == ".ko" {
modulePaths = append(modulePaths, modPath)
}
}
return modulePaths, nil
}