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  }