g2g/functions.go

245 lines
6.4 KiB
Go
Raw Normal View History

2019-06-09 14:44:07 +02:00
package main
import (
"bytes"
"encoding/json"
"errors"
2019-06-09 14:44:07 +02:00
"flag"
"fmt"
"io/ioutil"
"log"
"net/http"
"os"
2019-07-10 15:07:41 +02:00
"sync"
2019-06-09 14:44:07 +02:00
"gopkg.in/ini.v1"
)
// GetConfig fetch configuration
2019-07-14 19:32:47 +02:00
func (config *Config) GetConfig() error {
2019-07-07 12:47:28 +02:00
var configfile string
2019-06-09 14:44:07 +02:00
flag.Usage = Usage
2019-07-24 00:27:41 +02:00
flag.StringVar(&configfile, "configfile", "g2g.ini", "config file to use with g2g section")
2019-06-09 14:44:07 +02:00
flag.Parse()
cfg, err := ini.Load(configfile)
if err != nil {
return err
}
2019-06-09 14:44:07 +02:00
g2gsection := cfg.Section("g2g")
2019-06-09 14:44:07 +02:00
config.UserAgent = g2gsection.Key("user_agent").MustString("Golang")
config.RequestTimeout = g2gsection.Key("request_timeout").MustDuration(1200)
config.Threads = g2gsection.Key("threads").MustInt(2)
config.GitHubPageNum = g2gsection.Key("github_page_num").MustInt(3)
config.GitHubMaxPerPage = g2gsection.Key("github_max_per_page").MustInt(100)
config.GitHubAuthUsername = g2gsection.Key("github_auth_username").MustString("username")
config.GitHubAuthPassword = g2gsection.Key("github_auth_password").MustString("password")
2019-06-09 14:44:07 +02:00
config.GiteaUsername = g2gsection.Key("gitea_username").MustString("username")
config.GiteaDestUsername = g2gsection.Key("gitea_dest_username").MustString("dest_username")
config.GiteaRepoURLTmpl = g2gsection.Key("gitea_repo_url_tmpl").MustString("repo_url")
config.GiteaOrgsURLTmpl = g2gsection.Key("gitea_orgs_url_tmpl").MustString("orgs_url")
config.GiteaMigrateURL = g2gsection.Key("gitea_migrate_url").MustString("migrate_url")
config.GiteaAuthToken = g2gsection.Key("gitea_auth_token").MustString("token")
config.GiteaMirror = g2gsection.Key("gitea_mirror").MustBool(true)
2019-06-09 14:44:07 +02:00
return err
2019-06-09 14:44:07 +02:00
}
2019-07-07 12:47:28 +02:00
// GetReposFromGitHub get starred repositories from github
func GetReposFromGitHub(config *Config) ([]GitHubRepo, error) {
var repopartiallist []GitHubRepo
var repofulllist []GitHubRepo
2019-07-07 12:47:28 +02:00
2019-07-14 19:32:47 +02:00
fmt.Println("Getting GitHub starred repos")
for num := 1; num <= config.GitHubPageNum; num++ {
url := fmt.Sprintf("https://api.github.com/users/%s/starred?per_page=%d&page=%d", config.GitHubAuthUsername, config.GitHubMaxPerPage, num)
2019-07-10 15:07:41 +02:00
fmt.Println(url)
2019-07-07 12:47:28 +02:00
resp, err := InvokeGitHub(config, url)
if err != nil {
return nil, err
}
2019-07-24 00:27:41 +02:00
respbody, err := ioutil.ReadAll(resp.Body)
if err != nil {
return nil, err
}
2019-07-07 12:47:28 +02:00
2019-07-24 00:27:41 +02:00
err = json.Unmarshal(respbody, &repopartiallist)
if err != nil {
return nil, err
}
2019-07-24 00:27:41 +02:00
for _, elem := range repopartiallist {
repofulllist = append(repofulllist, elem)
2019-07-07 12:47:28 +02:00
}
}
2019-07-10 15:07:41 +02:00
fmt.Println(fmt.Sprintf("%d repositories from Github fetched", len(repofulllist)))
return repofulllist, nil
2019-07-07 12:47:28 +02:00
}
2019-06-09 14:44:07 +02:00
2019-07-07 12:47:28 +02:00
// InvokeGitHub ...
func InvokeGitHub(config *Config, url string) (*http.Response, error) {
2019-07-07 12:47:28 +02:00
req, err := http.NewRequest("GET", url, nil)
if err != nil {
return nil, err
}
2019-06-09 14:44:07 +02:00
req.Header.Add("Content-Type", "application/x-www-form-urlencoded")
req.Header.Set("User-Agent", config.UserAgent)
req.SetBasicAuth(config.GitHubAuthUsername, config.GitHubAuthPassword)
2019-07-07 12:47:28 +02:00
client := &http.Client{}
resp, err := client.Do(req)
if err != nil {
return nil, err
}
2019-07-07 12:47:28 +02:00
return resp, nil
2019-07-07 12:47:28 +02:00
}
// CheckGiteaExistingRepo checks if there's an existing repository in gitea
func CheckGiteaExistingRepo(config *Config, repo GitHubRepo) (bool, error) {
var isexists bool
2019-07-07 12:47:28 +02:00
gitearepourl := fmt.Sprintf(config.GiteaRepoURLTmpl, config.GiteaDestUsername, repo.Name)
2019-06-09 14:44:07 +02:00
req, err := http.NewRequest("GET", gitearepourl, nil)
req.Header.Set("Authorization", config.GiteaAuthToken)
req.Header.Set("User-Agent", config.UserAgent)
2019-06-09 14:44:07 +02:00
2019-07-07 12:47:28 +02:00
client := &http.Client{}
resp, err := client.Do(req)
if err != nil {
return false, err
}
2019-06-09 14:44:07 +02:00
if resp.StatusCode == 200 {
isexists = true
} else if resp.StatusCode == 404 {
isexists = false
2019-06-09 14:44:07 +02:00
} else {
err = fmt.Errorf("Can't determine error, cancelling, error %d in gitea webservice", resp.StatusCode)
return false, err
2019-06-09 14:44:07 +02:00
}
return isexists, nil
2019-06-09 14:44:07 +02:00
}
// GetGiteaUserUID get the logued user identifier
func (config *Config) GetGiteaUserUID() error {
var giteaorg GiteaOrg
2019-06-09 14:44:07 +02:00
gitearepourl := fmt.Sprintf(config.GiteaOrgsURLTmpl, config.GiteaDestUsername)
2019-06-09 14:44:07 +02:00
req, err := http.NewRequest("GET", gitearepourl, nil)
if err != nil {
return err
}
req.Header.Set("Authorization", config.GiteaAuthToken)
req.Header.Set("User-Agent", config.UserAgent)
2019-06-09 14:44:07 +02:00
2019-07-07 12:47:28 +02:00
client := &http.Client{}
resp, err := client.Do(req)
if err != nil {
return err
}
if resp.StatusCode != 200 {
err = errors.New("Error invoking gitea webservice")
return err
}
2019-06-09 14:44:07 +02:00
2019-07-24 00:27:41 +02:00
respbody, err := ioutil.ReadAll(resp.Body)
err = json.Unmarshal(respbody, &giteaorg)
if err != nil {
err = errors.New("Failed to parse user ID from gitea webservice, check auth")
return err
}
2019-06-09 14:44:07 +02:00
config.GiteaUID = giteaorg.ID
return nil
2019-06-09 14:44:07 +02:00
}
2019-07-10 15:07:41 +02:00
// RunMigration run threads for migration
func RunMigration(config *Config, repolist []GitHubRepo) {
2019-07-14 19:32:47 +02:00
repochan := make(chan GitHubRepo)
2019-07-10 15:07:41 +02:00
done := make(chan bool)
2019-06-09 14:44:07 +02:00
2019-07-10 15:07:41 +02:00
var wg sync.WaitGroup
for thr := range make([]int, config.Threads) {
go MigrateReposToGitea(config, &wg, repochan, done, thr)
2019-07-10 15:07:41 +02:00
}
2019-06-09 14:44:07 +02:00
2019-07-10 15:07:41 +02:00
for _, repo := range repolist {
2019-07-14 19:32:47 +02:00
repochan <- repo
2019-07-10 15:07:41 +02:00
}
2019-07-14 19:32:47 +02:00
close(repochan)
2019-07-10 15:07:41 +02:00
<-done
wg.Wait()
}
2019-06-09 14:44:07 +02:00
// MigrateReposToGitea migrates input repositories to gitea
func MigrateReposToGitea(config *Config, wg *sync.WaitGroup, jobs chan GitHubRepo, done chan bool, thr int) error {
2019-07-10 15:07:41 +02:00
wg.Add(1)
for {
elem, more := <-jobs
if more {
client := &http.Client{}
existingrepo, err := CheckGiteaExistingRepo(config, elem)
if err != nil {
return err
}
2019-07-10 15:07:41 +02:00
if !existingrepo {
jsondata := fmt.Sprintf(`{"uid" : %d, "repo_name" : "%s" , "mirror" : %v, "clone_addr" : "%s"}`, config.GiteaUID, elem.Name, true, elem.CloneURL)
2019-07-10 15:07:41 +02:00
req, err := http.NewRequest("POST", config.GiteaMigrateURL, bytes.NewBufferString(jsondata))
2019-07-10 15:07:41 +02:00
if err != nil {
return err
}
req.Header.Add("Content-Type", "application/json")
req.Header.Set("User-Agent", config.UserAgent)
req.Header.Set("Authorization", config.GiteaAuthToken)
2019-07-10 15:07:41 +02:00
client.Timeout = config.RequestTimeout
2019-07-10 15:07:41 +02:00
fmt.Println(fmt.Sprintf("Migrating repo %s to gitea rest api", elem.Name))
2019-07-24 00:27:41 +02:00
resp, err := client.Do(req)
2019-07-10 15:07:41 +02:00
if err != nil {
return err
}
2019-07-24 00:27:41 +02:00
2019-07-10 15:07:41 +02:00
if resp.StatusCode != 201 {
err = fmt.Errorf("Error when migrating repo %s to gitea with status code %d on gitea webservice", elem.Name, resp.StatusCode)
2019-07-10 15:07:41 +02:00
log.Println(err)
}
} else {
fmt.Println(fmt.Sprintf("Not migrating, %s exists in gitea", elem.Name))
}
2019-07-07 12:47:28 +02:00
} else {
2019-07-10 15:07:41 +02:00
fmt.Println(fmt.Sprintf("All repo migrated on thread num %d", thr))
wg.Done()
done <- true
return nil
2019-06-09 14:44:07 +02:00
}
}
}
// Usage displays possible arguments
func Usage() {
flag.PrintDefaults()
os.Exit(1)
}