]> xenbits.xensource.com Git - people/gdunlap/xsatool.git/commitdiff
main: Add partial implementation of sync-patches command
authorGeorge Dunlap <george.dunlap@citrix.com>
Fri, 24 Mar 2017 11:07:16 +0000 (11:07 +0000)
committerGeorge Dunlap <george.dunlap@citrix.com>
Fri, 24 Mar 2017 11:07:16 +0000 (11:07 +0000)
Partial implementation of sync-patches, which will look for trees
which contain xsa/NNN/VVV and xsa/NNN/VVV-baseline and run
`git format-patch` to generate patches.

To do this:
 - Implement Repo.FormatPatch()
 - Implement XSAMeta.GetRecipe(version) to get a recipe for a specific version
 - Modify IsApplied() to look for both $prefix/NNN/VVV and $prefix/NNN/VVV-baseline
 - Implement Recipe.MakePatches()
 - Modify IsApplied() to return only an error; but make return a
   distinguishable type to say what branch wasn't applied

A full implementation would also copy the patches into xsa.git either
as a single patch or a directory full of patches, as appropriate.

Signed-off-by: George Dunlap <george.dunlap@citrix.com>
git.go
main.go
meta.go
recipe.go
test.go
xsa.go [new file with mode: 0644]

diff --git a/git.go b/git.go
index 72c83e6785b744f9d91109a7284071d033a17ca7..0bf6a7af26eff10214b6509dd4408766e056e6c1 100644 (file)
--- a/git.go
+++ b/git.go
@@ -111,6 +111,12 @@ func (r Repo) DeleteBranch(branch string) (out []byte, err error) {
        return
 }
 
+func (r Repo) FormatPatch(path string, baseline string, branch string) (out []byte, err error) {
+       out, err = r.gitCmd("format-patch", "-o"+path, baseline+".."+branch)
+
+       return
+}
+
 func (r Repo) Am(amglob string) (out []byte, err error) {
        files, err := filepath.Glob(amglob)
        if err != nil {
diff --git a/main.go b/main.go
index b29aaabe6b7482acef028bb1e40c224138dc20ef..8f6dc233bed165f50039fe0a201bbfe21751d93a 100644 (file)
--- a/main.go
+++ b/main.go
@@ -68,6 +68,9 @@ func main() {
                                fmt.Printf("Would make new XSA %d\n", xsanum)
                                return 0
                        }
+               case "sync-patches":
+                       main = MainSyncPatches
+                       loadConfig = true
                default:
                        fmt.Printf("Unknown command: %s\n", cmd)
                        os.Exit(1)
@@ -117,7 +120,7 @@ func main() {
                                },
                                Recipe{
                                        XenVersionFull: XenVersionFull("4.5.5"),
-                                       Xen: TreeRecipe{ Patches: []string{"xsa206-4.6/*.patch"} },
+                                       Xen: TreeRecipe{ Patches: []string{"xsa206-4.5/*.patch"} },
                                },
                                Recipe{
                                        XenVersionFull: XenVersionFull("4.4.4"),
diff --git a/meta.go b/meta.go
index e6467ce13f569ba4a1445945612f7dc9b259d2d3..82158332bc898b105b6514314b804347d523761d 100644 (file)
--- a/meta.go
+++ b/meta.go
@@ -95,6 +95,15 @@ type XSAMeta struct {
        Recipes           []Recipe
 }
 
+func (m *XSAMeta) GetRecipe(v XenVersion) (*Recipe) {
+       for i := range m.Recipes {
+               if v == m.Recipes[i].XenVersionFull.XenVersion() {
+                       return &m.Recipes[i]
+               }
+       }
+       return nil
+}
+
 func (m *XSAMeta) Normalize() {
        for i := range m.Recipes {
                m.Recipes[i].xsa = m.XSA
index 7965fe717a5be1d8a23f4ce6de9e20ce7d0b8dac..1d81930d09ad3abf48eb2153d8faaf7c655daf12 100644 (file)
--- a/recipe.go
+++ b/recipe.go
@@ -53,25 +53,112 @@ type Recipe struct {
        xsa                 int
 }
 
-func (r *Recipe) IsApplied(prefix string) (ok bool, err error) {
-       branch, _ := r.branchName(prefix)
+const FPPath = "/tmp/xsatool-formatpatch"
+
+func (r *Recipe) MakePatches(prefix string) (err error) {
+       count := 0
+       branch, baseline := r.branchName(prefix)
+
+       // rm -rf /tmp/xsa
+       if err = os.RemoveAll(FPPath); err != nil {
+               err = fmt.Errorf("Removing temporary path: %v", err)
+               return
+       }
        
-       if r.Xen.HasPatches() && !repos.xen.VerifyRef(branch) {
-               ok = false
-               return 
+       
+       // mkdir /tmp/xsa
+       if err = os.Mkdir(FPPath, 0777); err != nil {
+               err = fmt.Errorf("Making temporary path %s: %v\n", FPPath, err)
+               return
        }
+       
+       makePatches := func(xr *XenRepo, repo string) (err error) {
+               if !xr.VerifyRef(branch) {
+                       return
+               }
+               if !xr.VerifyRef(baseline) {
+                       fmt.Printf("WARNING: Repo %s has branch %s but no branch %s, skipping\n",
+                               repo, branch, baseline)
+                       return
+               }
 
-       if r.QemuUpstream.HasPatches() && !repos.qemuu.VerifyRef(branch) {
-               ok = false
-               return 
+               count++
+
+               path := FPPath+"/"+repo
+               
+               if err = os.Mkdir(path, 0777); err != nil {
+                       err = fmt.Errorf("Making temporary path %s: %v", path, err)
+                       return
+               }
+
+               // git format-patch -o/tmp/xsa master
+               if _, err = xr.FormatPatch(path, baseline, branch); err != nil {
+                       err = fmt.Errorf("Format-patch: %v", err)
+                       return
+               }
+               
+               // rm -rf ../xsa.git/xsa206-unstable && mkdir ../xsa.git/xsa206-unstable && cp /tmp/xsa/* ../xsa.git/xsa206-unstable
+               
+               return
        }
 
-       if r.QemuTraditional.HasPatches() && !repos.qemut.VerifyRef(branch) {
-               ok = false
-               return 
+       if err = makePatches(&repos.xen, "xen"); err != nil {
+               return
+       }
+       if err = makePatches(&repos.qemuu, "qemuu"); err != nil {
+               return
+       }
+       if err = makePatches(&repos.qemut, "qemut"); err != nil {
+               return
+       }
+
+       if count == 0 {
+               err = fmt.Errorf("No patches created")
+               return
+       }
+       return
+}
+
+type ErrorMissingBranch string
+
+func (s ErrorMissingBranch) Error() string {
+       return fmt.Sprintf("Missing branch: %s", s)
+}
+
+// IsApplied returns nil if the patch has been properly applied.  It
+// returns an error of type ErrorMissingBranch if there's a missing
+// branch (which is aliased as a string which tells you the name of
+// the missing branch); otherwise it returns whatever error it
+// encountered when processing.
+func (r *Recipe) IsApplied(prefix string) (err error) {
+       branch, baseline := r.branchName(prefix)
+
+       check := func(xr *XenRepo) (err error) {
+               if !xr.VerifyRef(branch) {
+                       return ErrorMissingBranch(branch)
+               }
+               if !xr.VerifyRef(baseline) {
+                       return ErrorMissingBranch(baseline)
+               }
+               return
+       }
+       
+       if r.Xen.HasPatches() {
+               if err = check(&repos.xen) ; err != nil {
+                       return
+               }
+       }
+       if r.QemuUpstream.HasPatches() {
+               if err = check(&repos.qemuu) ; err != nil {
+                       return
+               }
+       }
+       if r.QemuTraditional.HasPatches() {
+               if err = check(&repos.qemut) ; err != nil {
+                       return
+               }
        }
 
-       ok = true
        return
 }
 
diff --git a/test.go b/test.go
index 898e915b35f49228cc395fd4525a195009f8e34a..fe2c80d18be6ce22ae063b383123be38837fff6f 100644 (file)
--- a/test.go
+++ b/test.go
@@ -12,8 +12,8 @@ func backport(xsa *XSAMeta) (ret int) {
                prefix := "xsa"
                r := &xsa.Recipes[i]
 
-               if ok, err := r.IsApplied(prefix); !ok {
-                       if err != nil {
+               if err := r.IsApplied(prefix); err != nil {
+                       if _, isMissingBranch := err.(ErrorMissingBranch); !isMissingBranch {
                                fmt.Printf("Error checking to see if recipe has been applied: %v\n", err)
                                return 1
                        }
@@ -32,7 +32,7 @@ func backport(xsa *XSAMeta) (ret int) {
                                return 1
                        }
                        fmt.Printf("SUCCESS: %v\n", r.XenVersionFull)
-               }
+               } 
 
        }
 
@@ -41,6 +41,9 @@ func backport(xsa *XSAMeta) (ret int) {
 
 func test(xsa *XSAMeta) (ret int) {
        for i := range xsa.Recipes {
+               if i == 0 {
+                       continue
+               }
                prefix := "test"
                r := &xsa.Recipes[i]
 
@@ -64,9 +67,20 @@ func test(xsa *XSAMeta) (ret int) {
        return 0
 }
 
-// Syncing an edited version back to xsa.git:
-// rm -rf /tmp/xsa && mkdir /tmp/xsa && git format-patch -o/tmp/xsa master && rm -rf ../xsa.git/xsa206-unstable && mkdir ../xsa.git/xsa206-unstable && cp /tmp/xsa/* ../xsa.git/xsa206-unstable
+func apply45(xsa *XSAMeta) (ret int) {
+       r := xsa.GetRecipe(XenVersion("4.5"))
+       if r == nil {
+               fmt.Printf("Couldn't get recipe")
+               return 1
+       }
+
+       if err := r.Apply("xsa"); err != nil {
+               fmt.Printf("Applying recipe: %v\n", err)
+               return 1
+       }
 
+       return 0
+}
 
 
 func MainTest(xsanum int, args []string) (ret int) {
diff --git a/xsa.go b/xsa.go
new file mode 100644 (file)
index 0000000..3922cd0
--- /dev/null
+++ b/xsa.go
@@ -0,0 +1,35 @@
+package main
+
+import (
+       "fmt"
+)
+
+func MainSyncPatches(xsanum int, args []string) (ret int) {
+       err := OpenRepos()
+       if err != nil {
+               fmt.Printf("Error initializing repos: %v\n", err)
+               return 1
+       }
+
+       // FIXME
+       if len(args) == 1 && args[0] == "all" {
+               fmt.Printf("Sorry, sync-patches 'all' not implemented yet")
+               return 1
+       }
+
+       for _, v := range args {
+               // FIXME: Check XenVersion format
+               r := xsa.GetRecipe(XenVersion(v))
+               if r == nil {
+                       fmt.Printf("Couldn't find recipe for XenVersion %s\n", v)
+                       return 1
+               }
+
+               if err := r.MakePatches("xsa"); err != nil {
+                       fmt.Printf("Making patches: %v\n", err)
+                       return 1
+               }
+       }
+       
+       return 0
+}