| 
									
										
										
										
											2017-03-28 15:06:13 +08:00
										 |  |  | package imagebuildah | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | import ( | 
					
						
							|  |  |  | 	"fmt" | 
					
						
							|  |  |  | 	"io/ioutil" | 
					
						
							|  |  |  | 	"net/http" | 
					
						
							|  |  |  | 	"os" | 
					
						
							|  |  |  | 	"os/exec" | 
					
						
							|  |  |  | 	"path" | 
					
						
							|  |  |  | 	"strings" | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	"github.com/containers/storage/pkg/chrootarchive" | 
					
						
							| 
									
										
										
										
											2017-06-02 03:23:02 +08:00
										 |  |  | 	"github.com/pkg/errors" | 
					
						
							| 
									
										
										
										
											2017-04-11 22:27:05 +08:00
										 |  |  | 	"github.com/projectatomic/buildah" | 
					
						
							| 
									
										
										
										
											2017-10-10 03:05:56 +08:00
										 |  |  | 	"github.com/sirupsen/logrus" | 
					
						
							| 
									
										
										
										
											2017-03-28 15:06:13 +08:00
										 |  |  | ) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func cloneToDirectory(url, dir string) error { | 
					
						
							|  |  |  | 	if !strings.HasPrefix(url, "git://") { | 
					
						
							|  |  |  | 		url = "git://" + url | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	logrus.Debugf("cloning %q to %q", url, dir) | 
					
						
							|  |  |  | 	cmd := exec.Command("git", "clone", url, dir) | 
					
						
							|  |  |  | 	return cmd.Run() | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func downloadToDirectory(url, dir string) error { | 
					
						
							|  |  |  | 	logrus.Debugf("extracting %q to %q", url, dir) | 
					
						
							|  |  |  | 	resp, err := http.Get(url) | 
					
						
							|  |  |  | 	if err != nil { | 
					
						
							| 
									
										
										
										
											2017-06-02 03:23:02 +08:00
										 |  |  | 		return errors.Wrapf(err, "error getting %q", url) | 
					
						
							| 
									
										
										
										
											2017-03-28 15:06:13 +08:00
										 |  |  | 	} | 
					
						
							|  |  |  | 	defer resp.Body.Close() | 
					
						
							|  |  |  | 	if resp.ContentLength == 0 { | 
					
						
							| 
									
										
										
										
											2017-06-03 00:17:27 +08:00
										 |  |  | 		return errors.Errorf("no contents in %q", url) | 
					
						
							| 
									
										
										
										
											2017-03-28 15:06:13 +08:00
										 |  |  | 	} | 
					
						
							|  |  |  | 	return chrootarchive.Untar(resp.Body, dir, nil) | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // TempDirForURL checks if the passed-in string looks like a URL.  If it is,
 | 
					
						
							|  |  |  | // TempDirForURL creates a temporary directory, arranges for its contents to be
 | 
					
						
							|  |  |  | // the contents of that URL, and returns the temporary directory's path, along
 | 
					
						
							|  |  |  | // with the name of a subdirectory which should be used as the build context
 | 
					
						
							|  |  |  | // (which may be empty or ".").  Removal of the temporary directory is the
 | 
					
						
							|  |  |  | // responsibility of the caller.  If the string doesn't look like a URL,
 | 
					
						
							|  |  |  | // TempDirForURL returns empty strings and a nil error code.
 | 
					
						
							|  |  |  | func TempDirForURL(dir, prefix, url string) (name string, subdir string, err error) { | 
					
						
							|  |  |  | 	if !strings.HasPrefix(url, "http://") && | 
					
						
							|  |  |  | 		!strings.HasPrefix(url, "https://") && | 
					
						
							|  |  |  | 		!strings.HasPrefix(url, "git://") && | 
					
						
							|  |  |  | 		!strings.HasPrefix(url, "github.com/") { | 
					
						
							|  |  |  | 		return "", "", nil | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	name, err = ioutil.TempDir(dir, prefix) | 
					
						
							|  |  |  | 	if err != nil { | 
					
						
							| 
									
										
										
										
											2017-06-02 03:23:02 +08:00
										 |  |  | 		return "", "", errors.Wrapf(err, "error creating temporary directory for %q", url) | 
					
						
							| 
									
										
										
										
											2017-03-28 15:06:13 +08:00
										 |  |  | 	} | 
					
						
							|  |  |  | 	if strings.HasPrefix(url, "git://") { | 
					
						
							|  |  |  | 		err = cloneToDirectory(url, name) | 
					
						
							|  |  |  | 		if err != nil { | 
					
						
							|  |  |  | 			if err2 := os.Remove(name); err2 != nil { | 
					
						
							|  |  |  | 				logrus.Debugf("error removing temporary directory %q: %v", name, err2) | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 			return "", "", err | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		return name, "", nil | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	if strings.HasPrefix(url, "github.com/") { | 
					
						
							|  |  |  | 		ghurl := url | 
					
						
							|  |  |  | 		url = fmt.Sprintf("https://%s/archive/master.tar.gz", ghurl) | 
					
						
							|  |  |  | 		logrus.Debugf("resolving url %q to %q", ghurl, url) | 
					
						
							|  |  |  | 		subdir = path.Base(ghurl) + "-master" | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	if strings.HasPrefix(url, "http://") || strings.HasPrefix(url, "https://") { | 
					
						
							|  |  |  | 		err = downloadToDirectory(url, name) | 
					
						
							|  |  |  | 		if err != nil { | 
					
						
							|  |  |  | 			if err2 := os.Remove(name); err2 != nil { | 
					
						
							|  |  |  | 				logrus.Debugf("error removing temporary directory %q: %v", name, err2) | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 			return "", subdir, err | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		return name, subdir, nil | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	logrus.Debugf("don't know how to retrieve %q", url) | 
					
						
							|  |  |  | 	if err2 := os.Remove(name); err2 != nil { | 
					
						
							|  |  |  | 		logrus.Debugf("error removing temporary directory %q: %v", name, err2) | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2017-06-03 00:17:27 +08:00
										 |  |  | 	return "", "", errors.Errorf("unreachable code reached") | 
					
						
							| 
									
										
										
										
											2017-03-28 15:06:13 +08:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2017-04-11 22:27:05 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | // InitReexec is a wrapper for buildah.InitReexec().  It should be called at
 | 
					
						
							|  |  |  | // the start of main(), and if it returns true, main() should return
 | 
					
						
							|  |  |  | // immediately.
 | 
					
						
							|  |  |  | func InitReexec() bool { | 
					
						
							|  |  |  | 	return buildah.InitReexec() | 
					
						
							|  |  |  | } |