func (so *s3Options) Execute(args []string) error { if err := app.CheckArity(1, 1, args); err != nil { return err } repo := args[0] s3 := s3.New(awsAuth, awsRegion) buk := s3.Bucket(defBucket) data, err := buk.Get("/binary/repos/repositories") if err != nil { return err } ts := &env.TagStore{} err = json.Unmarshal(data, &ts) id, err := ts.Lookup(repo) if err != nil { return err } dts, err := env.DefaultTagStore() if err != nil { return err } i := &Importer{tags: ts, sysTags: dts} if !so.Force { if i.alreadyExists(id) { return fmt.Errorf("Already have %s, skipping download\n", utils.TruncateID(id)) } } fmt.Printf("Downloading %s (%s)\n", repo, utils.TruncateID(id)) err = i.download(buk, id) dts.Flush() return err }
func LoadTagStore(root string) (*TagStore, error) { tags, err := ReadRepoFile(path.Join(root, "repositories")) if err != nil { return nil, err } dir, err := ioutil.ReadDir(path.Join(root, "graph")) if err != nil { return nil, err } tags.Entries = make(Entries) for _, ent := range dir { id := ent.Name() img := &Image{} img.ID = id data, err := ioutil.ReadFile(path.Join(root, "graph", id, "json")) if err != nil { continue } err = json.Unmarshal(data, &img) if err != nil { return nil, err } tags.Entries[id] = img } for id, img := range tags.Entries { if img.Parent != "" { par, ok := tags.Entries[img.Parent] if ok { img.parentImage = par } else { fmt.Fprintf(os.Stderr, "Unable to find parent image %s for %s\n", utils.TruncateID(img.Parent), id) } } } return tags, nil }
func nukeImage(no *nukeOptions, id string) error { ts, err := env.DefaultTagStore() if err != nil { return err } img, err := ts.LookupImage(id) if err == nil { repo, tag := env.ParseRepositoryTag(id) ts.RemoveTag(repo, tag) } else { long := env.ExpandImageID(id) var ok bool img, ok = ts.Entries[long] if !ok { return fmt.Errorf("Unable to find repo '%s'\n", id) } else { err = nil } if !no.Force && ts.UsedAsParent(long) { return fmt.Errorf("%s is a parent image, not removing (use -force to force)\n", id) } } if img != nil { otherRepo, _ := ts.Find(img.ID) if otherRepo != "" { fmt.Printf("Removing %s tag on %s only\n", id, utils.TruncateID(img.ID)) } else { fmt.Printf("Nuking image %s..\n", id) img.Remove() } } else { return fmt.Errorf("Error locating image: %s\n", err) } return ts.Flush() }
func (b *buildFile) BuildTar(tar string) error { defer b.cleanup() b.context = "/" if err := b.CmdFrom(""); err != nil { return err } if err := b.CmdAdd(tar + " /"); err != nil { return err } if err := b.container.ToDisk(); err != nil { return err } if b.outImage != "" { img, err := b.container.Commit("", "", nil, b.squash, true) if err != nil { return err } ts, err := env.DefaultTagStore() if err != nil { return err } repo, tag := env.ParseRepositoryTag(b.outImage) ts.Add(repo, tag, img.ID) ts.Flush() fmt.Fprintf(b.out, "Built %s successfully\n", b.outImage) return nil } b.saveContainer = true fmt.Fprintf(b.out, "Successfully built %s\n", utils.TruncateID(b.container.ID)) return nil }
func (container *Container) Commit(comment, author string, config *Config, squash bool, fast bool) (*Image, error) { if config == nil { config = container.Config } else { MergeConfig(config, container.Config) } img := &Image{ ID: utils.GenerateID(), Parent: container.Image, Comment: comment, Created: time.Now(), ContainerConfig: *container.Config, Author: author, Config: config, Architecture: "x86_64", } logv("Creating image %s", utils.TruncateID(img.ID)) root := path.Join(DIR, "graph", "_armktmp-"+img.ID) os.MkdirAll(root, 0755) layerPath := path.Join(root, "layer") if squash { layerFs := path.Join(root, "layer.fs") logv("Generating squashfs...") utils.Run("mksquashfs", container.rwPath(), layerFs, "-comp", "xz") } else { if false { logv("Moving data directly into image...") utils.Run("mv", container.rwPath(), layerPath) } else { logv("Copying data into image...") utils.Run("cp", "-a", container.rwPath(), layerPath) } } jsonData, err := json.Marshal(img) if err != nil { panic(err) } err = ioutil.WriteFile(path.Join(root, "json"), jsonData, 0644) if err != nil { panic(err) } err = os.Rename(root, path.Join(DIR, "graph", img.ID)) if err != nil { panic(err) } return img, nil }
func (b *buildFile) Build(context string) error { defer b.cleanup() b.context = context if _, err := os.Stat(path.Join(context, "build.sh")); err == nil { fmt.Printf("Step 0: Execute build.sh on host\n") utils.Shell("cd " + context + "; bash ./build.sh") } dockerfile, err := os.Open(path.Join(context, "Dockerfile")) if err != nil { return fmt.Errorf("Can't build a directory with no Dockerfile") } file := bufio.NewReader(dockerfile) stepN := 0 for { select { case <-b.abort: fmt.Printf("Aborting...\n") if b.container != nil { b.container.Remove() } return ErrAbort default: // continue } line, err := file.ReadString('\n') if err != nil { if err == io.EOF && line == "" { break } else if err != io.EOF { return err } } 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.out, "# Skipping unknown instruction %s\n", strings.ToUpper(instruction)) continue } stepN += 1 fmt.Fprintf(b.out, "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) } } b.config.Cmd = nil err = b.container.ToDisk() if err != nil { return err } if b.experiment { b.CmdRun("/bin/bash") return nil } if b.image != "" && b.outImage != "" { img, err := b.container.Commit("", "", nil, b.squash, true) if err != nil { return err } ts, err := env.DefaultTagStore() if err != nil { return err } repo, tag := env.ParseRepositoryTag(b.outImage) ts.Add(repo, tag, img.ID) ts.Flush() fmt.Fprintf(b.out, "Built %s successfully\n", b.outImage) return nil } if b.image != "" { b.saveContainer = true fmt.Fprintf(b.out, "Successfully built %s\n", utils.TruncateID(b.container.ID)) return nil } return fmt.Errorf("An error occured during the build\n") }
func (io *imagesOptions) Execute(args []string) error { if err := app.CheckArity(0, 1, args); err != nil { return err } var repoDir string if len(args) > 0 { repoDir = args[0] fmt.Printf("Loading tag store from: %s\n", repoDir) } else { repoDir = env.DIR } // TODO(kev): Don't hardcode file name ts, err := env.LoadTagStore(repoDir) if err != nil { return fmt.Errorf("No images: %s\n", err) } w := tabwriter.NewWriter(os.Stdout, 20, 1, 3, ' ', 0) if io.Verbose { fmt.Fprintf(w, "REPO\tTAG\tID\tPARENT\tCREATED\n") } else { fmt.Fprintf(w, "REPO\tTAG\tID\n") } var repos []string for repo, _ := range ts.Repositories { repos = append(repos, repo) } sort.Strings(repos) for _, repo := range repos { tags := ts.Repositories[repo] var stags []string for tag, _ := range tags { stags = append(stags, tag) } sort.Strings(stags) for _, tag := range stags { id := tags[tag] if io.Verbose { img := ts.Entries[id] if img == nil { fmt.Fprintf(w, "%s\t%s\t%s\t%s\t%s\n", repo, tag, utils.TruncateID(id), "?", "?") } else { fmt.Fprintf(w, "%s\t%s\t%s\t%s\t%s\n", repo, tag, utils.TruncateID(id), utils.TruncateID(img.Parent), img.Created) } } else { fmt.Fprintf(w, "%s\t%s\t%s\n", repo, tag, utils.TruncateID(id)) } } } w.Flush() return nil }