16306: Rename arvados-dev buildpackage -> arvados-package build
[arvados.git] / cmd / arvados-package / build.go
1 // Copyright (C) The Arvados Authors. All rights reserved.
2 //
3 // SPDX-License-Identifier: AGPL-3.0
4
5 package main
6
7 import (
8         "context"
9         "flag"
10         "fmt"
11         "io"
12         "os"
13         "os/exec"
14
15         "git.arvados.org/arvados.git/lib/install"
16         "git.arvados.org/arvados.git/sdk/go/ctxlog"
17         "github.com/sirupsen/logrus"
18 )
19
20 type build struct{}
21
22 func (bld build) RunCommand(prog string, args []string, stdin io.Reader, stdout, stderr io.Writer) int {
23         logger := ctxlog.New(stderr, "text", "info")
24         err := (&builder{
25                 PackageVersion: "0.0.0",
26                 logger:         logger,
27         }).run(context.Background(), prog, args, stdin, stdout, stderr)
28         if err != nil {
29                 logger.WithError(err).Error("failed")
30                 return 1
31         }
32         return 0
33 }
34
35 type builder struct {
36         PackageVersion string
37         SourcePath     string
38         OutputDir      string
39         SkipInstall    bool
40         logger         logrus.FieldLogger
41 }
42
43 func (bldr *builder) run(ctx context.Context, prog string, args []string, stdin io.Reader, stdout, stderr io.Writer) error {
44         flags := flag.NewFlagSet("", flag.ContinueOnError)
45         flags.StringVar(&bldr.PackageVersion, "package-version", bldr.PackageVersion, "package version")
46         flags.StringVar(&bldr.SourcePath, "source", bldr.SourcePath, "source tree location")
47         flags.StringVar(&bldr.OutputDir, "output-directory", bldr.OutputDir, "destination directory for new package (default is cwd)")
48         flags.BoolVar(&bldr.SkipInstall, "skip-install", bldr.SkipInstall, "skip install step, assume you have already run 'arvados-server install -type package'")
49         err := flags.Parse(args)
50         if err != nil {
51                 return err
52         }
53         if len(flags.Args()) > 0 {
54                 return fmt.Errorf("unrecognized command line arguments: %v", flags.Args())
55         }
56         if !bldr.SkipInstall {
57                 exitcode := install.Command.RunCommand("arvados-server install", []string{
58                         "-type", "package",
59                         "-package-version", bldr.PackageVersion,
60                         "-source", bldr.SourcePath,
61                 }, stdin, stdout, stderr)
62                 if exitcode != 0 {
63                         return fmt.Errorf("arvados-server install failed: exit code %d", exitcode)
64                 }
65         }
66         cmd := exec.Command("/var/lib/arvados/bin/gem", "install", "--user", "--no-document", "fpm")
67         cmd.Stdout = stdout
68         cmd.Stderr = stderr
69         err = cmd.Run()
70         if err != nil {
71                 return fmt.Errorf("gem install fpm: %w", err)
72         }
73
74         if _, err := os.Stat("/root/.gem/ruby/2.5.0/gems/fpm-1.11.0/lib/fpm/package/deb.rb"); err == nil {
75                 // Workaround for fpm bug https://github.com/jordansissel/fpm/issues/1739
76                 cmd = exec.Command("sed", "-i", `/require "digest"/a require "zlib"`, "/root/.gem/ruby/2.5.0/gems/fpm-1.11.0/lib/fpm/package/deb.rb")
77                 cmd.Stdout = stdout
78                 cmd.Stderr = stderr
79                 err = cmd.Run()
80                 if err != nil {
81                         return fmt.Errorf("monkeypatch fpm: %w", err)
82                 }
83         }
84
85         // Remove unneeded files. This is much faster than "fpm
86         // --exclude X" because fpm copies everything into a staging
87         // area before looking at the --exclude args.
88         cmd = exec.Command("bash", "-c", "cd /var/www/.gem/ruby && rm -rf */cache */bundler/gems/*/.git */bundler/gems/arvados-*/[^s]* */bundler/gems/arvados-*/s[^d]* */bundler/gems/arvados-*/sdk/[^cr]* */gems/passenger-*/src/cxx* ruby/*/gems/*/ext /var/lib/arvados/go")
89         cmd.Stdout = stdout
90         cmd.Stderr = stderr
91         err = cmd.Run()
92         if err != nil {
93                 return fmt.Errorf("rm -rf [...]: %w", err)
94         }
95
96         format := "deb" // TODO: rpm
97
98         cmd = exec.Command("/root/.gem/ruby/2.5.0/bin/fpm",
99                 "--name", "arvados-server-easy",
100                 "--version", bldr.PackageVersion,
101                 "--input-type", "dir",
102                 "--output-type", format)
103         deps, err := install.ProductionDependencies()
104         if err != nil {
105                 return err
106         }
107         for _, pkg := range deps {
108                 cmd.Args = append(cmd.Args, "--depends", pkg)
109         }
110         cmd.Args = append(cmd.Args,
111                 "--verbose",
112                 "--deb-use-file-permissions",
113                 "--rpm-use-file-permissions",
114                 "/var/lib/arvados",
115                 "/var/www/.gem",
116                 "/var/www/.passenger",
117                 "/var/www/.bundle",
118         )
119         fmt.Fprintf(stderr, "... %s\n", cmd.Args)
120         cmd.Dir = bldr.OutputDir
121         cmd.Stdout = stdout
122         cmd.Stderr = stderr
123         return cmd.Run()
124 }