mirror of https://github.com/perkeep/perkeep.git
147 lines
5.8 KiB
Go
147 lines
5.8 KiB
Go
/*
|
|
Copyright 2018 The Perkeep Authors
|
|
|
|
Licensed under the Apache License, Version 2.0 (the "License");
|
|
you may not use this file except in compliance with the License.
|
|
You may obtain a copy of the License at
|
|
|
|
http://www.apache.org/licenses/LICENSE-2.0
|
|
|
|
Unless required by applicable law or agreed to in writing, software
|
|
distributed under the License is distributed on an "AS IS" BASIS,
|
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
See the License for the specific language governing permissions and
|
|
limitations under the License.
|
|
*/
|
|
|
|
// Command build_syno builds and packages Perkeep for Synology appliances.
|
|
package main
|
|
|
|
import (
|
|
"flag"
|
|
"fmt"
|
|
"log"
|
|
"os"
|
|
"os/exec"
|
|
"path/filepath"
|
|
)
|
|
|
|
var (
|
|
// TODO(mpl): include more arches.
|
|
flagArch = flag.String("arch", "x64", "Synology architecture to build for. Possible values are limited to x64 or 6281 for now.")
|
|
flagDsm = flag.String("dsm", "6.2", "DSM version to build for.")
|
|
flagPerkeepRev = flag.String("pkrev", "8b537a66307cf41a659786f1a898c77b46303601", "git revision of Perkeep to package")
|
|
flagNoCache = flag.Bool("nocache", false, "build docker image with --no-cache")
|
|
)
|
|
|
|
var pwd string
|
|
|
|
func main() {
|
|
flag.Parse()
|
|
if *flagArch != "x64" && *flagArch != "6281" {
|
|
log.Fatalf("unsupported architecture: %v", *flagArch)
|
|
}
|
|
|
|
newCwd := filepath.Dir(flag.Arg(0))
|
|
if err := os.Chdir(newCwd); err != nil {
|
|
log.Fatalf("error changing dir to %v: %v", newCwd, err)
|
|
}
|
|
var err error
|
|
pwd, err = os.Getwd()
|
|
if err != nil {
|
|
log.Fatalf("error getting current directory: %v", err)
|
|
}
|
|
|
|
gobin := "/go/bin"
|
|
goarch := "amd64"
|
|
// TODO(mpl): figure out the correspondence between all the other arches and the
|
|
// values for the go vars.
|
|
if *flagArch == "6281" {
|
|
gobin = "/go/bin/linux_arm"
|
|
goarch = "arm"
|
|
}
|
|
|
|
// we start by building only the first stage of the Dockerfile, even though
|
|
// we're eventually going to build all the stages. We do that in order to tag the
|
|
// first stage (with its relevant arch in the tag), and therefore so it does not
|
|
// get removed by 'docker rmi'.
|
|
|
|
// docker build --target pkbuild -t perkeep/synology-pkbuild-x64 --build-arg arch=x64 --build-arg dsm=6.2 --build-arg gobin=/go/bin --build-arg goarch=amd64 --build-arg perkeep_version=8b537a66307cf41a659786f1a898c77b46303601 .
|
|
buildImage(gobin, goarch, true)
|
|
|
|
// docker build -t perkeep/synology-x64 --build-arg arch=x64 --build-arg dsm=6.2 --build-arg gobin=/go/bin --build-arg goarch=amd64 --build-arg perkeep_version=8b537a66307cf41a659786f1a898c77b46303601 .
|
|
buildImage(gobin, goarch, false)
|
|
|
|
if err := os.MkdirAll(filepath.Join(pwd+"/out"), 0755); err != nil {
|
|
log.Fatalf("Error creating out dir: %v", err)
|
|
}
|
|
|
|
// the actual building step (./pkgscripts/PkgCreate.py) can't be in the
|
|
// Dockerfile since it's doing higher privilege stuff like chroot and mounts.
|
|
// Which is why we run it as the last step, and in privileged mode.
|
|
|
|
// TODO(mpl): we might be able to "just" run a furtherly modified version of
|
|
// perkeep/SynoBuildConf/install because at the end of the day, we've already built the
|
|
// binaries, and all we need to do is package them in an .spk. But that would require
|
|
// further understanding and rewriting of the various pieces involved, and I don't think
|
|
// it's worth spending time on it for now.
|
|
// Although if we manage that, another win is that then we can skip EnvDeploy,
|
|
// which means avoiding a heavy download.
|
|
|
|
// For runPkgCreate, you need to fetch the GPG keys at
|
|
// https://drive.google.com/drive/folders/1P95Lk1U6nA6kaVaxKRPi4Dv2Het-CWlY?usp=sharing
|
|
// and add them to $HOME/keys/perkeep-synology , which is then mounted to the container.
|
|
runPkgCreate()
|
|
}
|
|
|
|
func buildImage(gobin, goarch string, firstStageOnly bool) {
|
|
args := []string{"build"}
|
|
if *flagNoCache {
|
|
args = append(args, "--no-cache")
|
|
}
|
|
if firstStageOnly {
|
|
args = append(args, "--target", "pkbuild",
|
|
"-t", "perkeep/synology-pkbuild-"+*flagArch)
|
|
} else {
|
|
args = append(args, "-t", "perkeep/synology-"+*flagArch)
|
|
}
|
|
args = append(args,
|
|
"--build-arg", "arch="+*flagArch,
|
|
"--build-arg", "dsm="+*flagDsm,
|
|
"--build-arg", "gobin="+gobin,
|
|
"--build-arg", "goarch="+goarch,
|
|
"--build-arg", "perkeep_version="+*flagPerkeepRev,
|
|
".")
|
|
cmd := exec.Command("docker", args...)
|
|
out, err := cmd.CombinedOutput()
|
|
if err != nil {
|
|
if firstStageOnly {
|
|
log.Fatalf("Error building first stage of synology image: %v, %s", err, out)
|
|
}
|
|
log.Fatalf("Error building synology image: %v, %s", err, out)
|
|
}
|
|
fmt.Println(string(out))
|
|
}
|
|
|
|
// runPkgCreate runs the actual build/install step provided in the DSM toolkit: ./pkgscripts/PkgCreate.py
|
|
// It can't be run during the build stage (in the Dockerfile), because it does
|
|
// privileged operations (at least chroot) so it is run as a privileged container.
|
|
// It requires the GPG keys at
|
|
// https://drive.google.com/drive/folders/1P95Lk1U6nA6kaVaxKRPi4Dv2Het-CWlY?usp=sharing
|
|
func runPkgCreate() {
|
|
// To test the equivalent from the shell:
|
|
// docker run --rm -i -t --privileged -v $PWD/out:/toolkit/result_spk -v $HOME/keys/perkeep-synology:/toolkit/build_env/ds.6281-6.2/root/.gnupg perkeep/synology ./pkgscripts/PkgCreate.py -v 6.2 -p x64 -x0 -c --print-log --build-opt="-J" perkeep
|
|
build_env := "ds." + *flagArch + "-" + *flagDsm
|
|
// TODO(mpl): test discrete --cap-add flags when I have a docker that supports them.
|
|
cmd := exec.Command("docker", "run", "--rm", "--privileged",
|
|
"-v", filepath.Join(pwd+"/out")+":/toolkit/result_spk",
|
|
"-v", filepath.Join(os.Getenv("HOME"), "keys", "perkeep-synology")+":/toolkit/build_env/"+build_env+"/root/.gnupg",
|
|
"perkeep/synology-"+*flagArch,
|
|
"./pkgscripts/PkgCreate.py", "-p", *flagArch, "-v", *flagDsm, "-x0", "-c", "--print-log", `--build-opt="-J"`, "perkeep")
|
|
out, err := cmd.CombinedOutput()
|
|
if err != nil {
|
|
log.Fatalf("Error building synology package: %v, %s", err, out)
|
|
}
|
|
fmt.Println(string(out))
|
|
}
|