github.com/mgoltzsche/ctnr@v0.7.1-alpha/cmd/commit.go (about) 1 // Copyright © 2017 Max Goltzsche 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 package cmd 16 17 import ( 18 "fmt" 19 "path/filepath" 20 21 "github.com/mgoltzsche/ctnr/image" 22 "github.com/mgoltzsche/ctnr/pkg/fs/tree" 23 "github.com/opencontainers/go-digest" 24 "github.com/pkg/errors" 25 "github.com/spf13/cobra" 26 ) 27 28 var ( 29 commitCmd = &cobra.Command{ 30 Use: "commit [flags] CONTAINER [IMAGENAME]", 31 Short: "Creates a new image from the current container", 32 Long: `Creates a new image from the current container.`, 33 Run: wrapRun(runCommit), 34 } 35 flagAuthor string 36 flagComment string 37 ) 38 39 func init() { 40 commitCmd.Flags().StringVarP(&flagAuthor, "author", "a", "", "Sets the new layer's author") 41 commitCmd.Flags().StringVarP(&flagComment, "comment", "c", "", "Sets the new layer's comment") 42 } 43 44 func runCommit(cmd *cobra.Command, args []string) (err error) { 45 if len(args) < 1 || len(args) > 2 { 46 return usageError("Invalid argument") 47 } 48 bundleId := args[0] 49 b, err := store.Bundle(bundleId) 50 if err != nil { 51 return 52 } 53 lockedBundle, err := b.Lock() 54 if err != nil { 55 return 56 } 57 defer lockedBundle.Close() 58 lockedStore, err := openImageStore() 59 if err != nil { 60 return 61 } 62 spec, err := lockedBundle.Spec() 63 if err != nil { 64 return 65 } 66 if spec.Root == nil { 67 return errors.Errorf("bundle %q has no root path", bundleId) 68 } 69 rootfs, err := tree.FromDir(filepath.Join(b.Dir(), spec.Root.Path), flagRootless) 70 if err != nil { 71 return 72 } 73 74 // Try to create new image 75 var ( 76 imgId digest.Digest 77 img image.Image 78 ) 79 if flagComment == "" { 80 flagComment = "commit" 81 } 82 if img, err = lockedStore.AddLayer(rootfs, lockedBundle.Image(), flagAuthor, flagComment); err == nil { 83 imgId = img.ID() 84 err = lockedBundle.SetParentImageId(&imgId) 85 } else if image.IsEmptyLayerDiff(err) { 86 bImgId := lockedBundle.Image() 87 if bImgId == nil { 88 panic("bundle has no parent but provides no layer contents") 89 } 90 imgId = *bImgId 91 err = nil 92 } 93 94 // Tag image 95 if err == nil { 96 if len(args) > 1 { 97 for _, tag := range args[1:] { 98 if _, err = lockedStore.TagImage(imgId, tag); err != nil { 99 return 100 } 101 } 102 } 103 fmt.Println(imgId) 104 } 105 return 106 }