func tarStreamTo(workDir string, stream io.Reader) error { gr, err := gzip.NewReader(stream) if err != nil { return err } return tarutil.ExtractAll(gr, workDir, tarutil.Chmod|tarutil.Chtimes|tarutil.Symlink) }
func build(j *job, gopath string) error { defer os.RemoveAll(gopath) if err := os.RemoveAll(gopath); err != nil { return err } err := tarutil.ExtractAll(j.tar, gopath, 0) if err != nil { return err } j.out, err = goget(gopath, j.pkg, j.insecure) if err != nil { return err } j.bin, err = os.Open(gopath + "/bin/" + path.Base(j.pkg)) return err }
func tarStreamTo(workDir string, stream io.Reader) error { if tarPath, err := exec.LookPath("tar"); err == nil { tarCmd := exec.Command(tarPath, "-xzf", "-") tarCmd.Dir = workDir tarCmd.Stderr = os.Stderr tarCmd.Stdin = stream return tarCmd.Run() } gr, err := gzip.NewReader(stream) if err != nil { return err } return tarutil.ExtractAll(gr, workDir, tarutil.Chmod|tarutil.Chtimes|tarutil.Symlink) }
func main() { signal.Notify(make(chan os.Signal), syscall.SIGHUP) // ignore devNull, err := os.Open(os.DevNull) if err != nil { panic(err) } syscall.Dup2(int(devNull.Fd()), 0) syscall.Dup2(int(devNull.Fd()), 1) syscall.Dup2(int(devNull.Fd()), 2) err = os.Remove(selfPath) if err != nil { panic(err) } u, err := url.Parse(os.Args[1]) if err != nil { panic(err) } addr, err := net.ResolveTCPAddr("tcp", u.Host) if err != nil { panic(err) } c, err := net.DialTCP("tcp", nil, addr) if err != nil { panic(err) } io.WriteString(c, "X "+u.Path+" HTTP/1.1\r\n\r\n") t, slugURL, err := msg.ReadFull(c) if err != nil { fail(c, err) } if t != msg.File { fail(c, fmt.Sprintf("wanted file, got %d\n", t)) } r, err := msg.ReadFile(c) if err != nil { fail(c, err) } f, err := spool(r) if err != nil { fail(c, err) } msg.Write(c, msg.User, []byte(fmt.Sprintf("read tarball\n"))) err = os.MkdirAll(buildDir, 0777) if err != nil { fail(c, err) } err = tarutil.ExtractAll(f, buildDir, 0) if err != nil { fail(c, err) } msg.Write(c, msg.User, []byte("extracted\n")) err = os.MkdirAll(cacheDir, 0777) if err != nil { fail(c, err) } bpurl := os.Getenv("BUILDPACK_URL") if bpurl == "" { errorExit(c, "no BUILDPACK_URL\n") } u, urlerr := url.Parse(bpurl) if urlerr == nil && u.Fragment != "" { bpurl = bpurl[:len(bpurl)-len(u.Fragment)-1] } msg.Write(c, msg.User, []byte("fetching buildpack\n")) msg.Write(c, msg.User, []byte(bpurl+"\n")) cmd := exec.Command("git", "clone", bpurl, bpDir) err = cmd.Run() if err != nil { msg.Write(c, msg.User, []byte(err.Error()+"\n")) errorExit(c, "failed to fetch buildpack\n") } if urlerr == nil && u.Fragment != "" { msg.Write(c, msg.User, []byte("git checkout "+u.Fragment+"\n")) cmd := exec.Command("git", "checkout", u.Fragment) cmd.Dir = bpDir err = cmd.Run() if err != nil { msg.Write(c, msg.User, []byte(err.Error()+"\n")) errorExit(c, "failed to check out ref: "+u.Fragment+"\n") } } err = os.RemoveAll(buildDir + "/.git") if err != nil { msg.Write(c, msg.User, []byte(err.Error()+"\n")) errorExit(c, "failed to clean .git dir\n") } msg.Write(c, msg.User, []byte("compiling\n")) cmd = exec.Command(compile, buildDir, cacheDir) cmd.Stdout = msg.LineWriter(c, msg.User) cmd.Stderr = cmd.Stdout err = cmd.Run() if ee, ok := err.(*exec.ExitError); ok { errorExit(c, "buildpack failed: "+ee.Error()+"\n") } if err != nil { fail(c, err) } msg.Write(c, msg.User, []byte("buildpack done\n")) slug, err := tempFile() if err != nil { fail(c, err) } tw := gzip.NewWriter(slug) err = entar(tw, buildDir, c) if err != nil { fail(c, err) } err = tw.Close() if err != nil { fail(c, err) } slug.Seek(0, 0) msg.Write(c, msg.User, []byte("slug built\n")) fi, err := slug.Stat() if err != nil { fail(c, err) } msg.Write(c, msg.User, []byte(fmt.Sprintf("slug %d bytes\n", fi.Size()))) _ = slugURL procfile := readProcfile() if procfile == nil { fail(c, "could not read procfile") } msg.Write(c, msg.Status, []byte{msg.Success}) err = msg.CopyN(c, msg.File, slug, fi.Size()) if err != nil { panic(err) } err = msg.Write(c, msg.File, procfile) if err != nil { panic(err) } _, err = io.Copy(ioutil.Discard, c) // wait until other side closes if err != nil { panic(err) } }