a862320360e94bc79e0c8faf2008e12ef3dd37c0
[arvados.git] / cmd / arvados-package / fpm.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         "fmt"
10         "io"
11         "os"
12         "os/exec"
13         "path/filepath"
14
15         "git.arvados.org/arvados.git/lib/install"
16 )
17
18 func fpm(ctx context.Context, opts opts, stdin io.Reader, stdout, stderr io.Writer) error {
19         var chownUid, chownGid int
20         if opts.PackageChown != "" {
21                 _, err := fmt.Sscanf(opts.PackageChown, "%d:%d", &chownUid, &chownGid)
22                 if err != nil {
23                         return fmt.Errorf("invalid value %q for PackageChown: %w", opts.PackageChown, err)
24                 }
25         }
26
27         exitcode := install.Command.RunCommand("arvados-server install", []string{
28                 "-type", "package",
29                 "-package-version", opts.PackageVersion,
30                 "-source", opts.SourceDir,
31         }, stdin, stdout, stderr)
32         if exitcode != 0 {
33                 return fmt.Errorf("arvados-server install failed: exit code %d", exitcode)
34         }
35
36         cmd := exec.Command("/var/lib/arvados/bin/gem", "install", "--user", "--no-document", "fpm")
37         cmd.Stdout = stdout
38         cmd.Stderr = stderr
39         err := cmd.Run()
40         if err != nil {
41                 return fmt.Errorf("gem install fpm: %w", err)
42         }
43
44         if _, err := os.Stat("/root/.gem/ruby/2.5.0/gems/fpm-1.11.0/lib/fpm/package/deb.rb"); err == nil {
45                 // Workaround for fpm bug https://github.com/jordansissel/fpm/issues/1739
46                 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")
47                 cmd.Stdout = stdout
48                 cmd.Stderr = stderr
49                 err = cmd.Run()
50                 if err != nil {
51                         return fmt.Errorf("monkeypatch fpm: %w", err)
52                 }
53         }
54
55         // Remove unneeded files. This is much faster than "fpm
56         // --exclude X" because fpm copies everything into a staging
57         // area before looking at the --exclude args.
58         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")
59         cmd.Stdout = stdout
60         cmd.Stderr = stderr
61         err = cmd.Run()
62         if err != nil {
63                 return fmt.Errorf("rm -rf [...]: %w", err)
64         }
65
66         format := "deb" // TODO: rpm
67         pkgfile := filepath.Join(opts.PackageDir, "arvados-server-easy_"+opts.PackageVersion+"_amd64."+format)
68
69         cmd = exec.Command("/root/.gem/ruby/2.5.0/bin/fpm",
70                 "--package", pkgfile,
71                 "--name", "arvados-server-easy",
72                 "--version", opts.PackageVersion,
73                 "--input-type", "dir",
74                 "--output-type", format)
75         deps, err := install.ProductionDependencies()
76         if err != nil {
77                 return err
78         }
79         for _, pkg := range deps {
80                 cmd.Args = append(cmd.Args, "--depends", pkg)
81         }
82         cmd.Args = append(cmd.Args,
83                 "--verbose",
84                 "--deb-use-file-permissions",
85                 "--rpm-use-file-permissions",
86                 "/var/lib/arvados",
87                 "/var/www/.gem",
88                 "/var/www/.passenger",
89                 "/var/www/.bundle",
90         )
91         fmt.Fprintf(stderr, "... %s\n", cmd.Args)
92         cmd.Dir = opts.PackageDir
93         cmd.Stdout = stdout
94         cmd.Stderr = stderr
95         err = cmd.Run()
96         if err != nil {
97                 return fmt.Errorf("fpm: %w", err)
98         }
99
100         if opts.PackageChown != "" {
101                 err = os.Chown(pkgfile, chownUid, chownGid)
102                 if err != nil {
103                         return fmt.Errorf("chown %s: %w", pkgfile, err)
104                 }
105         }
106
107         cmd = exec.Command("ls", "-l", pkgfile)
108         cmd.Stdout = stdout
109         cmd.Stderr = stderr
110         _ = cmd.Run()
111
112         return nil
113 }