forked from solo-io/unik
/
osv_boot_creator.go
138 lines (122 loc) · 3.94 KB
/
osv_boot_creator.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
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
package main
import (
"os/exec"
"os"
"strings"
unikutil "github.com/emc-advanced-dev/unik/pkg/util"
"fmt"
"github.com/Sirupsen/logrus"
"time"
"path/filepath"
"flag"
)
//expect project directory at /project_directory; mount w/ -v FOLDER:/project_directory
//output dir will be /project_directory
//output files to whatever is mounted to /project_directory
const (
java_main_caller_udp_bootstrap_dir = "/java-main-caller-udp-bootstrap"
java_main_caller_ec2_bootstrap_dir = "/java-main-caller-ec2-bootstrap"
project_directory = "/project_directory"
)
var buildImageTimeout = time.Minute * 10
func main() {
useEc2Bootstrap := flag.Bool("ec2", false, "indicates whether to compile using the wrapper for ec2")
flag.Parse()
javaMainCallerDir := java_main_caller_udp_bootstrap_dir //use udp by default
if *useEc2Bootstrap {
javaMainCallerDir = java_main_caller_ec2_bootstrap_dir
}
out, _ := exec.Command("ls", "/").CombinedOutput()
fmt.Println(strings.Split(string(out), "\n"))
appInfo, err := wrapJavaApplication(javaMainCallerDir, project_directory)
if err != nil {
logrus.WithError(err).Errorf("Failed to wrap java project Main Class", err)
os.Exit(-1)
}
logrus.AddHook(&unikutil.AddTraceHook{true})
fmt.Printf("read info from java project: %v\n", appInfo)
fmt.Printf("runnning mvn clean")
mvnClean := exec.Command("mvn", "clean")
mvnClean.Dir = project_directory
if err := mvnClean.Run(); err != nil {
fmt.Printf("mvn clean failed, simply cleaning up %s/target", project_directory)
os.RemoveAll(filepath.Join(project_directory, "target"))
}
fmt.Printf("running mvn package\n")
mvnPackageCmd := exec.Command("mvn", "package")
mvnPackageCmd.Dir = project_directory
printCommand(mvnPackageCmd)
if out, err := mvnPackageCmd.CombinedOutput(); err != nil {
logrus.WithError(err).Error(string(out))
os.Exit(-1)
}
mvnInstallCmd := exec.Command("mvn", "install:install-file",
"-Dfile=target/" + appInfo.ArtifactId + "-" + appInfo.Version + "-jar-with-dependencies.jar",
"-DgroupId=" + appInfo.GroupId,
"-DartifactId=" + appInfo.ArtifactId,
"-Dversion=" + appInfo.Version,
"-Dpackaging=jar")
mvnInstallCmd.Dir = project_directory
printCommand(mvnInstallCmd)
if out, err := mvnInstallCmd.CombinedOutput(); err != nil {
logrus.WithError(err).Error(string(out))
os.Exit(-1)
}
go func() {
fmt.Println("capstain building")
capstanCmd := exec.Command("capstan", "run", "-p", "qemu")
capstanCmd.Dir = javaMainCallerDir
capstanCmd.Stdout = os.Stdout
capstanCmd.Stderr = os.Stderr
printCommand(capstanCmd)
if err := capstanCmd.Run(); err != nil {
logrus.WithError(err).Error("captsain build failed")
os.Exit(-1)
}
}()
capstanImage := filepath.Join(os.Getenv("HOME"), ".capstan", "instances", "qemu", javaMainCallerDir, "disk.qcow2")
select {
case <-fileReady(capstanImage):
fmt.Printf("image ready at %s\n", capstanImage)
break
case <-time.After(buildImageTimeout):
logrus.Error("timed out waiting for capstan to finish building")
os.Exit(-1)
}
fmt.Println("qemu-img converting (compatibility")
convertToCompatibleCmd := exec.Command("qemu-img", "convert",
"-f", "qcow2",
"-O", "qcow2",
"-o", "compat=0.10",
capstanImage,
project_directory + "/boot.qcow2")
printCommand(convertToCompatibleCmd)
if out, err := convertToCompatibleCmd.CombinedOutput(); err != nil {
logrus.WithError(err).Error(string(out))
os.Exit(-1)
}
fmt.Println("file created at " + project_directory + "/boot.qcow2")
}
func fileReady(filename string) <-chan struct{} {
closeChan := make(chan struct{})
fmt.Printf("waiting for file to become ready...\n")
go func() {
count := 0
for {
if _, err := os.Stat(filename); err == nil {
close(closeChan)
return
}
//count every 5 sec
if count%5 == 0 {
fmt.Printf("waiting for file...%vs\n", count)
}
time.Sleep(time.Second * 1)
count++
}
}()
return closeChan
}
func printCommand(cmd *exec.Cmd) {
fmt.Printf("running command from dir %s: %v\n", cmd.Dir, cmd.Args)
}