This repository has been archived by the owner on Aug 26, 2022. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 3
/
Copy pathbuild.go
110 lines (91 loc) · 2.62 KB
/
build.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
package main
import (
"fmt"
"os"
"strings"
"github.com/giantswarm/conair/btrfs"
"github.com/giantswarm/conair/layer"
"github.com/giantswarm/conair/nspawn"
"github.com/giantswarm/conair/parser"
)
var cmdBuild = &Command{
Name: "build",
Description: "Build an image",
Summary: "Build an image",
Run: runBuild,
}
func readFile(filename string) (*parser.Conairfile, error) {
if _, err := os.Stat(filename); os.IsNotExist(err) {
return nil, err
}
return parser.Parse(filename)
}
func runBuild(args []string) (exit int) {
if len(args) < 1 {
fmt.Fprintln(os.Stderr, "Image name missing.")
return 1
}
newImagePath := args[0]
fs, _ := btrfs.Init(home)
// remove existing layer
if fs.Exists(newImagePath) {
if err := fs.Remove(newImagePath); err != nil {
fmt.Printf("%v", err)
fmt.Fprintln(os.Stderr, fmt.Sprintf("Couldn't remove existing image. %v", err))
return 1
}
}
// read build file
f, err := readFile("./Conairfile")
if err != nil {
f, err = readFile("./Dockerfile")
if err != nil {
fmt.Fprintln(os.Stderr, "Couldn't read Conairfile or Dockerfile.", err)
return 1
}
}
parentPath := f.From
for i, snap := range f.Snapshots {
paths := strings.Split(snap, ":")
if len(paths) < 2 {
fmt.Fprintln(os.Stderr, "SNAPSHOT definition is unreadable. Please use <snapshot name>:<container path> notation.")
return 1
}
// check if snapshot exists - otherwise create a new subvolume
snapshotPath := fmt.Sprintf(".cnr-snapshot-%s", paths[0])
if !fs.Exists(snapshotPath) {
if err := fs.Subvolume(snapshotPath); err != nil {
fmt.Fprintln(os.Stderr, fmt.Sprintf("Couldn't create snapshot '%s'.", snapshotPath))
return 1
}
}
f.Snapshots[i] = fmt.Sprintf("%s/.cnr-snapshot-%s", home, snap)
}
for _, cmd := range f.Commands {
l, err := layer.Create(fs, cmd.Verb, cmd.Payload, parentPath)
if err != nil {
fmt.Fprintln(os.Stderr, fmt.Sprintf("Couldn't create layer: %v.", err))
return 1
}
fmt.Println(l.Hash, cmd.Verb, cmd.Payload)
if l.Exists == true {
parentPath = l.Path
continue
}
c := nspawn.Init(l.Hash, fmt.Sprintf("%s/%s", home, l.Path))
c.SetBinds(append(f.Binds, f.Snapshots...))
if err := c.Build(cmd.Verb, cmd.Payload); err != nil {
fmt.Fprintln(os.Stderr, fmt.Sprintf("Buildstep failed: %v.", err))
if err = l.Remove(); err != nil {
fmt.Fprintln(os.Stderr, "Couldn't remove temporary build container.", err)
}
return 1
}
parentPath = l.Path
}
if err = fs.Snapshot(parentPath, newImagePath, false); err != nil {
fmt.Fprintln(os.Stderr, "Couldn't create filesystem for new image.", err)
return 1
}
return 0
}