X-Git-Url: https://git.arvados.org/arvados.git/blobdiff_plain/985ece13dd7147f153c7a59c5b3665570c5943c8..bfdecdcaf7dbeabfacc0efefb864e0024dbef9ab:/cmd/arvados-package/cmd.go diff --git a/cmd/arvados-package/cmd.go b/cmd/arvados-package/cmd.go index 02bc16cea8..a64d440749 100644 --- a/cmd/arvados-package/cmd.go +++ b/cmd/arvados-package/cmd.go @@ -5,9 +5,17 @@ package main import ( + "context" + "flag" + "fmt" + "io" "os" + "path/filepath" + "strings" "git.arvados.org/arvados.git/lib/cmd" + "git.arvados.org/arvados.git/lib/install" + "git.arvados.org/arvados.git/sdk/go/ctxlog" ) var ( @@ -16,10 +24,118 @@ var ( "-version": cmd.Version, "--version": cmd.Version, - "build": build{}, + "build": cmdFunc(build), + "testinstall": cmdFunc(testinstall), + "_fpm": cmdFunc(fpm), // internal use + "_install": install.Command, // internal use }) ) func main() { + if len(os.Args) < 2 || strings.HasPrefix(os.Args[1], "-") { + parseFlags(os.Args[0], []string{"-help"}, os.Stderr) + os.Exit(2) + } os.Exit(handler.RunCommand(os.Args[0], os.Args[1:], os.Stdin, os.Stdout, os.Stderr)) } + +type cmdFunc func(ctx context.Context, opts opts, stdin io.Reader, stdout, stderr io.Writer) error + +func (cf cmdFunc) RunCommand(prog string, args []string, stdin io.Reader, stdout, stderr io.Writer) int { + logger := ctxlog.New(stderr, "text", "info") + ctx := ctxlog.Context(context.Background(), logger) + opts, ok, code := parseFlags(prog, args, stderr) + if !ok { + return code + } + err := cf(ctx, opts, stdin, stdout, stderr) + if err != nil { + logger.WithError(err).Error("failed") + return 1 + } + return 0 +} + +type opts struct { + PackageVersion string + PackageDir string + PackageChown string + RebuildImage bool + SourceDir string + TargetOS string + Maintainer string + Vendor string +} + +func parseFlags(prog string, args []string, stderr io.Writer) (_ opts, ok bool, exitCode int) { + opts := opts{ + SourceDir: ".", + TargetOS: "debian:10", + Maintainer: "Arvados Package Maintainers ", + Vendor: "The Arvados Project", + } + flags := flag.NewFlagSet("", flag.ContinueOnError) + flags.StringVar(&opts.PackageVersion, "package-version", opts.PackageVersion, "package version to build/test, like \"1.2.3\"") + flags.StringVar(&opts.SourceDir, "source", opts.SourceDir, "arvados source tree location") + flags.StringVar(&opts.PackageDir, "package-dir", opts.PackageDir, "destination directory for new package (default is cwd)") + flags.StringVar(&opts.PackageChown, "package-chown", opts.PackageChown, "desired uid:gid for new package (default is current user:group)") + flags.StringVar(&opts.TargetOS, "target-os", opts.TargetOS, "target operating system vendor:version") + flags.StringVar(&opts.Maintainer, "package-maintainer", opts.Maintainer, "maintainer to be listed in package metadata") + flags.StringVar(&opts.Vendor, "package-vendor", opts.Vendor, "vendor to be listed in package metadata") + flags.BoolVar(&opts.RebuildImage, "rebuild-image", opts.RebuildImage, "rebuild docker image(s) instead of using existing") + flags.Usage = func() { + fmt.Fprint(flags.Output(), `Usage: arvados-package [options] + +Subcommands: + build + use a docker container to build a package from a checked + out version of the arvados source tree + testinstall + use a docker container to install a package and confirm + the resulting installation is functional + version + show program version + +Internally used subcommands: + _fpm + build a package + _install + equivalent to "arvados-server install" + +Automation/integration notes: + The first time a given machine runs "build" or "testinstall" (and + any time the -rebuild-image is used), new docker images are built, + which is quite slow. If you use on-demand VMs to run automated builds, + run "build" and "testinstall" once when setting up your initial VM + image, and be prepared to rebuild that VM image when package-building + slows down (this will happen when new dependencies are introduced). + + The "build" subcommand, if successful, also runs + dpkg-scanpackages to create/replace Packages.gz in the package + dir. This enables the "testinstall" subcommand to list the + package dir as a source in /etc/apt/sources.*. + +Options: +`) + flags.PrintDefaults() + } + if ok, code := cmd.ParseFlags(flags, prog, args, "", stderr); !ok { + return opts, false, code + } + if opts.SourceDir == "" { + d, err := os.Getwd() + if err != nil { + fmt.Fprintf(stderr, "error getting current working directory: %s\n", err) + return opts, false, 1 + } + opts.SourceDir = d + } + opts.PackageDir = filepath.Clean(opts.PackageDir) + abs, err := filepath.Abs(opts.SourceDir) + if err != nil { + fmt.Fprintf(stderr, "error resolving source dir %q: %s\n", opts.SourceDir, err) + return opts, false, 1 + } + opts.SourceDir = abs + return opts, true, 0 +}