github.com/ggreg80/ketos@v0.0.0-20171109040536-049616f51ddb/cmd/commit/command.go (about) 1 package commit 2 3 import ( 4 "encoding/json" 5 "io/ioutil" 6 "os" 7 "path/filepath" 8 "time" 9 10 manifestV1 "github.com/docker/distribution/manifest/schema1" 11 imageV1 "github.com/docker/docker/image" 12 "github.com/opencontainers/go-digest" 13 "github.com/setekhid/ketos/pkg/metadata" 14 "github.com/setekhid/ketos/pkg/registry" 15 "github.com/spf13/cobra" 16 ) 17 18 var ( 19 Command = &cobra.Command{ 20 Use: "commit", 21 Short: "commit [--tag|-t tag-name]", 22 Args: cobra.NoArgs, 23 24 RunE: commitMain, 25 } 26 ) 27 28 func init() { 29 30 flags := Command.Flags() 31 flags.StringP("tag", "t", "", "commit to a tag") 32 } 33 34 type blackHole struct{} 35 36 func (_ blackHole) Write(p []byte) (int, error) { return len(p), nil } 37 func (_ blackHole) Read(p []byte) (int, error) { return 0, nil } 38 func (_ blackHole) Close() error { return nil } 39 40 func commitMain(cmd *cobra.Command, args []string) error { 41 42 tag, err := cmd.Flags().GetString("tag") 43 if err != nil { 44 return err 45 } 46 47 meta, err := metadata.CurrentMetadatas() 48 if err != nil { 49 return err 50 } 51 52 containerPath := meta.ContainerPath() 53 metaFolderPath := meta.MetaFolderPath() 54 55 tmpDir, err := ioutil.TempDir("", "") 56 if err != nil { 57 return err 58 } 59 defer os.RemoveAll(tmpDir) 60 61 tmpPack := filepath.Join(tmpDir, "container-pack.tar.gz") 62 digest := digest.Digest("unknow") 63 64 // tar container pack 65 err = func() error { 66 containerPack, err := os.Create(tmpPack) 67 if err != nil { 68 return err 69 } 70 defer containerPack.Close() 71 72 digest, err = registry.TarLayerDirectory(containerPack, 73 containerPath, metaFolderPath) 74 75 return err 76 }() 77 if err != nil { 78 return err 79 } 80 81 // save container pack 82 packFile := meta.PackFile(digest) 83 err = os.Rename(tmpPack, packFile) 84 if err != nil { 85 return err 86 } 87 pack, err := os.Open(packFile) 88 if err != nil { 89 return err 90 } 91 defer pack.Close() 92 93 layerPath := meta.LayerPath(digest) 94 err = registry.UntarLayerDirectory(pack, layerPath) 95 if err != nil { 96 return err 97 } 98 99 // update manifest 100 manifest, err := meta.GetManifest(tag) 101 if err != nil { 102 return err 103 } 104 105 manifest.FSLayers = append( 106 []manifestV1.FSLayer{ 107 {BlobSum: digest}, 108 }, 109 manifest.FSLayers..., 110 ) 111 112 shit := manifest.History[0] 113 imageShit := &imageV1.V1Image{} 114 err = json.Unmarshal([]byte(shit.V1Compatibility), imageShit) 115 if err != nil { 116 return err 117 } 118 119 imageJson, err := json.Marshal(&imageV1.V1Image{ 120 ID: digest.Hex(), 121 Parent: imageShit.ID, 122 Created: time.Now(), 123 }) 124 if err != nil { 125 return err 126 } 127 manifest.History = append( 128 []manifestV1.History{ 129 {V1Compatibility: string(imageJson)}, 130 }, 131 manifest.History..., 132 ) 133 134 return meta.PutManifest(tag, manifest) 135 }