func (b *buildFile) Build(context io.Reader) (string, error) { // FIXME: @creack "name" is a terrible variable name name, err := ioutil.TempDir("", "docker-build") if err != nil { return "", err } if err := archive.Untar(context, name, nil); err != nil { return "", err } defer os.RemoveAll(name) b.context = name filename := path.Join(name, "Dockerfile") if _, err := os.Stat(filename); os.IsNotExist(err) { return "", fmt.Errorf("Can't build a directory with no Dockerfile") } fileBytes, err := ioutil.ReadFile(filename) if err != nil { return "", err } dockerfile := string(fileBytes) dockerfile = lineContinuation.ReplaceAllString(dockerfile, "") stepN := 0 for _, line := range strings.Split(dockerfile, "\n") { line = strings.Trim(strings.Replace(line, "\t", " ", -1), " \t\r\n") // Skip comments and empty line if len(line) == 0 || line[0] == '#' { continue } tmp := strings.SplitN(line, " ", 2) if len(tmp) != 2 { return "", fmt.Errorf("Invalid Dockerfile format") } instruction := strings.ToLower(strings.Trim(tmp[0], " ")) arguments := strings.Trim(tmp[1], " ") method, exists := reflect.TypeOf(b).MethodByName("Cmd" + strings.ToUpper(instruction[:1]) + strings.ToLower(instruction[1:])) if !exists { fmt.Fprintf(b.errStream, "# Skipping unknown instruction %s\n", strings.ToUpper(instruction)) continue } stepN += 1 fmt.Fprintf(b.outStream, "Step %d : %s %s\n", stepN, strings.ToUpper(instruction), arguments) ret := method.Func.Call([]reflect.Value{reflect.ValueOf(b), reflect.ValueOf(arguments)})[0].Interface() if ret != nil { return "", ret.(error) } fmt.Fprintf(b.outStream, " ---> %s\n", utils.TruncateID(b.image)) } if b.image != "" { fmt.Fprintf(b.outStream, "Successfully built %s\n", utils.TruncateID(b.image)) if b.rm { b.clearTmp(b.tmpContainers) } return b.image, nil } return "", fmt.Errorf("No image was generated. This may be because the Dockerfile does not, like, do anything.\n") }
func (b *buildFile) Build(context io.Reader) (string, error) { tmpdirPath, err := ioutil.TempDir("", "docker-build") if err != nil { return "", err } decompressedStream, err := archive.DecompressStream(context) if err != nil { return "", err } b.context = &utils.TarSum{Reader: decompressedStream, DisableCompression: true} if err := archive.Untar(b.context, tmpdirPath, nil); err != nil { return "", err } defer os.RemoveAll(tmpdirPath) b.contextPath = tmpdirPath filename := path.Join(tmpdirPath, "Dockerfile") if _, err := os.Stat(filename); os.IsNotExist(err) { return "", fmt.Errorf("Can't build a directory with no Dockerfile") } fileBytes, err := ioutil.ReadFile(filename) if err != nil { return "", err } if len(fileBytes) == 0 { return "", ErrDockerfileEmpty } var ( dockerfile = lineContinuation.ReplaceAllString(stripComments(fileBytes), "") stepN = 0 ) for _, line := range strings.Split(dockerfile, "\n") { line = strings.Trim(strings.Replace(line, "\t", " ", -1), " \t\r\n") if len(line) == 0 { continue } if err := b.BuildStep(fmt.Sprintf("%d", stepN), line); err != nil { if b.forceRm { b.clearTmp(b.tmpContainers) } return "", err } else if b.rm { b.clearTmp(b.tmpContainers) } stepN += 1 } if b.image != "" { fmt.Fprintf(b.outStream, "Successfully built %s\n", utils.TruncateID(b.image)) return b.image, nil } return "", fmt.Errorf("No image was generated. This may be because the Dockerfile does not, like, do anything.\n") }
// Loads a set of images into the repository. This is the complementary of ImageExport. // The input stream is an uncompressed tar ball containing images and metadata. func (srv *Server) ImageLoad(in io.Reader) error { tmpImageDir, err := ioutil.TempDir("", "docker-import-") if err != nil { return err } defer os.RemoveAll(tmpImageDir) var ( repoTarFile = path.Join(tmpImageDir, "repo.tar") repoDir = path.Join(tmpImageDir, "repo") ) tarFile, err := os.Create(repoTarFile) if err != nil { return err } if _, err := io.Copy(tarFile, in); err != nil { return err } tarFile.Close() repoFile, err := os.Open(repoTarFile) if err != nil { return err } if err := os.Mkdir(repoDir, os.ModeDir); err != nil { return err } if err := archive.Untar(repoFile, repoDir); err != nil { return err } repositoriesJson, err := ioutil.ReadFile(path.Join(tmpImageDir, "repo", "repositories")) if err != nil { return err } repositories := map[string]Repository{} if err := json.Unmarshal(repositoriesJson, &repositories); err != nil { return err } for imageName, tagMap := range repositories { for tag, address := range tagMap { if err := srv.recursiveLoad(address, tmpImageDir); err != nil { return err } if err := srv.runtime.repositories.Set(imageName, tag, address, true); err != nil { return err } } } return nil }
func StoreImage(img *Image, jsonData []byte, layerData archive.Archive, root string) error { // Check that root doesn't already exist if _, err := os.Stat(root); err == nil { return fmt.Errorf("Image %s already exists", img.ID) } else if !os.IsNotExist(err) { return err } // Store the layer layer := layerPath(root) if err := os.MkdirAll(layer, 0755); err != nil { return err } // If layerData is not nil, unpack it into the new layer if layerData != nil { start := time.Now() utils.Debugf("Start untar layer") if err := archive.Untar(layerData, layer); err != nil { return err } utils.Debugf("Untar time: %vs", time.Now().Sub(start).Seconds()) } // If raw json is provided, then use it if jsonData != nil { return ioutil.WriteFile(jsonPath(root), jsonData, 0600) } // Otherwise, unmarshal the image jsonData, err := json.Marshal(img) if err != nil { return err } if err := ioutil.WriteFile(jsonPath(root), jsonData, 0600); err != nil { return err } return StoreSize(img, root) }
func (a *Driver) ApplyDiff(id string, diff archive.ArchiveReader) error { return archive.Untar(diff, path.Join(a.rootPath(), "diff", id), nil) }