My Very Own CI-server
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 

169 lines
4.9 KiB

  1. // entry point of mvoCI
  2. // currently mvoCI uses gorm as the Database ORM, and echo as the webserver.
  3. package main
  4. import (
  5. "os"
  6. "fmt"
  7. "flag"
  8. "bytes"
  9. "errors"
  10. "strconv"
  11. "net/http"
  12. "io/ioutil"
  13. . "mvoCI/core"
  14. "mvoCI/core"
  15. "mvoCI/web"
  16. "mvoCI/build"
  17. . "mvoCI/hook"
  18. "encoding/json"
  19. "github.com/jinzhu/gorm"
  20. )
  21. // send a webhook to the local instance of mvoCI to trigger a build event
  22. func SendLocalBuild ( db *gorm.DB, port int, rID uint, secret string ) error {
  23. var r core.Repository
  24. db.Where("id = ?", rID).First( &r )
  25. if r.ID != rID {
  26. return errors.New ("Repository not found")
  27. }
  28. if r.Secret != secret {
  29. return errors.New ("Secret not accepted")
  30. }
  31. if r.LocalBuildEnable == false {
  32. return errors.New ("Local Build is not enabled")
  33. }
  34. var l LocalPayload = LocalPayload {
  35. Secret: r.Secret,
  36. RepositoryID: r.ID,
  37. RepositoryName: r.Name,
  38. Action: "build",
  39. }
  40. // set-up JSON data
  41. b, err := json.Marshal(l)
  42. if err != nil {
  43. return err
  44. }
  45. // send JSON data to the local instance (find out the correct URL)
  46. url := "http://127.0.0.1:" + strconv.FormatInt ( int64(port), 10 ) + "/push/hook/local"
  47. req, _ := http.NewRequest( "POST", url, bytes.NewBuffer( b ) )
  48. req.Header.Set("Content-Type", "application/json")
  49. client := &http.Client{}
  50. resp, err := client.Do(req)
  51. // wait for response and report an error back (or nil if success)
  52. if err != nil {
  53. return err
  54. }
  55. defer resp.Body.Close()
  56. if resp.StatusCode != 200 {
  57. body, _ := ioutil.ReadAll ( resp.Body )
  58. return errors.New( string(body) )
  59. }
  60. return nil
  61. }
  62. // entry point of mvoCI, sets up the config data structure for the rest of the
  63. // system and bootstraps the database and the web-server
  64. func main() {
  65. // set up command line parameters
  66. var install bool;
  67. var w bool;
  68. var port int;
  69. var d bool;
  70. var localhook bool;
  71. var repositoryID int;
  72. var localSecret string;
  73. var err error
  74. flag.BoolVar ( &w, "web", false, "Starts the complete web-application, if not: only webhook and local hook");
  75. flag.BoolVar ( &install, "install", false, "Starts " + os.Args[0] + " with installer enabled")
  76. flag.IntVar ( &port, "port", 0, "Specify the port to bind to")
  77. flag.BoolVar ( &d, "debug", false, "Starts " + os.Args[0] + " with verbose debug output")
  78. flag.BoolVar ( &localhook, "local", false, "Send a local build hook")
  79. flag.IntVar ( &repositoryID, "repository", -1, "The ID of the repository to build")
  80. flag.StringVar ( &localSecret, "secret", "", "Secret for starting a build locally")
  81. flag.Parse()
  82. // read the config
  83. var cfg core.Config;
  84. cfg, err = core.ConfigRead ( core.ConfigFile )
  85. if ( install ) {
  86. cfg.Install = true
  87. }
  88. os.Mkdir ( "log", 0777 )
  89. lf := cfg.LogFile;
  90. lfenable := cfg.LogFileEnable;
  91. lmode := cfg.LogMode;
  92. if lfenable == true && len(lf) > 0 {
  93. core.LogFileEnable = true;
  94. }
  95. if lmode == "stdout" {
  96. core.LogStdoutEnable = true;
  97. core.LogStderrEnable = false;
  98. } else {
  99. core.LogStdoutEnable = false;
  100. core.LogStderrEnable = true;
  101. }
  102. if ( d ) {
  103. cfg.Debug = true;
  104. }
  105. if ( port != 0 ) {
  106. cfg.HttpPort = port
  107. }
  108. core.LogInit ( lf )
  109. defer core.LogClose();
  110. Console.Log ("Read Configuration (", ConfigFile, ") successfully" )
  111. // set up gorm database connection
  112. var db *gorm.DB;
  113. if cfg.Install == true {
  114. Console.Log ("Installation mode: Skipping Database connection");
  115. db = nil
  116. } else {
  117. Console.Log ("Connecting to database: ", cfg.Database.Provider );
  118. db, err = core.DBConnect ( &cfg );
  119. if err != nil {
  120. Console.Log ("Cannot connect to database: ", err )
  121. }
  122. }
  123. // send build hook locally
  124. if cfg.Install != true && localhook {
  125. if repositoryID < 0 {
  126. fmt.Println ("[FAIL] No valid repository ID given")
  127. } else {
  128. if db == nil {
  129. fmt.Println ("[FAIL] Cannot procede with no database connection")
  130. }
  131. err = SendLocalBuild( db, cfg.HttpPort, uint(repositoryID), localSecret )
  132. if err == nil {
  133. fmt.Println ("[ OK ] Sending hook for R (", repositoryID, ") successful")
  134. } else {
  135. fmt.Println ("[FAIL] An error occured while sending hook for R (", repositoryID, "): ", err)
  136. }
  137. }
  138. return;
  139. }
  140. if cfg.Install == false {
  141. Console.Log ( "Setting up build workers" )
  142. build.SetupWorkerThreads ( &cfg, db );
  143. }
  144. Console.Log ( "Starting: %s", cfg.AppTitle )
  145. // start eh web server and hand everything over to it
  146. server := web.NewServer ( &cfg, db )
  147. server.Start();
  148. }