mirror of
https://github.com/rocky-linux/srpmproc.git
synced 2024-11-16 10:11:24 +00:00
enhancement: make it a real library and drop srpm mode
This commit is contained in:
parent
7d84156a4b
commit
23bea74126
@ -21,23 +21,8 @@
|
|||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
|
||||||
"github.com/rocky-linux/srpmproc/pkg/srpmproc"
|
"github.com/rocky-linux/srpmproc/pkg/srpmproc"
|
||||||
"log"
|
"log"
|
||||||
"os"
|
|
||||||
"os/user"
|
|
||||||
"path/filepath"
|
|
||||||
"strings"
|
|
||||||
|
|
||||||
"github.com/go-git/go-billy/v5"
|
|
||||||
"github.com/go-git/go-billy/v5/memfs"
|
|
||||||
"github.com/go-git/go-billy/v5/osfs"
|
|
||||||
"github.com/go-git/go-git/v5/plumbing/transport/ssh"
|
|
||||||
"github.com/rocky-linux/srpmproc/pkg/blob"
|
|
||||||
"github.com/rocky-linux/srpmproc/pkg/blob/file"
|
|
||||||
"github.com/rocky-linux/srpmproc/pkg/blob/gcs"
|
|
||||||
"github.com/rocky-linux/srpmproc/pkg/blob/s3"
|
|
||||||
"github.com/rocky-linux/srpmproc/pkg/data"
|
|
||||||
|
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
)
|
)
|
||||||
@ -62,7 +47,6 @@ var (
|
|||||||
noStorageDownload bool
|
noStorageDownload bool
|
||||||
noStorageUpload bool
|
noStorageUpload bool
|
||||||
manualCommits string
|
manualCommits string
|
||||||
upstreamPrefixHttps string
|
|
||||||
moduleFallbackStream string
|
moduleFallbackStream string
|
||||||
allowStreamBranches bool
|
allowStreamBranches bool
|
||||||
)
|
)
|
||||||
@ -73,104 +57,37 @@ var root = &cobra.Command{
|
|||||||
}
|
}
|
||||||
|
|
||||||
func mn(_ *cobra.Command, _ []string) {
|
func mn(_ *cobra.Command, _ []string) {
|
||||||
switch version {
|
pd, err := srpmproc.NewProcessData(&srpmproc.ProcessDataRequest{
|
||||||
case 8:
|
|
||||||
break
|
|
||||||
default:
|
|
||||||
log.Fatalf("unsupported upstream version %d", version)
|
|
||||||
}
|
|
||||||
|
|
||||||
var importer data.ImportMode
|
|
||||||
var blobStorage blob.Storage
|
|
||||||
|
|
||||||
if strings.HasPrefix(storageAddr, "gs://") {
|
|
||||||
blobStorage = gcs.New(strings.Replace(storageAddr, "gs://", "", 1))
|
|
||||||
} else if strings.HasPrefix(storageAddr, "s3://") {
|
|
||||||
blobStorage = s3.New(strings.Replace(storageAddr, "s3://", "", 1))
|
|
||||||
} else if strings.HasPrefix(storageAddr, "file://") {
|
|
||||||
blobStorage = file.New(strings.Replace(storageAddr, "file://", "", 1))
|
|
||||||
} else {
|
|
||||||
log.Fatalf("invalid blob storage")
|
|
||||||
}
|
|
||||||
|
|
||||||
sourceRpmLocation := ""
|
|
||||||
if strings.HasPrefix(sourceRpm, "file://") {
|
|
||||||
sourceRpmLocation = strings.TrimPrefix(sourceRpm, "file://")
|
|
||||||
importer = &srpmproc.SrpmMode{}
|
|
||||||
} else {
|
|
||||||
if moduleMode {
|
|
||||||
sourceRpmLocation = fmt.Sprintf("%s/%s", modulePrefix, sourceRpm)
|
|
||||||
} else {
|
|
||||||
sourceRpmLocation = fmt.Sprintf("%s/%s", rpmPrefix, sourceRpm)
|
|
||||||
}
|
|
||||||
importer = &srpmproc.GitMode{}
|
|
||||||
}
|
|
||||||
|
|
||||||
lastKeyLocation := sshKeyLocation
|
|
||||||
if lastKeyLocation == "" {
|
|
||||||
usr, err := user.Current()
|
|
||||||
if err != nil {
|
|
||||||
log.Fatalf("could not get user: %v", err)
|
|
||||||
}
|
|
||||||
lastKeyLocation = filepath.Join(usr.HomeDir, ".ssh/id_rsa")
|
|
||||||
}
|
|
||||||
|
|
||||||
var authenticator *ssh.PublicKeys
|
|
||||||
|
|
||||||
var err error
|
|
||||||
// create ssh key authenticator
|
|
||||||
authenticator, err = ssh.NewPublicKeysFromFile(sshUser, lastKeyLocation, "")
|
|
||||||
if err != nil {
|
|
||||||
log.Fatalf("could not get git authenticator: %v", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
fsCreator := func(branch string) billy.Filesystem {
|
|
||||||
return memfs.New()
|
|
||||||
}
|
|
||||||
|
|
||||||
if tmpFsMode != "" {
|
|
||||||
log.Printf("using tmpfs dir: %s", tmpFsMode)
|
|
||||||
fsCreator = func(branch string) billy.Filesystem {
|
|
||||||
tmpDir := filepath.Join(tmpFsMode, branch)
|
|
||||||
err := os.MkdirAll(tmpDir, 0755)
|
|
||||||
if err != nil {
|
|
||||||
log.Fatalf("could not create tmpfs dir: %v", err)
|
|
||||||
}
|
|
||||||
return osfs.New(tmpDir)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
var manualCs []string
|
|
||||||
if strings.TrimSpace(manualCommits) != "" {
|
|
||||||
manualCs = strings.Split(manualCommits, ",")
|
|
||||||
}
|
|
||||||
|
|
||||||
srpmproc.ProcessRPM(&data.ProcessData{
|
|
||||||
Importer: importer,
|
|
||||||
RpmLocation: sourceRpmLocation,
|
|
||||||
UpstreamPrefix: upstreamPrefix,
|
|
||||||
SshKeyLocation: sshKeyLocation,
|
|
||||||
SshUser: sshUser,
|
|
||||||
Version: version,
|
Version: version,
|
||||||
BlobStorage: blobStorage,
|
StorageAddr: storageAddr,
|
||||||
GitCommitterName: gitCommitterName,
|
Package: sourceRpm,
|
||||||
GitCommitterEmail: gitCommitterEmail,
|
|
||||||
ModulePrefix: modulePrefix,
|
|
||||||
ImportBranchPrefix: importBranchPrefix,
|
|
||||||
BranchPrefix: branchPrefix,
|
|
||||||
SingleTag: singleTag,
|
|
||||||
Authenticator: authenticator,
|
|
||||||
NoDupMode: noDupMode,
|
|
||||||
ModuleMode: moduleMode,
|
ModuleMode: moduleMode,
|
||||||
TmpFsMode: tmpFsMode,
|
TmpFsMode: tmpFsMode,
|
||||||
NoStorageDownload: noStorageDownload,
|
ModulePrefix: modulePrefix,
|
||||||
NoStorageUpload: noStorageUpload,
|
RpmPrefix: rpmPrefix,
|
||||||
ManualCommits: manualCs,
|
SshKeyLocation: sshKeyLocation,
|
||||||
UpstreamPrefixHttps: upstreamPrefixHttps,
|
SshUser: sshUser,
|
||||||
ModuleFallbackStream: moduleFallbackStream,
|
ManualCommits: manualCommits,
|
||||||
|
UpstreamPrefix: upstreamPrefix,
|
||||||
|
GitCommitterName: gitCommitterName,
|
||||||
|
GitCommitterEmail: gitCommitterEmail,
|
||||||
|
ImportBranchPrefix: importBranchPrefix,
|
||||||
|
BranchPrefix: branchPrefix,
|
||||||
|
NoDupMode: noDupMode,
|
||||||
AllowStreamBranches: allowStreamBranches,
|
AllowStreamBranches: allowStreamBranches,
|
||||||
FsCreator: fsCreator,
|
ModuleFallbackStream: moduleFallbackStream,
|
||||||
|
NoStorageUpload: noStorageUpload,
|
||||||
|
NoStorageDownload: noStorageDownload,
|
||||||
|
SingleTag: singleTag,
|
||||||
})
|
})
|
||||||
|
if err != nil {
|
||||||
|
log.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
err = srpmproc.ProcessRPM(pd)
|
||||||
|
if err != nil {
|
||||||
|
log.Fatal(err)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
@ -198,7 +115,6 @@ func main() {
|
|||||||
root.Flags().BoolVar(&noStorageDownload, "no-storage-download", false, "If enabled, blobs are always downloaded from upstream")
|
root.Flags().BoolVar(&noStorageDownload, "no-storage-download", false, "If enabled, blobs are always downloaded from upstream")
|
||||||
root.Flags().BoolVar(&noStorageUpload, "no-storage-upload", false, "If enabled, blobs are not uploaded to blob storage")
|
root.Flags().BoolVar(&noStorageUpload, "no-storage-upload", false, "If enabled, blobs are not uploaded to blob storage")
|
||||||
root.Flags().StringVar(&manualCommits, "manual-commits", "", "Comma separated branch and commit list for packages with broken release tags (Format: BRANCH:HASH)")
|
root.Flags().StringVar(&manualCommits, "manual-commits", "", "Comma separated branch and commit list for packages with broken release tags (Format: BRANCH:HASH)")
|
||||||
root.Flags().StringVar(&upstreamPrefixHttps, "upstream-prefix-https", "", "Web version of upstream prefix. Required if module-mode")
|
|
||||||
root.Flags().StringVar(&moduleFallbackStream, "module-fallback-stream", "", "Override fallback stream. Some module packages are published as collections and mostly use the same stream name, some of them deviate from the main stream")
|
root.Flags().StringVar(&moduleFallbackStream, "module-fallback-stream", "", "Override fallback stream. Some module packages are published as collections and mostly use the same stream name, some of them deviate from the main stream")
|
||||||
root.Flags().BoolVar(&allowStreamBranches, "allow-stream-branches", false, "Allow import from stream branches")
|
root.Flags().BoolVar(&allowStreamBranches, "allow-stream-branches", false, "Allow import from stream branches")
|
||||||
|
|
||||||
|
@ -21,22 +21,21 @@
|
|||||||
package data
|
package data
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/cavaliercoder/go-rpm"
|
|
||||||
"github.com/go-git/go-git/v5"
|
"github.com/go-git/go-git/v5"
|
||||||
"hash"
|
"hash"
|
||||||
)
|
)
|
||||||
|
|
||||||
type ImportMode interface {
|
type ImportMode interface {
|
||||||
RetrieveSource(pd *ProcessData) *ModeData
|
RetrieveSource(pd *ProcessData) (*ModeData, error)
|
||||||
WriteSource(pd *ProcessData, md *ModeData)
|
WriteSource(pd *ProcessData, md *ModeData) error
|
||||||
PostProcess(md *ModeData)
|
PostProcess(md *ModeData) error
|
||||||
ImportName(pd *ProcessData, md *ModeData) string
|
ImportName(pd *ProcessData, md *ModeData) string
|
||||||
}
|
}
|
||||||
|
|
||||||
type ModeData struct {
|
type ModeData struct {
|
||||||
|
Name string
|
||||||
Repo *git.Repository
|
Repo *git.Repository
|
||||||
Worktree *git.Worktree
|
Worktree *git.Worktree
|
||||||
RpmFile *rpm.PackageFile
|
|
||||||
FileWrites map[string][]byte
|
FileWrites map[string][]byte
|
||||||
TagBranch string
|
TagBranch string
|
||||||
PushBranch string
|
PushBranch string
|
||||||
|
@ -26,6 +26,8 @@ import (
|
|||||||
"github.com/rocky-linux/srpmproc/pkg/blob"
|
"github.com/rocky-linux/srpmproc/pkg/blob"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
type FsCreatorFunc func(branch string) (billy.Filesystem, error)
|
||||||
|
|
||||||
type ProcessData struct {
|
type ProcessData struct {
|
||||||
RpmLocation string
|
RpmLocation string
|
||||||
UpstreamPrefix string
|
UpstreamPrefix string
|
||||||
@ -48,8 +50,7 @@ type ProcessData struct {
|
|||||||
NoStorageDownload bool
|
NoStorageDownload bool
|
||||||
NoStorageUpload bool
|
NoStorageUpload bool
|
||||||
ManualCommits []string
|
ManualCommits []string
|
||||||
UpstreamPrefixHttps string
|
|
||||||
ModuleFallbackStream string
|
ModuleFallbackStream string
|
||||||
AllowStreamBranches bool
|
AllowStreamBranches bool
|
||||||
FsCreator func(branch string) billy.Filesystem
|
FsCreator FsCreatorFunc
|
||||||
}
|
}
|
||||||
|
@ -234,7 +234,7 @@ func specChange(cfg *srpmprocpb.Cfg, pd *data.ProcessData, md *data.ModeData, _
|
|||||||
hasPatch := false
|
hasPatch := false
|
||||||
|
|
||||||
version := ""
|
version := ""
|
||||||
importName := strings.Replace(pd.Importer.ImportName(pd, md), md.RpmFile.Name(), "1", 1)
|
importName := strings.Replace(pd.Importer.ImportName(pd, md), md.Name, "1", 1)
|
||||||
importNameSplit := strings.SplitN(importName, "-", 2)
|
importNameSplit := strings.SplitN(importName, "-", 2)
|
||||||
if len(importNameSplit) == 2 {
|
if len(importNameSplit) == 2 {
|
||||||
versionSplit := strings.SplitN(importNameSplit[1], ".el", 2)
|
versionSplit := strings.SplitN(importNameSplit[1], ".el", 2)
|
||||||
|
14
pkg/misc/regex.go
Normal file
14
pkg/misc/regex.go
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
package misc
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"regexp"
|
||||||
|
)
|
||||||
|
|
||||||
|
func GetTagImportRegex(importBranchPrefix string, allowStreamBranches bool) *regexp.Regexp {
|
||||||
|
if allowStreamBranches {
|
||||||
|
return regexp.MustCompile(fmt.Sprintf("refs/tags/(imports/(%s(?:.s|.)|%s(?:|s).+)/(.*))", importBranchPrefix, importBranchPrefix))
|
||||||
|
} else {
|
||||||
|
return regexp.MustCompile(fmt.Sprintf("refs/tags/(imports/(%s.|%s.-.+)/(.*))", importBranchPrefix, importBranchPrefix))
|
||||||
|
}
|
||||||
|
}
|
@ -18,10 +18,11 @@
|
|||||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
// SOFTWARE.
|
// SOFTWARE.
|
||||||
|
|
||||||
package srpmproc
|
package modes
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"github.com/rocky-linux/srpmproc/pkg/misc"
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
"log"
|
"log"
|
||||||
"net/http"
|
"net/http"
|
||||||
@ -60,15 +61,15 @@ func (p remoteTargetSlice) Swap(i, j int) {
|
|||||||
|
|
||||||
type GitMode struct{}
|
type GitMode struct{}
|
||||||
|
|
||||||
func (g *GitMode) RetrieveSource(pd *data.ProcessData) *data.ModeData {
|
func (g *GitMode) RetrieveSource(pd *data.ProcessData) (*data.ModeData, error) {
|
||||||
repo, err := git.Init(memory.NewStorage(), memfs.New())
|
repo, err := git.Init(memory.NewStorage(), memfs.New())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatalf("could not init git Repo: %v", err)
|
return nil, fmt.Errorf("could not init git Repo: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
w, err := repo.Worktree()
|
w, err := repo.Worktree()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatalf("could not get Worktree: %v", err)
|
return nil, fmt.Errorf("could not get Worktree: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
refspec := config.RefSpec("+refs/heads/*:refs/remotes/*")
|
refspec := config.RefSpec("+refs/heads/*:refs/remotes/*")
|
||||||
@ -78,7 +79,7 @@ func (g *GitMode) RetrieveSource(pd *data.ProcessData) *data.ModeData {
|
|||||||
Fetch: []config.RefSpec{refspec},
|
Fetch: []config.RefSpec{refspec},
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatalf("could not create remote: %v", err)
|
return nil, fmt.Errorf("could not create remote: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
err = remote.Fetch(&git.FetchOptions{
|
err = remote.Fetch(&git.FetchOptions{
|
||||||
@ -87,7 +88,7 @@ func (g *GitMode) RetrieveSource(pd *data.ProcessData) *data.ModeData {
|
|||||||
Force: true,
|
Force: true,
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatalf("could not fetch upstream: %v", err)
|
return nil, fmt.Errorf("could not fetch upstream: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
var branches remoteTargetSlice
|
var branches remoteTargetSlice
|
||||||
@ -97,8 +98,8 @@ func (g *GitMode) RetrieveSource(pd *data.ProcessData) *data.ModeData {
|
|||||||
tagAdd := func(tag *object.Tag) error {
|
tagAdd := func(tag *object.Tag) error {
|
||||||
if strings.HasPrefix(tag.Name, fmt.Sprintf("imports/%s%d", pd.ImportBranchPrefix, pd.Version)) {
|
if strings.HasPrefix(tag.Name, fmt.Sprintf("imports/%s%d", pd.ImportBranchPrefix, pd.Version)) {
|
||||||
refSpec := fmt.Sprintf("refs/tags/%s", tag.Name)
|
refSpec := fmt.Sprintf("refs/tags/%s", tag.Name)
|
||||||
if tagImportRegex.MatchString(refSpec) {
|
if misc.GetTagImportRegex(pd.ImportBranchPrefix, pd.AllowStreamBranches).MatchString(refSpec) {
|
||||||
match := tagImportRegex.FindStringSubmatch(refSpec)
|
match := misc.GetTagImportRegex(pd.ImportBranchPrefix, pd.AllowStreamBranches).FindStringSubmatch(refSpec)
|
||||||
|
|
||||||
exists := latestTags[match[2]]
|
exists := latestTags[match[2]]
|
||||||
if exists != nil && exists.when.After(tag.Tagger.When) {
|
if exists != nil && exists.when.After(tag.Tagger.When) {
|
||||||
@ -116,13 +117,13 @@ func (g *GitMode) RetrieveSource(pd *data.ProcessData) *data.ModeData {
|
|||||||
|
|
||||||
tagIter, err := repo.TagObjects()
|
tagIter, err := repo.TagObjects()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatalf("could not get tag objects: %v", err)
|
return nil, fmt.Errorf("could not get tag objects: %v", err)
|
||||||
}
|
}
|
||||||
_ = tagIter.ForEach(tagAdd)
|
_ = tagIter.ForEach(tagAdd)
|
||||||
|
|
||||||
list, err := remote.List(&git.ListOptions{})
|
list, err := remote.List(&git.ListOptions{})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatalf("could not list upstream: %v", err)
|
return nil, fmt.Errorf("could not list upstream: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, ref := range list {
|
for _, ref := range list {
|
||||||
@ -153,18 +154,18 @@ func (g *GitMode) RetrieveSource(pd *data.ProcessData) *data.ModeData {
|
|||||||
}
|
}
|
||||||
|
|
||||||
return &data.ModeData{
|
return &data.ModeData{
|
||||||
|
Name: filepath.Base(pd.RpmLocation),
|
||||||
Repo: repo,
|
Repo: repo,
|
||||||
Worktree: w,
|
Worktree: w,
|
||||||
RpmFile: createPackageFile(filepath.Base(pd.RpmLocation)),
|
|
||||||
FileWrites: nil,
|
FileWrites: nil,
|
||||||
Branches: sortedBranches,
|
Branches: sortedBranches,
|
||||||
}
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (g *GitMode) WriteSource(pd *data.ProcessData, md *data.ModeData) {
|
func (g *GitMode) WriteSource(pd *data.ProcessData, md *data.ModeData) error {
|
||||||
remote, err := md.Repo.Remote("upstream")
|
remote, err := md.Repo.Remote("upstream")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatalf("could not get upstream remote: %v", err)
|
return fmt.Errorf("could not get upstream remote: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
var refspec config.RefSpec
|
var refspec config.RefSpec
|
||||||
@ -174,7 +175,7 @@ func (g *GitMode) WriteSource(pd *data.ProcessData, md *data.ModeData) {
|
|||||||
refspec = config.RefSpec(fmt.Sprintf("+%s:%s", md.TagBranch, md.TagBranch))
|
refspec = config.RefSpec(fmt.Sprintf("+%s:%s", md.TagBranch, md.TagBranch))
|
||||||
branchName = strings.TrimPrefix(md.TagBranch, "refs/heads/")
|
branchName = strings.TrimPrefix(md.TagBranch, "refs/heads/")
|
||||||
} else {
|
} else {
|
||||||
match := tagImportRegex.FindStringSubmatch(md.TagBranch)
|
match := misc.GetTagImportRegex(pd.ImportBranchPrefix, pd.AllowStreamBranches).FindStringSubmatch(md.TagBranch)
|
||||||
branchName = match[2]
|
branchName = match[2]
|
||||||
refspec = config.RefSpec(fmt.Sprintf("+refs/heads/%s:%s", branchName, md.TagBranch))
|
refspec = config.RefSpec(fmt.Sprintf("+refs/heads/%s:%s", branchName, md.TagBranch))
|
||||||
}
|
}
|
||||||
@ -186,7 +187,7 @@ func (g *GitMode) WriteSource(pd *data.ProcessData, md *data.ModeData) {
|
|||||||
Force: true,
|
Force: true,
|
||||||
})
|
})
|
||||||
if err != nil && err != git.NoErrAlreadyUpToDate {
|
if err != nil && err != git.NoErrAlreadyUpToDate {
|
||||||
log.Fatalf("could not fetch upstream: %v", err)
|
return fmt.Errorf("could not fetch upstream: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
err = md.Worktree.Checkout(&git.CheckoutOptions{
|
err = md.Worktree.Checkout(&git.CheckoutOptions{
|
||||||
@ -194,23 +195,23 @@ func (g *GitMode) WriteSource(pd *data.ProcessData, md *data.ModeData) {
|
|||||||
Force: true,
|
Force: true,
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatalf("could not checkout source from git: %v", err)
|
return fmt.Errorf("could not checkout source from git: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
_, err = md.Worktree.Add(".")
|
_, err = md.Worktree.Add(".")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatalf("could not add Worktree: %v", err)
|
return fmt.Errorf("could not add Worktree: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
metadataFile, err := md.Worktree.Filesystem.Open(fmt.Sprintf(".%s.metadata", md.RpmFile.Name()))
|
metadataFile, err := md.Worktree.Filesystem.Open(fmt.Sprintf(".%s.metadata", md.Name))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Printf("warn: could not open metadata file, so skipping: %v", err)
|
log.Printf("warn: could not open metadata file, so skipping: %v", err)
|
||||||
return
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
fileBytes, err := ioutil.ReadAll(metadataFile)
|
fileBytes, err := ioutil.ReadAll(metadataFile)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatalf("could not read metadata file: %v", err)
|
return fmt.Errorf("could not read metadata file: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
client := &http.Client{
|
client := &http.Client{
|
||||||
@ -239,27 +240,27 @@ func (g *GitMode) WriteSource(pd *data.ProcessData, md *data.ModeData) {
|
|||||||
body = fromBlobStorage
|
body = fromBlobStorage
|
||||||
log.Printf("downloading %s from blob storage", hash)
|
log.Printf("downloading %s from blob storage", hash)
|
||||||
} else {
|
} else {
|
||||||
url := fmt.Sprintf("https://git.centos.org/sources/%s/%s/%s", md.RpmFile.Name(), branchName, hash)
|
url := fmt.Sprintf("https://git.centos.org/sources/%s/%s/%s", md.Name, branchName, hash)
|
||||||
log.Printf("downloading %s", url)
|
log.Printf("downloading %s", url)
|
||||||
|
|
||||||
req, err := http.NewRequest("GET", url, nil)
|
req, err := http.NewRequest("GET", url, nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatalf("could not create new http request: %v", err)
|
return fmt.Errorf("could not create new http request: %v", err)
|
||||||
}
|
}
|
||||||
req.Header.Set("Accept-Encoding", "*")
|
req.Header.Set("Accept-Encoding", "*")
|
||||||
|
|
||||||
resp, err := client.Do(req)
|
resp, err := client.Do(req)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatalf("could not download dist-git file: %v", err)
|
return fmt.Errorf("could not download dist-git file: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
body, err = ioutil.ReadAll(resp.Body)
|
body, err = ioutil.ReadAll(resp.Body)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatalf("could not read the whole dist-git file: %v", err)
|
return fmt.Errorf("could not read the whole dist-git file: %v", err)
|
||||||
}
|
}
|
||||||
err = resp.Body.Close()
|
err = resp.Body.Close()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatalf("could not close body handle: %v", err)
|
return fmt.Errorf("could not close body handle: %v", err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -268,7 +269,7 @@ func (g *GitMode) WriteSource(pd *data.ProcessData, md *data.ModeData) {
|
|||||||
|
|
||||||
f, err := md.Worktree.Filesystem.Create(path)
|
f, err := md.Worktree.Filesystem.Create(path)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatalf("could not open file pointer: %v", err)
|
return fmt.Errorf("could not open file pointer: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
hasher := data.CompareHash(body, hash)
|
hasher := data.CompareHash(body, hash)
|
||||||
@ -283,32 +284,36 @@ func (g *GitMode) WriteSource(pd *data.ProcessData, md *data.ModeData) {
|
|||||||
|
|
||||||
_, err = f.Write(body)
|
_, err = f.Write(body)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatalf("could not copy dist-git file to in-tree: %v", err)
|
return fmt.Errorf("could not copy dist-git file to in-tree: %v", err)
|
||||||
}
|
}
|
||||||
_ = f.Close()
|
_ = f.Close()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (g *GitMode) PostProcess(md *data.ModeData) {
|
func (g *GitMode) PostProcess(md *data.ModeData) error {
|
||||||
for _, source := range md.SourcesToIgnore {
|
for _, source := range md.SourcesToIgnore {
|
||||||
_, err := md.Worktree.Filesystem.Stat(source.Name)
|
_, err := md.Worktree.Filesystem.Stat(source.Name)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
err := md.Worktree.Filesystem.Remove(source.Name)
|
err := md.Worktree.Filesystem.Remove(source.Name)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatalf("could not remove dist-git file: %v", err)
|
return fmt.Errorf("could not remove dist-git file: %v", err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
_, err := md.Worktree.Add(".")
|
_, err := md.Worktree.Add(".")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatalf("could not add git sources: %v", err)
|
return fmt.Errorf("could not add git sources: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (g *GitMode) ImportName(_ *data.ProcessData, md *data.ModeData) string {
|
func (g *GitMode) ImportName(pd *data.ProcessData, md *data.ModeData) string {
|
||||||
if tagImportRegex.MatchString(md.TagBranch) {
|
if misc.GetTagImportRegex(pd.ImportBranchPrefix, pd.AllowStreamBranches).MatchString(md.TagBranch) {
|
||||||
match := tagImportRegex.FindStringSubmatch(md.TagBranch)
|
match := misc.GetTagImportRegex(pd.ImportBranchPrefix, pd.AllowStreamBranches).FindStringSubmatch(md.TagBranch)
|
||||||
return match[3]
|
return match[3]
|
||||||
}
|
}
|
||||||
|
|
@ -1,51 +0,0 @@
|
|||||||
// Copyright (c) 2021 The Srpmproc Authors
|
|
||||||
//
|
|
||||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
||||||
// of this software and associated documentation files (the "Software"), to deal
|
|
||||||
// in the Software without restriction, including without limitation the rights
|
|
||||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
||||||
// copies of the Software, and to permit persons to whom the Software is
|
|
||||||
// furnished to do so, subject to the following conditions:
|
|
||||||
//
|
|
||||||
// The above copyright notice and this permission notice shall be included in all
|
|
||||||
// copies or substantial portions of the Software.
|
|
||||||
//
|
|
||||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
||||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
||||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
||||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
||||||
// SOFTWARE.
|
|
||||||
|
|
||||||
package srpmproc
|
|
||||||
|
|
||||||
import (
|
|
||||||
"github.com/cavaliercoder/go-rpm"
|
|
||||||
)
|
|
||||||
|
|
||||||
// TODO: ugly hack, should create an interface
|
|
||||||
// since GitMode does not parse an RPM file, we just mimick
|
|
||||||
// the headers of an actual file to reuse RpmFile.Name()
|
|
||||||
func createPackageFile(name string) *rpm.PackageFile {
|
|
||||||
return &rpm.PackageFile{
|
|
||||||
Lead: rpm.Lead{},
|
|
||||||
Headers: []rpm.Header{
|
|
||||||
{},
|
|
||||||
{
|
|
||||||
Version: 0,
|
|
||||||
IndexCount: 1,
|
|
||||||
Length: 1,
|
|
||||||
Indexes: []rpm.IndexEntry{
|
|
||||||
{
|
|
||||||
Tag: 1000,
|
|
||||||
Type: rpm.IndexDataTypeStringArray,
|
|
||||||
Offset: 0,
|
|
||||||
ItemCount: 1,
|
|
||||||
Value: []string{name},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,21 +0,0 @@
|
|||||||
// Copyright (c) 2021 The Srpmproc Authors
|
|
||||||
//
|
|
||||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
||||||
// of this software and associated documentation files (the "Software"), to deal
|
|
||||||
// in the Software without restriction, including without limitation the rights
|
|
||||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
||||||
// copies of the Software, and to permit persons to whom the Software is
|
|
||||||
// furnished to do so, subject to the following conditions:
|
|
||||||
//
|
|
||||||
// The above copyright notice and this permission notice shall be included in all
|
|
||||||
// copies or substantial portions of the Software.
|
|
||||||
//
|
|
||||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
||||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
||||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
||||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
||||||
// SOFTWARE.
|
|
||||||
|
|
||||||
package srpmproc
|
|
@ -40,14 +40,14 @@ import (
|
|||||||
"google.golang.org/protobuf/encoding/prototext"
|
"google.golang.org/protobuf/encoding/prototext"
|
||||||
)
|
)
|
||||||
|
|
||||||
func cfgPatches(pd *data.ProcessData, md *data.ModeData, patchTree *git.Worktree, pushTree *git.Worktree) {
|
func cfgPatches(pd *data.ProcessData, md *data.ModeData, patchTree *git.Worktree, pushTree *git.Worktree) error {
|
||||||
// check CFG patches
|
// check CFG patches
|
||||||
_, err := patchTree.Filesystem.Stat("ROCKY/CFG")
|
_, err := patchTree.Filesystem.Stat("ROCKY/CFG")
|
||||||
if err == nil {
|
if err == nil {
|
||||||
// iterate through patches
|
// iterate through patches
|
||||||
infos, err := patchTree.Filesystem.ReadDir("ROCKY/CFG")
|
infos, err := patchTree.Filesystem.ReadDir("ROCKY/CFG")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatalf("could not walk patches: %v", err)
|
return fmt.Errorf("could not walk patches: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, info := range infos {
|
for _, info := range infos {
|
||||||
@ -60,44 +60,51 @@ func cfgPatches(pd *data.ProcessData, md *data.ModeData, patchTree *git.Worktree
|
|||||||
filePath := filepath.Join("ROCKY/CFG", info.Name())
|
filePath := filepath.Join("ROCKY/CFG", info.Name())
|
||||||
directive, err := patchTree.Filesystem.Open(filePath)
|
directive, err := patchTree.Filesystem.Open(filePath)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatalf("could not open directive file %s: %v", info.Name(), err)
|
return fmt.Errorf("could not open directive file %s: %v", info.Name(), err)
|
||||||
}
|
}
|
||||||
directiveBytes, err := ioutil.ReadAll(directive)
|
directiveBytes, err := ioutil.ReadAll(directive)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatalf("could not read directive file: %v", err)
|
return fmt.Errorf("could not read directive file: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
var cfg srpmprocpb.Cfg
|
var cfg srpmprocpb.Cfg
|
||||||
err = prototext.Unmarshal(directiveBytes, &cfg)
|
err = prototext.Unmarshal(directiveBytes, &cfg)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatalf("could not unmarshal cfg file: %v", err)
|
return fmt.Errorf("could not unmarshal cfg file: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
directives.Apply(&cfg, pd, md, patchTree, pushTree)
|
directives.Apply(&cfg, pd, md, patchTree, pushTree)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func applyPatches(pd *data.ProcessData, md *data.ModeData, patchTree *git.Worktree, pushTree *git.Worktree) {
|
func applyPatches(pd *data.ProcessData, md *data.ModeData, patchTree *git.Worktree, pushTree *git.Worktree) error {
|
||||||
// check if patches exist
|
// check if patches exist
|
||||||
_, err := patchTree.Filesystem.Stat("ROCKY")
|
_, err := patchTree.Filesystem.Stat("ROCKY")
|
||||||
if err == nil {
|
if err == nil {
|
||||||
cfgPatches(pd, md, patchTree, pushTree)
|
err := cfgPatches(pd, md, patchTree, pushTree)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func executePatchesRpm(pd *data.ProcessData, md *data.ModeData) {
|
func executePatchesRpm(pd *data.ProcessData, md *data.ModeData) error {
|
||||||
// fetch patch repository
|
// fetch patch repository
|
||||||
repo, err := git.Init(memory.NewStorage(), memfs.New())
|
repo, err := git.Init(memory.NewStorage(), memfs.New())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatalf("could not create new dist Repo: %v", err)
|
return fmt.Errorf("could not create new dist Repo: %v", err)
|
||||||
}
|
}
|
||||||
w, err := repo.Worktree()
|
w, err := repo.Worktree()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatalf("could not get dist Worktree: %v", err)
|
return fmt.Errorf("could not get dist Worktree: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
remoteUrl := fmt.Sprintf("%s/patch/%s.git", pd.UpstreamPrefix, gitlabify(md.RpmFile.Name()))
|
remoteUrl := fmt.Sprintf("%s/patch/%s.git", pd.UpstreamPrefix, gitlabify(md.Name))
|
||||||
refspec := config.RefSpec(fmt.Sprintf("+refs/heads/*:refs/remotes/origin/*"))
|
refspec := config.RefSpec(fmt.Sprintf("+refs/heads/*:refs/remotes/origin/*"))
|
||||||
|
|
||||||
_, err = repo.CreateRemote(&config.RemoteConfig{
|
_, err = repo.CreateRemote(&config.RemoteConfig{
|
||||||
@ -106,7 +113,7 @@ func executePatchesRpm(pd *data.ProcessData, md *data.ModeData) {
|
|||||||
Fetch: []config.RefSpec{refspec},
|
Fetch: []config.RefSpec{refspec},
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatalf("could not create remote: %v", err)
|
return fmt.Errorf("could not create remote: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
fetchOptions := &git.FetchOptions{
|
fetchOptions := &git.FetchOptions{
|
||||||
@ -124,7 +131,7 @@ func executePatchesRpm(pd *data.ProcessData, md *data.ModeData) {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
// no patches active
|
// no patches active
|
||||||
log.Println("info: patch repo not found")
|
log.Println("info: patch repo not found")
|
||||||
return
|
return nil
|
||||||
} else {
|
} else {
|
||||||
err = w.Checkout(&git.CheckoutOptions{
|
err = w.Checkout(&git.CheckoutOptions{
|
||||||
Branch: plumbing.NewRemoteReferenceName("origin", "main"),
|
Branch: plumbing.NewRemoteReferenceName("origin", "main"),
|
||||||
@ -132,7 +139,10 @@ func executePatchesRpm(pd *data.ProcessData, md *data.ModeData) {
|
|||||||
})
|
})
|
||||||
// common patches found, apply them
|
// common patches found, apply them
|
||||||
if err == nil {
|
if err == nil {
|
||||||
applyPatches(pd, md, w, md.Worktree)
|
err := applyPatches(pd, md, w, md.Worktree)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
log.Println("info: no common patches found")
|
log.Println("info: no common patches found")
|
||||||
}
|
}
|
||||||
@ -143,17 +153,22 @@ func executePatchesRpm(pd *data.ProcessData, md *data.ModeData) {
|
|||||||
})
|
})
|
||||||
// branch specific patches found, apply them
|
// branch specific patches found, apply them
|
||||||
if err == nil {
|
if err == nil {
|
||||||
applyPatches(pd, md, w, md.Worktree)
|
err := applyPatches(pd, md, w, md.Worktree)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
log.Println("info: no branch specific patches found")
|
log.Println("info: no branch specific patches found")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func getTipStream(pd *data.ProcessData, module string, pushBranch string, origPushBranch string, tries int) string {
|
func getTipStream(pd *data.ProcessData, module string, pushBranch string, origPushBranch string, tries int) (string, error) {
|
||||||
repo, err := git.Init(memory.NewStorage(), memfs.New())
|
repo, err := git.Init(memory.NewStorage(), memfs.New())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatalf("could not init git Repo: %v", err)
|
return "", fmt.Errorf("could not init git Repo: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
remoteUrl := fmt.Sprintf("%s/rpms/%s.git", pd.UpstreamPrefix, gitlabify(module))
|
remoteUrl := fmt.Sprintf("%s/rpms/%s.git", pd.UpstreamPrefix, gitlabify(module))
|
||||||
@ -164,7 +179,7 @@ func getTipStream(pd *data.ProcessData, module string, pushBranch string, origPu
|
|||||||
Fetch: []config.RefSpec{refspec},
|
Fetch: []config.RefSpec{refspec},
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatalf("could not create remote: %v", err)
|
return "", fmt.Errorf("could not create remote: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
list, err := remote.List(&git.ListOptions{
|
list, err := remote.List(&git.ListOptions{
|
||||||
@ -178,7 +193,7 @@ func getTipStream(pd *data.ProcessData, module string, pushBranch string, origPu
|
|||||||
return getTipStream(pd, module, pushBranch, origPushBranch, tries+1)
|
return getTipStream(pd, module, pushBranch, origPushBranch, tries+1)
|
||||||
}
|
}
|
||||||
|
|
||||||
log.Fatalf("could not get rpm refs. import the rpm before the module: %v", err)
|
return "", fmt.Errorf("could not get rpm refs. import the rpm before the module: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
var tipHash string
|
var tipHash string
|
||||||
@ -238,14 +253,14 @@ func getTipStream(pd *data.ProcessData, module string, pushBranch string, origPu
|
|||||||
log.Fatal("could not find tip hash")
|
log.Fatal("could not find tip hash")
|
||||||
}
|
}
|
||||||
|
|
||||||
return strings.TrimSpace(tipHash)
|
return strings.TrimSpace(tipHash), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func patchModuleYaml(pd *data.ProcessData, md *data.ModeData) {
|
func patchModuleYaml(pd *data.ProcessData, md *data.ModeData) error {
|
||||||
// special case for platform.yaml
|
// special case for platform.yaml
|
||||||
_, err := md.Worktree.Filesystem.Open("platform.yaml")
|
_, err := md.Worktree.Filesystem.Open("platform.yaml")
|
||||||
if err == nil {
|
if err == nil {
|
||||||
return
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
mdTxtPath := "SOURCES/modulemd.src.txt"
|
mdTxtPath := "SOURCES/modulemd.src.txt"
|
||||||
@ -254,18 +269,18 @@ func patchModuleYaml(pd *data.ProcessData, md *data.ModeData) {
|
|||||||
mdTxtPath = "SOURCES/modulemd.txt"
|
mdTxtPath = "SOURCES/modulemd.txt"
|
||||||
f, err = md.Worktree.Filesystem.Open(mdTxtPath)
|
f, err = md.Worktree.Filesystem.Open(mdTxtPath)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatalf("could not open modulemd file: %v", err)
|
return fmt.Errorf("could not open modulemd file: %v", err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
content, err := ioutil.ReadAll(f)
|
content, err := ioutil.ReadAll(f)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatalf("could not read modulemd file: %v", err)
|
return fmt.Errorf("could not read modulemd file: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
module, err := modulemd.Parse(content)
|
module, err := modulemd.Parse(content)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatalf("could not parse modulemd file: %v", err)
|
return fmt.Errorf("could not parse modulemd file: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get stream branch from tag
|
// Get stream branch from tag
|
||||||
@ -311,23 +326,31 @@ func patchModuleYaml(pd *data.ProcessData, md *data.ModeData) {
|
|||||||
log.Fatal("could not recognize modulemd ref")
|
log.Fatal("could not recognize modulemd ref")
|
||||||
}
|
}
|
||||||
|
|
||||||
tipHash = getTipStream(pd, name, pushBranch, md.PushBranch, 0)
|
tipHash, err = getTipStream(pd, name, pushBranch, md.PushBranch, 0)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
if tipHash == "0000000000000000000000000000000000000000" {
|
if tipHash == "0000000000000000000000000000000000000000" {
|
||||||
pushBranch = defaultBranch
|
pushBranch = defaultBranch
|
||||||
tipHash = getTipStream(pd, name, pushBranch, md.PushBranch, 0)
|
tipHash, err = getTipStream(pd, name, pushBranch, md.PushBranch, 0)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
rpm.Ref = tipHash
|
rpm.Ref = tipHash
|
||||||
}
|
}
|
||||||
|
|
||||||
rootModule := fmt.Sprintf("%s.yaml", md.RpmFile.Name())
|
rootModule := fmt.Sprintf("%s.yaml", md.Name)
|
||||||
err = module.Marshal(md.Worktree.Filesystem, rootModule)
|
err = module.Marshal(md.Worktree.Filesystem, rootModule)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatalf("could not marshal root modulemd: %v", err)
|
return fmt.Errorf("could not marshal root modulemd: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
_, err = md.Worktree.Add(rootModule)
|
_, err = md.Worktree.Add(rootModule)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatalf("could not add root modulemd: %v", err)
|
return fmt.Errorf("could not add root modulemd: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
|
@ -24,9 +24,17 @@ import (
|
|||||||
"encoding/hex"
|
"encoding/hex"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"github.com/go-git/go-billy/v5"
|
||||||
|
"github.com/go-git/go-git/v5/plumbing/transport/ssh"
|
||||||
|
"github.com/rocky-linux/srpmproc/pkg/blob"
|
||||||
|
"github.com/rocky-linux/srpmproc/pkg/blob/file"
|
||||||
|
"github.com/rocky-linux/srpmproc/pkg/blob/gcs"
|
||||||
|
"github.com/rocky-linux/srpmproc/pkg/blob/s3"
|
||||||
|
"github.com/rocky-linux/srpmproc/pkg/modes"
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
"log"
|
"log"
|
||||||
"os"
|
"os"
|
||||||
|
"os/user"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"regexp"
|
"regexp"
|
||||||
"strings"
|
"strings"
|
||||||
@ -41,8 +49,44 @@ import (
|
|||||||
"github.com/rocky-linux/srpmproc/pkg/data"
|
"github.com/rocky-linux/srpmproc/pkg/data"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
RpmPrefixCentOS = "https://git.centos.org/rpms"
|
||||||
|
ModulePrefixCentOS = "https://git.centos.org/modules"
|
||||||
|
RpmPrefixRocky = "https://git.rockylinux.org/staging/rpms"
|
||||||
|
ModulePrefixRocky = "https://git.rockylinux.org/staging/modules"
|
||||||
|
UpstreamPrefixRocky = "https://git.rockylinux.org/staging"
|
||||||
|
)
|
||||||
|
|
||||||
var tagImportRegex *regexp.Regexp
|
var tagImportRegex *regexp.Regexp
|
||||||
|
|
||||||
|
type ProcessDataRequest struct {
|
||||||
|
// Required
|
||||||
|
Version int
|
||||||
|
StorageAddr string
|
||||||
|
Package string
|
||||||
|
|
||||||
|
// Optional
|
||||||
|
ModuleMode bool
|
||||||
|
TmpFsMode string
|
||||||
|
ModulePrefix string
|
||||||
|
RpmPrefix string
|
||||||
|
SshKeyLocation string
|
||||||
|
SshUser string
|
||||||
|
ManualCommits string
|
||||||
|
UpstreamPrefix string
|
||||||
|
GitCommitterName string
|
||||||
|
GitCommitterEmail string
|
||||||
|
ImportBranchPrefix string
|
||||||
|
BranchPrefix string
|
||||||
|
FsCreator data.FsCreatorFunc
|
||||||
|
NoDupMode bool
|
||||||
|
AllowStreamBranches bool
|
||||||
|
ModuleFallbackStream string
|
||||||
|
NoStorageUpload bool
|
||||||
|
NoStorageDownload bool
|
||||||
|
SingleTag string
|
||||||
|
}
|
||||||
|
|
||||||
func gitlabify(str string) string {
|
func gitlabify(str string) string {
|
||||||
if str == "tree" {
|
if str == "tree" {
|
||||||
return "treepkg"
|
return "treepkg"
|
||||||
@ -51,6 +95,144 @@ func gitlabify(str string) string {
|
|||||||
return strings.Replace(str, "+", "plus", -1)
|
return strings.Replace(str, "+", "plus", -1)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func NewProcessData(req *ProcessDataRequest) (*data.ProcessData, error) {
|
||||||
|
switch req.Version {
|
||||||
|
case 8:
|
||||||
|
break
|
||||||
|
default:
|
||||||
|
return nil, fmt.Errorf("unsupported upstream version %d", req.Version)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set defaults
|
||||||
|
if req.ModulePrefix == "" {
|
||||||
|
req.ModulePrefix = ModulePrefixCentOS
|
||||||
|
}
|
||||||
|
if req.RpmPrefix == "" {
|
||||||
|
req.RpmPrefix = RpmPrefixCentOS
|
||||||
|
}
|
||||||
|
if req.SshUser == "" {
|
||||||
|
req.SshUser = "git"
|
||||||
|
}
|
||||||
|
if req.UpstreamPrefix == "" {
|
||||||
|
req.UpstreamPrefix = UpstreamPrefixRocky
|
||||||
|
}
|
||||||
|
if req.GitCommitterName == "" {
|
||||||
|
req.GitCommitterName = "rockyautomation"
|
||||||
|
}
|
||||||
|
if req.GitCommitterEmail == "" {
|
||||||
|
req.GitCommitterEmail = "rockyautomation@rockylinux.org"
|
||||||
|
}
|
||||||
|
if req.ImportBranchPrefix == "" {
|
||||||
|
req.ImportBranchPrefix = "c"
|
||||||
|
}
|
||||||
|
if req.BranchPrefix == "" {
|
||||||
|
req.BranchPrefix = "r"
|
||||||
|
}
|
||||||
|
|
||||||
|
// Validate required
|
||||||
|
if req.Package == "" {
|
||||||
|
return nil, fmt.Errorf("package cannot be empty")
|
||||||
|
}
|
||||||
|
|
||||||
|
var importer data.ImportMode
|
||||||
|
var blobStorage blob.Storage
|
||||||
|
|
||||||
|
if strings.HasPrefix(req.StorageAddr, "gs://") {
|
||||||
|
blobStorage = gcs.New(strings.Replace(req.StorageAddr, "gs://", "", 1))
|
||||||
|
} else if strings.HasPrefix(req.StorageAddr, "s3://") {
|
||||||
|
blobStorage = s3.New(strings.Replace(req.StorageAddr, "s3://", "", 1))
|
||||||
|
} else if strings.HasPrefix(req.StorageAddr, "file://") {
|
||||||
|
blobStorage = file.New(strings.Replace(req.StorageAddr, "file://", "", 1))
|
||||||
|
} else {
|
||||||
|
log.Fatalf("invalid blob storage")
|
||||||
|
}
|
||||||
|
|
||||||
|
sourceRpmLocation := ""
|
||||||
|
if req.ModuleMode {
|
||||||
|
sourceRpmLocation = fmt.Sprintf("%s/%s", req.ModulePrefix, req.Package)
|
||||||
|
} else {
|
||||||
|
sourceRpmLocation = fmt.Sprintf("%s/%s", req.RpmPrefix, req.Package)
|
||||||
|
}
|
||||||
|
importer = &modes.GitMode{}
|
||||||
|
|
||||||
|
lastKeyLocation := req.SshKeyLocation
|
||||||
|
if lastKeyLocation == "" {
|
||||||
|
usr, err := user.Current()
|
||||||
|
if err != nil {
|
||||||
|
log.Fatalf("could not get user: %v", err)
|
||||||
|
}
|
||||||
|
lastKeyLocation = filepath.Join(usr.HomeDir, ".ssh/id_rsa")
|
||||||
|
}
|
||||||
|
|
||||||
|
var authenticator *ssh.PublicKeys
|
||||||
|
|
||||||
|
var err error
|
||||||
|
// create ssh key authenticator
|
||||||
|
authenticator, err = ssh.NewPublicKeysFromFile(req.SshUser, lastKeyLocation, "")
|
||||||
|
if err != nil {
|
||||||
|
log.Fatalf("could not get git authenticator: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
fsCreator := func(branch string) (billy.Filesystem, error) {
|
||||||
|
return memfs.New(), nil
|
||||||
|
}
|
||||||
|
if req.FsCreator != nil {
|
||||||
|
fsCreator = req.FsCreator
|
||||||
|
}
|
||||||
|
|
||||||
|
if req.TmpFsMode != "" {
|
||||||
|
log.Printf("using tmpfs dir: %s", req.TmpFsMode)
|
||||||
|
fsCreator = func(branch string) (billy.Filesystem, error) {
|
||||||
|
fs, err := fsCreator(branch)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
tmpDir := filepath.Join(req.TmpFsMode, branch)
|
||||||
|
err = fs.MkdirAll(tmpDir, 0755)
|
||||||
|
if err != nil {
|
||||||
|
log.Fatalf("could not create tmpfs dir: %v", err)
|
||||||
|
}
|
||||||
|
nFs, err := fs.Chroot(tmpDir)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return nFs, nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var manualCs []string
|
||||||
|
if strings.TrimSpace(req.ManualCommits) != "" {
|
||||||
|
manualCs = strings.Split(req.ManualCommits, ",")
|
||||||
|
}
|
||||||
|
|
||||||
|
return &data.ProcessData{
|
||||||
|
Importer: importer,
|
||||||
|
RpmLocation: sourceRpmLocation,
|
||||||
|
UpstreamPrefix: req.UpstreamPrefix,
|
||||||
|
SshKeyLocation: lastKeyLocation,
|
||||||
|
SshUser: req.SshUser,
|
||||||
|
Version: req.Version,
|
||||||
|
BlobStorage: blobStorage,
|
||||||
|
GitCommitterName: req.GitCommitterName,
|
||||||
|
GitCommitterEmail: req.GitCommitterEmail,
|
||||||
|
ModulePrefix: req.ModulePrefix,
|
||||||
|
ImportBranchPrefix: req.ImportBranchPrefix,
|
||||||
|
BranchPrefix: req.BranchPrefix,
|
||||||
|
SingleTag: req.SingleTag,
|
||||||
|
Authenticator: authenticator,
|
||||||
|
NoDupMode: req.NoDupMode,
|
||||||
|
ModuleMode: req.ModuleMode,
|
||||||
|
TmpFsMode: req.TmpFsMode,
|
||||||
|
NoStorageDownload: req.NoStorageDownload,
|
||||||
|
NoStorageUpload: req.NoStorageUpload,
|
||||||
|
ManualCommits: manualCs,
|
||||||
|
ModuleFallbackStream: req.ModuleFallbackStream,
|
||||||
|
AllowStreamBranches: req.AllowStreamBranches,
|
||||||
|
FsCreator: fsCreator,
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
|
||||||
// ProcessRPM checks the RPM specs and discards any remote files
|
// ProcessRPM checks the RPM specs and discards any remote files
|
||||||
// This functions also sorts files into directories
|
// This functions also sorts files into directories
|
||||||
// .spec files goes into -> SPECS
|
// .spec files goes into -> SPECS
|
||||||
@ -58,14 +240,11 @@ func gitlabify(str string) string {
|
|||||||
// source files goes into -> SOURCES
|
// source files goes into -> SOURCES
|
||||||
// all files that are remote goes into .gitignore
|
// all files that are remote goes into .gitignore
|
||||||
// all ignored files' hash goes into .{Name}.metadata
|
// all ignored files' hash goes into .{Name}.metadata
|
||||||
func ProcessRPM(pd *data.ProcessData) {
|
func ProcessRPM(pd *data.ProcessData) error {
|
||||||
if pd.AllowStreamBranches {
|
md, err := pd.Importer.RetrieveSource(pd)
|
||||||
tagImportRegex = regexp.MustCompile(fmt.Sprintf("refs/tags/(imports/(%s(?:.s|.)|%s(?:|s).+)/(.*))", pd.ImportBranchPrefix, pd.ImportBranchPrefix))
|
if err != nil {
|
||||||
} else {
|
return err
|
||||||
tagImportRegex = regexp.MustCompile(fmt.Sprintf("refs/tags/(imports/(%s.|%s.-.+)/(.*))", pd.ImportBranchPrefix, pd.ImportBranchPrefix))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
md := pd.Importer.RetrieveSource(pd)
|
|
||||||
md.BlobCache = map[string][]byte{}
|
md.BlobCache = map[string][]byte{}
|
||||||
|
|
||||||
remotePrefix := "rpms"
|
remotePrefix := "rpms"
|
||||||
@ -83,9 +262,9 @@ func ProcessRPM(pd *data.ProcessData) {
|
|||||||
if pd.NoDupMode {
|
if pd.NoDupMode {
|
||||||
repo, err := git.Init(memory.NewStorage(), memfs.New())
|
repo, err := git.Init(memory.NewStorage(), memfs.New())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatalf("could not init git repo: %v", err)
|
return fmt.Errorf("could not init git repo: %v", err)
|
||||||
}
|
}
|
||||||
remoteUrl := fmt.Sprintf("%s/%s/%s.git", pd.UpstreamPrefix, remotePrefix, gitlabify(md.RpmFile.Name()))
|
remoteUrl := fmt.Sprintf("%s/%s/%s.git", pd.UpstreamPrefix, remotePrefix, gitlabify(md.Name))
|
||||||
refspec := config.RefSpec("+refs/heads/*:refs/remotes/origin/*")
|
refspec := config.RefSpec("+refs/heads/*:refs/remotes/origin/*")
|
||||||
|
|
||||||
remote, err := repo.CreateRemote(&config.RemoteConfig{
|
remote, err := repo.CreateRemote(&config.RemoteConfig{
|
||||||
@ -94,7 +273,7 @@ func ProcessRPM(pd *data.ProcessData) {
|
|||||||
Fetch: []config.RefSpec{refspec},
|
Fetch: []config.RefSpec{refspec},
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatalf("could not create remote: %v", err)
|
return fmt.Errorf("could not create remote: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
list, err := remote.List(&git.ListOptions{
|
list, err := remote.List(&git.ListOptions{
|
||||||
@ -127,7 +306,7 @@ func ProcessRPM(pd *data.ProcessData) {
|
|||||||
log.Fatalln("invalid manual commit list")
|
log.Fatalln("invalid manual commit list")
|
||||||
}
|
}
|
||||||
|
|
||||||
head := fmt.Sprintf("refs/tags/imports/%s/%s-%s", branchCommit[0], md.RpmFile.Name(), branchCommit[1])
|
head := fmt.Sprintf("refs/tags/imports/%s/%s-%s", branchCommit[0], md.Name, branchCommit[1])
|
||||||
md.Branches = append(md.Branches, head)
|
md.Branches = append(md.Branches, head)
|
||||||
commitPin[head] = branchCommit[1]
|
commitPin[head] = branchCommit[1]
|
||||||
}
|
}
|
||||||
@ -167,15 +346,19 @@ func ProcessRPM(pd *data.ProcessData) {
|
|||||||
newTag := "imports/" + pd.BranchPrefix + strings.TrimPrefix(match[1], "imports/"+pd.ImportBranchPrefix)
|
newTag := "imports/" + pd.BranchPrefix + strings.TrimPrefix(match[1], "imports/"+pd.ImportBranchPrefix)
|
||||||
newTag = strings.Replace(newTag, "%", "_", -1)
|
newTag = strings.Replace(newTag, "%", "_", -1)
|
||||||
|
|
||||||
rpmFile := md.RpmFile
|
createdFs, err := pd.FsCreator(md.PushBranch)
|
||||||
// create new Repo for final dist
|
|
||||||
repo, err := git.Init(memory.NewStorage(), pd.FsCreator(md.PushBranch))
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatalf("could not create new dist Repo: %v", err)
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
// create new Repo for final dist
|
||||||
|
repo, err := git.Init(memory.NewStorage(), createdFs)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("could not create new dist Repo: %v", err)
|
||||||
}
|
}
|
||||||
w, err := repo.Worktree()
|
w, err := repo.Worktree()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatalf("could not get dist Worktree: %v", err)
|
return fmt.Errorf("could not get dist Worktree: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
shouldContinue := true
|
shouldContinue := true
|
||||||
@ -190,7 +373,7 @@ func ProcessRPM(pd *data.ProcessData) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// create a new remote
|
// create a new remote
|
||||||
remoteUrl := fmt.Sprintf("%s/%s/%s.git", pd.UpstreamPrefix, remotePrefix, gitlabify(rpmFile.Name()))
|
remoteUrl := fmt.Sprintf("%s/%s/%s.git", pd.UpstreamPrefix, remotePrefix, gitlabify(md.Name))
|
||||||
log.Printf("using remote: %s", remoteUrl)
|
log.Printf("using remote: %s", remoteUrl)
|
||||||
refspec := config.RefSpec(fmt.Sprintf("+refs/heads/%s:refs/remotes/origin/%s", md.PushBranch, md.PushBranch))
|
refspec := config.RefSpec(fmt.Sprintf("+refs/heads/%s:refs/remotes/origin/%s", md.PushBranch, md.PushBranch))
|
||||||
log.Printf("using refspec: %s", refspec)
|
log.Printf("using refspec: %s", refspec)
|
||||||
@ -201,7 +384,7 @@ func ProcessRPM(pd *data.ProcessData) {
|
|||||||
Fetch: []config.RefSpec{refspec},
|
Fetch: []config.RefSpec{refspec},
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatalf("could not create remote: %v", err)
|
return fmt.Errorf("could not create remote: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
err = repo.Fetch(&git.FetchOptions{
|
err = repo.Fetch(&git.FetchOptions{
|
||||||
@ -221,7 +404,7 @@ func ProcessRPM(pd *data.ProcessData) {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
h := plumbing.NewSymbolicReference(plumbing.HEAD, refName)
|
h := plumbing.NewSymbolicReference(plumbing.HEAD, refName)
|
||||||
if err := repo.Storer.CheckAndSetReference(h, nil); err != nil {
|
if err := repo.Storer.CheckAndSetReference(h, nil); err != nil {
|
||||||
log.Fatalf("could not set reference: %v", err)
|
return fmt.Errorf("could not set reference: %v", err)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
err = w.Checkout(&git.CheckoutOptions{
|
err = w.Checkout(&git.CheckoutOptions{
|
||||||
@ -230,27 +413,36 @@ func ProcessRPM(pd *data.ProcessData) {
|
|||||||
Force: true,
|
Force: true,
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatalf("could not checkout: %v", err)
|
return fmt.Errorf("could not checkout: %v", err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pd.Importer.WriteSource(pd, md)
|
err = pd.Importer.WriteSource(pd, md)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
data.CopyFromFs(md.Worktree.Filesystem, w.Filesystem, ".")
|
data.CopyFromFs(md.Worktree.Filesystem, w.Filesystem, ".")
|
||||||
md.Repo = repo
|
md.Repo = repo
|
||||||
md.Worktree = w
|
md.Worktree = w
|
||||||
|
|
||||||
if pd.ModuleMode {
|
if pd.ModuleMode {
|
||||||
patchModuleYaml(pd, md)
|
err := patchModuleYaml(pd, md)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
executePatchesRpm(pd, md)
|
err := executePatchesRpm(pd, md)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// get ignored files hash and add to .{Name}.metadata
|
// get ignored files hash and add to .{Name}.metadata
|
||||||
metadataFile := fmt.Sprintf(".%s.metadata", rpmFile.Name())
|
metadataFile := fmt.Sprintf(".%s.metadata", md.Name)
|
||||||
metadata, err := w.Filesystem.Create(metadataFile)
|
metadata, err := w.Filesystem.Create(metadataFile)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatalf("could not create metadata file: %v", err)
|
return fmt.Errorf("could not create metadata file: %v", err)
|
||||||
}
|
}
|
||||||
for _, source := range md.SourcesToIgnore {
|
for _, source := range md.SourcesToIgnore {
|
||||||
sourcePath := source.Name
|
sourcePath := source.Name
|
||||||
@ -262,23 +454,23 @@ func ProcessRPM(pd *data.ProcessData) {
|
|||||||
|
|
||||||
sourceFile, err := w.Filesystem.Open(sourcePath)
|
sourceFile, err := w.Filesystem.Open(sourcePath)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatalf("could not open ignored source file %s: %v", sourcePath, err)
|
return fmt.Errorf("could not open ignored source file %s: %v", sourcePath, err)
|
||||||
}
|
}
|
||||||
sourceFileBts, err := ioutil.ReadAll(sourceFile)
|
sourceFileBts, err := ioutil.ReadAll(sourceFile)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatalf("could not read the whole of ignored source file: %v", err)
|
return fmt.Errorf("could not read the whole of ignored source file: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
source.HashFunction.Reset()
|
source.HashFunction.Reset()
|
||||||
_, err = source.HashFunction.Write(sourceFileBts)
|
_, err = source.HashFunction.Write(sourceFileBts)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatalf("could not write bytes to hash function: %v", err)
|
return fmt.Errorf("could not write bytes to hash function: %v", err)
|
||||||
}
|
}
|
||||||
checksum := hex.EncodeToString(source.HashFunction.Sum(nil))
|
checksum := hex.EncodeToString(source.HashFunction.Sum(nil))
|
||||||
checksumLine := fmt.Sprintf("%s %s\n", checksum, sourcePath)
|
checksumLine := fmt.Sprintf("%s %s\n", checksum, sourcePath)
|
||||||
_, err = metadata.Write([]byte(checksumLine))
|
_, err = metadata.Write([]byte(checksumLine))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatalf("could not write to metadata file: %v", err)
|
return fmt.Errorf("could not write to metadata file: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
if data.StrContains(alreadyUploadedBlobs, checksum) {
|
if data.StrContains(alreadyUploadedBlobs, checksum) {
|
||||||
@ -293,7 +485,7 @@ func ProcessRPM(pd *data.ProcessData) {
|
|||||||
|
|
||||||
_, err = w.Add(metadataFile)
|
_, err = w.Add(metadataFile)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatalf("could not add metadata file: %v", err)
|
return fmt.Errorf("could not add metadata file: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
lastFilesToAdd := []string{".gitignore", "SPECS"}
|
lastFilesToAdd := []string{".gitignore", "SPECS"}
|
||||||
@ -302,7 +494,7 @@ func ProcessRPM(pd *data.ProcessData) {
|
|||||||
if err == nil {
|
if err == nil {
|
||||||
_, err := w.Add(f)
|
_, err := w.Add(f)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatalf("could not add %s: %v", f, err)
|
return fmt.Errorf("could not add %s: %v", f, err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -311,7 +503,10 @@ func ProcessRPM(pd *data.ProcessData) {
|
|||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
pd.Importer.PostProcess(md)
|
err = pd.Importer.PostProcess(md)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
// show status
|
// show status
|
||||||
status, _ := w.Status()
|
status, _ := w.Status()
|
||||||
@ -324,7 +519,7 @@ func ProcessRPM(pd *data.ProcessData) {
|
|||||||
path := strings.TrimPrefix(trimmed, "D ")
|
path := strings.TrimPrefix(trimmed, "D ")
|
||||||
_, err := w.Remove(path)
|
_, err := w.Remove(path)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatalf("could not delete extra file %s: %v", path, err)
|
return fmt.Errorf("could not delete extra file %s: %v", path, err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -354,12 +549,12 @@ func ProcessRPM(pd *data.ProcessData) {
|
|||||||
Parents: hashes,
|
Parents: hashes,
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatalf("could not commit object: %v", err)
|
return fmt.Errorf("could not commit object: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
obj, err := repo.CommitObject(commit)
|
obj, err := repo.CommitObject(commit)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatalf("could not get commit object: %v", err)
|
return fmt.Errorf("could not get commit object: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
log.Printf("committed:\n%s", obj.String())
|
log.Printf("committed:\n%s", obj.String())
|
||||||
@ -374,7 +569,7 @@ func ProcessRPM(pd *data.ProcessData) {
|
|||||||
SignKey: nil,
|
SignKey: nil,
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatalf("could not create tag: %v", err)
|
return fmt.Errorf("could not create tag: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
pushRefspecs = append(pushRefspecs, config.RefSpec("HEAD:"+plumbing.NewTagReferenceName(newTag)))
|
pushRefspecs = append(pushRefspecs, config.RefSpec("HEAD:"+plumbing.NewTagReferenceName(newTag)))
|
||||||
@ -386,15 +581,17 @@ func ProcessRPM(pd *data.ProcessData) {
|
|||||||
Force: true,
|
Force: true,
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatalf("could not push to remote: %v", err)
|
return fmt.Errorf("could not push to remote: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
hashString := obj.Hash.String()
|
hashString := obj.Hash.String()
|
||||||
latestHashForBranch[md.PushBranch] = hashString
|
latestHashForBranch[md.PushBranch] = hashString
|
||||||
}
|
}
|
||||||
|
|
||||||
err := json.NewEncoder(os.Stdout).Encode(latestHashForBranch)
|
err = json.NewEncoder(os.Stdout).Encode(latestHashForBranch)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatalf("could not print hashes")
|
return fmt.Errorf("could not print hashes")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
|
@ -1,187 +0,0 @@
|
|||||||
// Copyright (c) 2021 The Srpmproc Authors
|
|
||||||
//
|
|
||||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
||||||
// of this software and associated documentation files (the "Software"), to deal
|
|
||||||
// in the Software without restriction, including without limitation the rights
|
|
||||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
||||||
// copies of the Software, and to permit persons to whom the Software is
|
|
||||||
// furnished to do so, subject to the following conditions:
|
|
||||||
//
|
|
||||||
// The above copyright notice and this permission notice shall be included in all
|
|
||||||
// copies or substantial portions of the Software.
|
|
||||||
//
|
|
||||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
||||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
||||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
||||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
||||||
// SOFTWARE.
|
|
||||||
|
|
||||||
package srpmproc
|
|
||||||
|
|
||||||
import (
|
|
||||||
"bytes"
|
|
||||||
"crypto/sha256"
|
|
||||||
"fmt"
|
|
||||||
"io"
|
|
||||||
"io/ioutil"
|
|
||||||
"log"
|
|
||||||
"os"
|
|
||||||
"os/exec"
|
|
||||||
"path/filepath"
|
|
||||||
"strings"
|
|
||||||
|
|
||||||
"github.com/cavaliercoder/go-cpio"
|
|
||||||
"github.com/cavaliercoder/go-rpm"
|
|
||||||
"github.com/go-git/go-billy/v5/memfs"
|
|
||||||
"github.com/go-git/go-git/v5"
|
|
||||||
"github.com/go-git/go-git/v5/storage/memory"
|
|
||||||
"github.com/rocky-linux/srpmproc/pkg/data"
|
|
||||||
)
|
|
||||||
|
|
||||||
type SrpmMode struct{}
|
|
||||||
|
|
||||||
func (s *SrpmMode) RetrieveSource(pd *data.ProcessData) *data.ModeData {
|
|
||||||
cmd := exec.Command("rpm2cpio", pd.RpmLocation)
|
|
||||||
cpioBytes, err := cmd.Output()
|
|
||||||
if err != nil {
|
|
||||||
log.Fatalf("could not convert to cpio (maybe rpm2cpio is missing): %v", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
// create in memory git repository
|
|
||||||
repo, err := git.Init(memory.NewStorage(), memfs.New())
|
|
||||||
if err != nil {
|
|
||||||
log.Fatalf("could not init git Repo: %v", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
// read the rpm in cpio format
|
|
||||||
buf := bytes.NewReader(cpioBytes)
|
|
||||||
r := cpio.NewReader(buf)
|
|
||||||
fileWrites := map[string][]byte{}
|
|
||||||
for {
|
|
||||||
hdr, err := r.Next()
|
|
||||||
if err == io.EOF {
|
|
||||||
// end of cpio archive
|
|
||||||
break
|
|
||||||
}
|
|
||||||
if err != nil {
|
|
||||||
log.Fatalln(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
bts, err := ioutil.ReadAll(r)
|
|
||||||
if err != nil {
|
|
||||||
log.Fatalf("could not copy file to virtual filesystem: %v", err)
|
|
||||||
}
|
|
||||||
fileWrites[hdr.Name] = bts
|
|
||||||
}
|
|
||||||
|
|
||||||
w, err := repo.Worktree()
|
|
||||||
if err != nil {
|
|
||||||
log.Fatalf("could not get Worktree: %v", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
// create structure
|
|
||||||
err = w.Filesystem.MkdirAll("SPECS", 0755)
|
|
||||||
if err != nil {
|
|
||||||
log.Fatalf("could not create SPECS dir in vfs: %v", err)
|
|
||||||
}
|
|
||||||
err = w.Filesystem.MkdirAll("SOURCES", 0755)
|
|
||||||
if err != nil {
|
|
||||||
log.Fatalf("could not create SOURCES dir in vfs: %v", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
f, err := os.Open(pd.RpmLocation)
|
|
||||||
if err != nil {
|
|
||||||
log.Fatalf("could not open the file again: %v", err)
|
|
||||||
}
|
|
||||||
rpmFile, err := rpm.ReadPackageFile(f)
|
|
||||||
if err != nil {
|
|
||||||
log.Fatalf("could not read package, invalid?: %v", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
var sourcesToIgnore []*data.IgnoredSource
|
|
||||||
for _, source := range rpmFile.Source() {
|
|
||||||
if strings.Contains(source, ".tar") {
|
|
||||||
sourcesToIgnore = append(sourcesToIgnore, &data.IgnoredSource{
|
|
||||||
Name: source,
|
|
||||||
HashFunction: sha256.New(),
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
branch := fmt.Sprintf("%s%d", pd.BranchPrefix, pd.Version)
|
|
||||||
return &data.ModeData{
|
|
||||||
Repo: repo,
|
|
||||||
Worktree: w,
|
|
||||||
RpmFile: rpmFile,
|
|
||||||
FileWrites: fileWrites,
|
|
||||||
Branches: []string{branch},
|
|
||||||
SourcesToIgnore: sourcesToIgnore,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *SrpmMode) WriteSource(_ *data.ProcessData, md *data.ModeData) {
|
|
||||||
for fileName, contents := range md.FileWrites {
|
|
||||||
var newPath string
|
|
||||||
if filepath.Ext(fileName) == ".spec" {
|
|
||||||
newPath = filepath.Join("SPECS", fileName)
|
|
||||||
} else {
|
|
||||||
newPath = filepath.Join("SOURCES", fileName)
|
|
||||||
}
|
|
||||||
|
|
||||||
mode := os.FileMode(0666)
|
|
||||||
for _, file := range md.RpmFile.Files() {
|
|
||||||
if file.Name() == fileName {
|
|
||||||
mode = file.Mode()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// add the file to the virtual filesystem
|
|
||||||
// we will move it to correct destination later
|
|
||||||
f, err := md.Worktree.Filesystem.OpenFile(newPath, os.O_RDWR|os.O_CREATE|os.O_TRUNC, mode)
|
|
||||||
if err != nil {
|
|
||||||
log.Fatalf("could not create file %s: %v", fileName, err)
|
|
||||||
}
|
|
||||||
|
|
||||||
_, err = f.Write(contents)
|
|
||||||
if err != nil {
|
|
||||||
log.Fatalf("could not write to file %s: %v", fileName, err)
|
|
||||||
}
|
|
||||||
|
|
||||||
_ = f.Close()
|
|
||||||
|
|
||||||
// don't add ignored file to git
|
|
||||||
if data.IgnoredContains(md.SourcesToIgnore, fileName) {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
_, err = md.Worktree.Add(newPath)
|
|
||||||
if err != nil {
|
|
||||||
log.Fatalf("could not add source file: %v", err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// add sources to ignore (remote sources)
|
|
||||||
gitIgnore, err := md.Worktree.Filesystem.Create(".gitignore")
|
|
||||||
if err != nil {
|
|
||||||
log.Fatalf("could not create .gitignore: %v", err)
|
|
||||||
}
|
|
||||||
for _, ignore := range md.SourcesToIgnore {
|
|
||||||
line := fmt.Sprintf("SOURCES/%s\n", ignore)
|
|
||||||
_, err := gitIgnore.Write([]byte(line))
|
|
||||||
if err != nil {
|
|
||||||
log.Fatalf("could not write line to .gitignore: %v", err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
err = gitIgnore.Close()
|
|
||||||
if err != nil {
|
|
||||||
log.Fatalf("could not close .gitignore: %v", err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *SrpmMode) PostProcess(_ *data.ModeData) {}
|
|
||||||
|
|
||||||
func (s *SrpmMode) ImportName(pd *data.ProcessData, _ *data.ModeData) string {
|
|
||||||
return filepath.Base(pd.RpmLocation)
|
|
||||||
}
|
|
Loading…
Reference in New Issue
Block a user