| package actions |
| |
| import ( |
| goflag "flag" |
| "strings" |
| |
| "cos.googlesource.com/cos/tools.git/src/pkg/dkms" |
| "cos.googlesource.com/cos/tools.git/src/pkg/gcs" |
| "cos.googlesource.com/cos/tools.git/src/pkg/modules" |
| |
| "github.com/golang/glog" |
| "github.com/spf13/cobra" |
| flag "github.com/spf13/pflag" |
| ) |
| |
| var RootTrees = &dkms.Trees{} |
| var RootModuleParams = modules.NewModuleParameters() |
| var RootPackage = &dkms.Package{Trees: RootTrees, ModuleParams: RootModuleParams} |
| var RootGCSBucket *gcs.GCSBucket = nil |
| var RootOptions = &dkms.Options{} |
| |
| // resetState resets all of the global state back to defaults so the root |
| // command can be run again and re-populate the global state correctly. |
| // |
| // This is intended to be used for tests. |
| func resetState() { |
| // We have to be very careful not to change any addresses here; otherwise, |
| // we'll break the root command's flag bindings. |
| *RootTrees = dkms.Trees{} |
| RootModuleParams = modules.NewModuleParameters() |
| *RootPackage = dkms.Package{Trees: RootTrees, ModuleParams: RootModuleParams} |
| RootGCSBucket = nil |
| *RootOptions = dkms.Options{} |
| } |
| |
| var rootCmd = &cobra.Command{ |
| Use: "cos-dkms [action] [options] [module/module-version] [/path/to/source-tree]", |
| Short: "cos-dkms - Dynamic Kernel Module Support for COS", |
| Long: strings.TrimSpace(` |
| cos-dkms can be used to dynamically build kernel modules for COS, download |
| precompiled modules, and upload compiled modules to a GCS bucket. |
| |
| A directory containing sources for one or more kernel modules is referred to |
| as a package. A package may contain a dkms.conf file, which specifies how the |
| package should be built and installed. If no dkms.conf is present in the |
| package, default values will be used for all settings. The dkms.conf format |
| is based on the format used by Dell DKMS (github.com/dell/dkms) and supports |
| the following directives: |
| PACKAGE_NAME (defaults to --package) |
| PACKAGE_VERSION (defaults to --package-version) |
| |
| -- Per-module settings |
| BUILT_MODULE_NAME[#] (defaults to --package) |
| BUILT_MODULE_LOCATION[#] (relative to build directory; defaults to empty path) |
| DEST_MODULE_NAME[#] (defaults to BUILT_MODULE_NAME[#]) |
| DEST_MODULE_LOCATION[#] (relative to install directory; |
| if # is 0, defaults to /kernel/updates; |
| otherwise, defaults to DEST_MODULE_LOCATION[0]) |
| STRIP[#] (if # is 0, defaults to 'yes'; |
| otherwise, defaults to STRIP[0]) |
| |
| -- Command(s) for building the package |
| MAKE[#] (defaults to 'make -C ${kerneltree} M=${build-dir}') |
| MAKE_MATCH[#] (defaults to '.*') |
| |
| -- Command to run when unbuilding the package |
| CLEAN (defaults to 'make -C ${kerneltree} M=${build-dir} clean') |
| |
| -- Patches to apply before building the package |
| PATCH[#] (defaults to empty array) |
| PATCH_MATCH[#] (defaults to empty array) |
| |
| -- List of packages which should be built before this one |
| BUILD_DEPENDS[#] (defaults to empty array) |
| |
| -- Regexes to specify kernel and arch for which this package can be built |
| BUILD_EXCLUSIVE_KERNEL (defaults to '.*') |
| BUILD_EXCLUSIVE_ARCH (defaults to '.*') |
| More directives may be added in the future. |
| |
| In many cases, packages can be managed using only the install and remove |
| subcommands. Internally, install will call the add and build commands to |
| add a package to the DKMS source tree and compile its modules, then |
| install them to a target install tree; and remove will uninstall and unbuild |
| a package, then remove it from the DKMS source tree. See the --help for each |
| subcommand for more details. |
| `), |
| SilenceUsage: true, |
| } |
| |
| func init() { |
| flag.CommandLine.AddGoFlagSet(goflag.CommandLine) |
| |
| pflags := rootCmd.PersistentFlags() |
| pflags.StringVarP(&RootPackage.Name, "package", "p", "", |
| "the name of the package") |
| pflags.StringVarP(&RootPackage.Name, "module", "m", "", |
| "the name of the module/package (alias of --package for compatibility with dkms)") |
| pflags.StringVar(&RootPackage.Version, "package-version", "", |
| "the version of the package") |
| pflags.StringVar(&RootPackage.Version, "module-version", "", |
| "the version of the module/package (alias of --package-version for compatibility with dkms)") |
| pflags.StringVarP(&RootPackage.KernelVersion, "kernel-version", "k", "", |
| "the kernel version (defaults to the kernel version of the running kernel)") |
| pflags.StringVarP(&RootPackage.Arch, "arch", "a", "", |
| "the compiler architecture (e.g., x86_64, aarch64; defaults to the arch of the running kernel)") |
| pflags.StringVar(&RootPackage.Trees.Kernel, "kernelsourcedir", "", |
| "the directory where the kernel sources are located (defaults to /lib/modules/${kernel-version}/build)") |
| pflags.StringVarP(&RootPackage.Trees.Dkms, "dkmstree", "d", "/var/lib/dkms", |
| "the directory where the dkms tree is located") |
| pflags.StringVarP(&RootPackage.Trees.Source, "sourcetree", "s", "", |
| "the directory where the module source tree is located (defaults to /usr/src)") |
| pflags.StringVarP(&RootPackage.Trees.Install, "installtree", "i", "", |
| "the directory where the modules will be installed (defaults to /lib/modules/${kernel-version})") |
| pflags.StringVarP(&RootPackage.Trees.KernelModules, "kernelmodulestree", "b", "", |
| "the directory where compiled kernel modules are installed (defaults to ${installtree}") |
| pflags.StringVar(&RootPackage.BuildId, "build-id", "", |
| "the kernel build id") |
| pflags.StringVar(&RootPackage.Board, "board", "", |
| "the kernel board") |
| pflags.Var(&RootPackage.ModuleParams, "module-arg", |
| "parameters to be passed to kernel modules, in the form module1.param1=value1,module2.param2=value2, etc.") |
| |
| pflags.BoolVar(&RootOptions.Latest, "latest", false, |
| "use the latest compatible version of the package which is available") |
| pflags.BoolVarP(&RootOptions.Force, "force", "f", false, |
| "whether to force an action even if it has already happened") |
| pflags.BoolVar(&RootOptions.ForceVersionOverride, "force-version-override", false, |
| "skip any version checks when using a module which has an earlier version than one which is already present") |
| pflags.BoolVar(&RootOptions.InstallBuildDependencies, "install-build-dependencies", false, |
| "install build dependencies before running build if they are not installed") |
| pflags.BoolVarP(&RootOptions.InsertOnInstall, "insert-on-install", "I", false, |
| "insert installed modules and their dependencies into the running kernel on install") |
| pflags.BoolVarP(&RootOptions.ModprobeOnInstall, "modprobe-on-install", "M", false, |
| "run modprobe on install, inserting installed modules and their dependencies into the running kernel") |
| pflags.BoolVar(&RootOptions.NoDepmod, "no-depmod", false, |
| "do not run depmod before modprobe on install when --modprobe-on-install is specified") |
| pflags.IntVarP(&RootOptions.Jobs, "jobs", "j", 1, |
| "the maximum number of jobs to use when compiling modules") |
| pflags.StringVar(&RootOptions.GCSBucket, "gcs-bucket", "", |
| "a GCS bucket path to use as a cache for builds and source files") |
| pflags.BoolVar(&RootOptions.Upload, "upload", false, |
| "whether or not to upload files to the GCS bucket after a build or install") |
| pflags.IntVarP(&RootOptions.DownloadWorkers, "download-workers", "w", 1, |
| "the maximum number of workers to use when downloading from a GCS bucket; if the number of workers is negative or 0, one download worker will be created per object to be downloaded") |
| pflags.StringVar(&RootOptions.MakeVariables, "make-variables", "", |
| "variables to be passed to the make command, such as CC. If set to 'cos-default', the variables for compiling the COS kernel will be used.") |
| pflags.StringVar(&RootOptions.LSBReleasePath, "lsb-release-path", "/etc/lsb-release", |
| "path to the LSB Release file which will be used to populate default values for --build-id and --board if they are not supplied") |
| pflags.StringVar(&RootOptions.Hash, "hash-algorithm", "sha256", |
| "the hash algorithm used during signing of modules. Currently, only SHA-2 and SHA-3 families are supported (e.g. 'sha256')") |
| } |
| |
| func Execute() { |
| if err := rootCmd.Execute(); err != nil { |
| glog.Exitf("%v", err) |
| } |
| } |