2019-10-13 21:23:14 +08:00
// Copyright 2019 Gitea. All rights reserved.
2022-11-27 13:20:29 -05:00
// SPDX-License-Identifier: MIT
2019-10-13 21:23:14 +08:00
package task
import (
"fmt"
2022-08-25 10:31:57 +08:00
admin_model "code.gitea.io/gitea/models/admin"
2021-12-10 09:27:50 +08:00
repo_model "code.gitea.io/gitea/models/repo"
2021-11-24 17:49:20 +08:00
user_model "code.gitea.io/gitea/models/user"
2020-01-07 11:23:09 +00:00
"code.gitea.io/gitea/modules/graceful"
2021-07-25 00:03:58 +08:00
"code.gitea.io/gitea/modules/json"
2019-10-13 21:23:14 +08:00
"code.gitea.io/gitea/modules/log"
2021-11-16 23:25:33 +08:00
base "code.gitea.io/gitea/modules/migration"
2020-01-07 11:23:09 +00:00
"code.gitea.io/gitea/modules/queue"
2020-01-12 20:11:17 +08:00
repo_module "code.gitea.io/gitea/modules/repository"
2021-05-31 08:25:47 +00:00
"code.gitea.io/gitea/modules/secret"
"code.gitea.io/gitea/modules/setting"
2019-10-13 21:23:14 +08:00
"code.gitea.io/gitea/modules/structs"
2020-01-12 20:11:17 +08:00
"code.gitea.io/gitea/modules/timeutil"
2021-05-31 08:25:47 +00:00
"code.gitea.io/gitea/modules/util"
2019-10-13 21:23:14 +08:00
)
// taskQueue is a global queue of tasks
2020-01-07 11:23:09 +00:00
var taskQueue queue . Queue
2019-10-13 21:23:14 +08:00
// Run a task
2022-08-25 10:31:57 +08:00
func Run ( t * admin_model . Task ) error {
2019-10-13 21:23:14 +08:00
switch t . Type {
case structs . TaskTypeMigrateRepo :
return runMigrateTask ( t )
default :
2020-01-07 11:23:09 +00:00
return fmt . Errorf ( "Unknown task type: %d" , t . Type )
2019-10-13 21:23:14 +08:00
}
}
// Init will start the service to get all unfinished tasks and run them
func Init ( ) error {
2022-08-25 10:31:57 +08:00
taskQueue = queue . CreateQueue ( "task" , handle , & admin_model . Task { } )
2020-01-07 11:23:09 +00:00
if taskQueue == nil {
return fmt . Errorf ( "Unable to create Task Queue" )
2019-10-13 21:23:14 +08:00
}
2020-01-07 11:23:09 +00:00
go graceful . GetManager ( ) . RunWithShutdownFns ( taskQueue . Run )
2019-10-13 21:23:14 +08:00
return nil
}
2022-01-22 21:22:14 +00:00
func handle ( data ... queue . Data ) [ ] queue . Data {
2020-01-07 11:23:09 +00:00
for _ , datum := range data {
2022-08-25 10:31:57 +08:00
task := datum . ( * admin_model . Task )
2020-01-07 11:23:09 +00:00
if err := Run ( task ) ; err != nil {
log . Error ( "Run task failed: %v" , err )
}
}
2022-01-22 21:22:14 +00:00
return nil
2020-01-07 11:23:09 +00:00
}
2019-10-13 21:23:14 +08:00
// MigrateRepository add migration repository to task
2021-11-24 17:49:20 +08:00
func MigrateRepository ( doer , u * user_model . User , opts base . MigrateOptions ) error {
2020-01-12 20:11:17 +08:00
task , err := CreateMigrateTask ( doer , u , opts )
2019-10-13 21:23:14 +08:00
if err != nil {
return err
}
return taskQueue . Push ( task )
}
2020-01-12 20:11:17 +08:00
// CreateMigrateTask creates a migrate task
2022-08-25 10:31:57 +08:00
func CreateMigrateTask ( doer , u * user_model . User , opts base . MigrateOptions ) ( * admin_model . Task , error ) {
2021-05-31 08:25:47 +00:00
// encrypt credentials for persistence
var err error
opts . CloneAddrEncrypted , err = secret . EncryptSecret ( setting . SecretKey , opts . CloneAddr )
if err != nil {
return nil , err
}
2022-03-31 10:25:40 +08:00
opts . CloneAddr = util . SanitizeCredentialURLs ( opts . CloneAddr )
2021-05-31 08:25:47 +00:00
opts . AuthPasswordEncrypted , err = secret . EncryptSecret ( setting . SecretKey , opts . AuthPassword )
if err != nil {
return nil , err
}
opts . AuthPassword = ""
opts . AuthTokenEncrypted , err = secret . EncryptSecret ( setting . SecretKey , opts . AuthToken )
if err != nil {
return nil , err
}
opts . AuthToken = ""
2020-01-12 20:11:17 +08:00
bs , err := json . Marshal ( & opts )
if err != nil {
return nil , err
}
2022-08-25 10:31:57 +08:00
task := & admin_model . Task {
2020-01-12 20:11:17 +08:00
DoerID : doer . ID ,
OwnerID : u . ID ,
Type : structs . TaskTypeMigrateRepo ,
Status : structs . TaskStatusQueue ,
PayloadContent : string ( bs ) ,
}
2022-08-25 10:31:57 +08:00
if err := admin_model . CreateTask ( task ) ; err != nil {
2020-01-12 20:11:17 +08:00
return nil , err
}
2022-08-25 10:31:57 +08:00
repo , err := repo_module . CreateRepository ( doer , u , repo_module . CreateRepoOptions {
2020-01-12 20:11:17 +08:00
Name : opts . RepoName ,
Description : opts . Description ,
OriginalURL : opts . OriginalURL ,
GitServiceType : opts . GitServiceType ,
IsPrivate : opts . Private ,
IsMirror : opts . Mirror ,
2021-12-10 09:27:50 +08:00
Status : repo_model . RepositoryBeingMigrated ,
2020-01-12 20:11:17 +08:00
} )
if err != nil {
task . EndTime = timeutil . TimeStampNow ( )
task . Status = structs . TaskStatusFailed
err2 := task . UpdateCols ( "end_time" , "status" )
if err2 != nil {
log . Error ( "UpdateCols Failed: %v" , err2 . Error ( ) )
}
return nil , err
}
task . RepoID = repo . ID
if err = task . UpdateCols ( "repo_id" ) ; err != nil {
return nil , err
}
2021-11-13 11:28:50 +00:00
return task , nil
2020-01-12 20:11:17 +08:00
}