11package cmd
22
33import (
4- "archive/zip"
54 "context"
65 "fmt"
76 "io/ioutil"
8- "os"
97 "time"
108
11- ignore "github.com/codeskyblue/dockerignore"
129 "github.com/spf13/cobra"
1310 "github.com/spf13/viper"
14- "github.com/yottab/cli/config"
11+ cliConfig "github.com/yottab/cli/config"
1512 ybApi "github.com/yottab/proto-api/proto"
13+ "gopkg.in/src-d/go-git.v4"
14+ "gopkg.in/src-d/go-git.v4/config"
15+ "gopkg.in/src-d/go-git.v4/plumbing/object"
16+ "gopkg.in/src-d/go-git.v4/plumbing/transport/http"
1617)
1718
1819const (
19- imageLogIDFormat = "%s:%s" // imageName:imageTag
20- archiveNameFormat = "repository_%s_archive.zip" //
21- bucketNameFormat = "yottab-bucket-build-%s" //
22- formatTempArchive = "YOTTAb.io.*.zip"
20+ ybRemoteName = "io.YOTTAb.git"
21+ pushLogIDFormat = "%s:%s" // imageName:imageTa
2322)
2423
25- var (
26- ignoreFile = ".dockerignore" // TODO get by EnvVar
27- )
28-
29- func imageBuild (cmd * cobra.Command , args []string ) {
24+ func pushRepository (cmd * cobra.Command , args []string ) {
3025 baseFolder := cmd .Flag ("path" ).Value .String () // Repository path
3126 imageTag := cmd .Flag ("tag" ).Value .String () // Repository tag
3227 imageName := cmd .Flag ("name" ).Value .String () // Repository name
33- zipName := fmt .Sprintf (archiveNameFormat , imageName )
3428
3529 checkExistDockerfile (baseFolder )
36- zipPath , err := zipFolder (baseFolder , zipName )
37- defer os .Remove (zipPath )
38- uiCheckErr ("Could not Archive the Folder" , err )
39- log .Printf ("archive folder at [%s]" , zipPath )
4030
41- zipArchiveURL , err := s3SendArchive (zipPath , zipName )
42- uiCheckErr ("Could not Save the Archive at s3.YOTTAb.io" , err )
43- log .Print ("Archive uploaded successfully." )
31+ push (imageName , imageTag , baseFolder )
4432
4533 client := grpcConnect ()
4634 defer client .Close ()
4735 req := new (ybApi.ImgBuildReq )
4836 req .RepositoryName = imageName
4937 req .RepositoryTag = imageTag
50- req . ZipArchiveURL = zipArchiveURL
51- _ , err = client .V2 ().ImgBuild (client .Context (), req )
38+
39+ _ , err : = client .V2 ().ImgBuild (client .Context (), req )
5240 uiCheckErr ("Could not Build the Repository" , err )
53- log .Print ("Build started!" )
54- log .Print ("Waiting for builder log to get ready..." )
41+ log .Print ("Build started!\r \n Waiting for builder log to get ready..." )
5542 time .Sleep (20 * time .Second )
56- getBuildLog (imageName , imageTag )
43+ getPushLog (imageName , imageTag )
44+ log .Printf ("Enter this command to see more:\r \n $: yb push log --name=%s --tag=%s\r \n " , imageName , imageTag )
5745}
5846
59- func imageBuildLog (cmd * cobra.Command , args []string ) {
47+ func pushLog (cmd * cobra.Command , args []string ) {
6048 imageTag := cmd .Flag ("tag" ).Value .String () // Repository tag
6149 imageName := cmd .Flag ("name" ).Value .String () // Repository name
62- getBuildLog (imageName , imageTag )
50+ getPushLog (imageName , imageTag )
6351}
6452
65- func getBuildLog ( imageName , imageTag string ) {
53+ func getPushLog ( appName , appTag string ) {
6654 id := getRequestIdentity (
67- fmt .Sprintf (imageLogIDFormat , imageName , imageTag ))
55+ fmt .Sprintf (pushLogIDFormat , appName , appTag ))
6856 client := grpcConnect ()
6957 defer client .Close ()
7058 logClient , err := client .V2 ().ImgBuildLog (context .Background (), id )
71- uiCheckErr (fmt .Sprintf ("Could not get build log right now!\n Try again in a few soconds using $yb build- log --name=%s --tag=%s" , imageName , imageTag ), err )
59+ uiCheckErr (fmt .Sprintf ("Could not get build log right now!\n Try again in a few soconds using: \n $yb push log --name=%s --tag=%s" , appName , appTag ), err )
7260 uiImageLog (logClient )
7361
7462}
7563
76- func s3SendArchive (zipFilePath , objectName string ) (uri string , err error ) {
77- var bucketName = fmt .Sprintf (bucketNameFormat , viper .GetString (config .KEY_USER ))
78-
79- // Initialize minio client object.
80- minioClient := initializeObjectStore ()
81-
82- // Initialize Archive bucket.
83- if err = initializeS3ArchiveBucket (minioClient , bucketName ); err != nil {
84- log .Printf ("Err: Initialize S3 Archive bucket, Err:%v" , err )
85- return
86- }
87-
88- // save Archive File
89- if err = s3PutObject (minioClient , zipFilePath , bucketName , objectName ); err != nil {
90- log .Printf ("Err: Put S3 Archive bucket, Err:%v" , err )
91- return
92- }
93-
94- // Genrate URL for Download
95- uriObj , err := minioClient .PresignedGetObject (bucketName , objectName , time .Hour * 16 , nil )
96- if err != nil {
97- log .Printf ("Err: Put Object to Bucket:%s, Path:%s, Name:%s, Err:%v" , bucketName , zipFilePath , objectName , err )
98- return
99- }
100- return uriObj .String (), nil
101- }
102-
10364func checkExistDockerfile (basePath string ) {
10465 files , err := ioutil .ReadDir (basePath )
10566 if err != nil {
@@ -114,95 +75,101 @@ func checkExistDockerfile(basePath string) {
11475 log .Fatalf ("Err: can find Dockerfile at [%s]" , basePath )
11576}
11677
117- func zipFolder (baseFolder , archFileName string ) (archivePath string , err error ) {
118- ignorePatterns := readIgnorePatterns ()
78+ func push (imageName , imageTag , repoPath string ) {
79+ user := viper .GetString (cliConfig .KEY_USER )
80+ token := viper .GetString (cliConfig .KEY_TOKEN )
11981
120- // Get a TempFile Buffer
121- //archiveFileName := fmt.Sprintf()
122- outFile , err := ioutil .TempFile ("" , formatTempArchive )
123- uiCheckErr ("Could not create file" , err )
124- archivePath = outFile .Name ()
125- log .Printf ("Successfully create Archive file at [%s]" , archivePath )
126-
127- // Create a new zip archive.
128- w := zip .NewWriter (outFile )
129-
130- // Add some files to the archive.
131- err = zipAddFiles (w , baseFolder , "" , archFileName , ignorePatterns )
132- uiCheckErr ("Could not create Archive file" , err )
82+ repo , err := getYbRepo (repoPath , imageName , user )
83+ if err != nil {
84+ log .Fatal ("getYbRepo: " , err )
85+ }
13386
134- // Make sure to check the error on Close.
135- err = w . Close ( )
136- uiCheckErr ( "Could not Close Archive file" , err )
87+ if repositoryYbIsClean ( repo ) == false {
88+ repositoryYbCommit ( repo , imageTag )
89+ }
13790
138- return
91+ fmt .Println ("Start PUSH" )
92+ err = ybPush (repo , user , token )
93+ uiCheckErr ("push.ybPush" , err )
13994}
14095
141- func zipAddFiles (w * zip.Writer , basePath , baseInZip , archFileName string , ignorePatterns []string ) (err error ) {
142- // Open the Directory
143- files , err := ioutil .ReadDir (basePath )
144- if err != nil {
145- log .Printf ("ioutil.ReadDir Err: %v" , err )
146- return err
147- }
96+ func repositoryYbIsClean (repo * git.Repository ) bool {
97+ wt , err := repo .Worktree ()
98+ uiCheckErr ("repositoryYbIsClean.Worktree" , err )
14899
149- for _ , file := range files {
150- // if path in ignorePatterns, Skip path
151- if checkIgnoreMatches (
152- baseInZip + file .Name (), // File path in project
153- ignorePatterns ) {
154- continue
155- }
100+ s , err := wt .Status ()
101+ uiCheckErr ("repositoryYbIsClean.Status" , err )
156102
157- // archive file created at rootPath, dont add it
158- if len (baseInZip ) == 0 && (file .Name () == archFileName || file .Name () == ignoreFile ) {
159- continue
160- }
161-
162- if file .IsDir () {
163- // Recurse
164- newBase := fmt .Sprintf ("%s%s%c" , basePath , file .Name (), os .PathSeparator )
165- newBaseInZip := fmt .Sprintf ("%s%s%c" , baseInZip , file .Name (), os .PathSeparator )
103+ return s .IsClean ()
104+ }
166105
167- if err = zipAddFiles (w , newBase , newBaseInZip , archFileName , ignorePatterns ); err != nil {
168- log .Printf ("zipAddFiles basePath: %s, file:%s, Err: %v" , basePath , file .Name (), err )
169- return err
170- }
171- } else {
172- dat , err := ioutil .ReadFile (basePath + file .Name ())
173- if err != nil {
174- log .Printf ("zip ioutil.ReadFile Err: %v" , err )
175- return err
176- }
106+ func repositoryYbCommit (repo * git.Repository , tag string ) {
107+ w , err := repo .Worktree ()
108+ _ , err = w .Add ("." )
109+ uiCheckErr ("repositoryYbCommit.Add" , err )
110+
111+ _ , err = w .Commit (tag , & git.CommitOptions {
112+ Author : & object.Signature {
113+ When : time .Now (),
114+ },
115+ })
116+ uiCheckErr ("repositoryYbCommit.Commit" , err )
117+ }
177118
178- // Add some files to the archive.
179- f , err := w .Create (baseInZip + file .Name ())
180- if err != nil {
181- log .Printf ("zip.Writer.Create Err: %v" , err )
182- return err
183- }
184- _ , err = f .Write (dat )
119+ // getRepo open Repository and
120+ // if yottab.Remote not exist, add the Remote to Repository
121+ func getYbRepo (path , appName , user string ) (repo * git.Repository , err error ) {
122+ repo , err = git .PlainOpen (path )
123+ if err != nil {
124+ if err == git .ErrRepositoryNotExists {
125+ fmt .Printf ("Repasitory %s Create at %s" , appName , path )
126+ repo , err = git .PlainInit (path , false )
185127 if err != nil {
186- log .Printf ("zip.Writer.Write Err: %v" , err )
187- return err
128+ return
188129 }
130+ } else {
131+ return
189132 }
133+ fmt .Printf ("Repasitory %s open at %s" , appName , path )
190134 }
135+
136+ err = addYbRemote (repo , appName , user )
191137 return
192138}
193139
194- func readIgnorePatterns () (patterns []string ) {
195- patterns , err := ignore .ReadIgnoreFile (ignoreFile )
196- if os .IsNotExist (err ) {
197- return []string {}
140+ func ybPush (repo * git.Repository , user , pass string ) error {
141+ remo , err := repo .Remote (ybRemoteName )
142+ if err != nil {
143+ log .Println ("ybPush.Remote: " , err )
144+ return err
198145 }
199- uiCheckErr ("Read '.dockerignore' file" , err )
200- log .Printf ("Successfully reading data from of file [%s]" , ignoreFile )
201- return
146+
147+ err = remo .Push (& git.PushOptions {
148+ RemoteName : ybRemoteName ,
149+ Auth : & http.BasicAuth {
150+ Username : user ,
151+ Password : pass ,
152+ },
153+ })
154+
155+ return err
202156}
203157
204- func checkIgnoreMatches (path string , patterns []string ) (isSkip bool ) {
205- isSkip , err := ignore .Matches (path , patterns )
206- uiCheckErr ("DockerIgnore check for path [" + path + "]" , err )
207- return
158+ // addRemote Add a new remote, with the default fetch refspec
159+ func addYbRemote (repo * git.Repository , appName , user string ) error {
160+ // check exist YbRemote
161+ _ , err := repo .Remote (ybRemoteName )
162+ if err == git .ErrRemoteNotFound {
163+ _ , err = repo .CreateRemote (& config.RemoteConfig {
164+ Name : ybRemoteName ,
165+ URLs : []string {
166+ getRemoteURL (user , appName )},
167+ })
168+ }
169+
170+ return err
171+ }
172+
173+ func getRemoteURL (user , app string ) string {
174+ return fmt .Sprintf ("https://git.yottab.io/%s/%s.git" , user , app )
208175}
0 commit comments