gitea

Зеркало из https://github.com/go-gitea/gitea
Форк
0
/
task.go 
211 строк · 5.6 Кб
1
// Copyright 2019 Gitea. All rights reserved.
2
// SPDX-License-Identifier: MIT
3

4
package admin
5

6
import (
7
	"context"
8
	"fmt"
9

10
	"code.gitea.io/gitea/models/db"
11
	repo_model "code.gitea.io/gitea/models/repo"
12
	user_model "code.gitea.io/gitea/models/user"
13
	"code.gitea.io/gitea/modules/json"
14
	"code.gitea.io/gitea/modules/migration"
15
	"code.gitea.io/gitea/modules/secret"
16
	"code.gitea.io/gitea/modules/setting"
17
	"code.gitea.io/gitea/modules/structs"
18
	"code.gitea.io/gitea/modules/timeutil"
19
	"code.gitea.io/gitea/modules/util"
20
)
21

22
// Task represents a task
23
type Task struct {
24
	ID             int64
25
	DoerID         int64                  `xorm:"index"` // operator
26
	Doer           *user_model.User       `xorm:"-"`
27
	OwnerID        int64                  `xorm:"index"` // repo owner id, when creating, the repoID maybe zero
28
	Owner          *user_model.User       `xorm:"-"`
29
	RepoID         int64                  `xorm:"index"`
30
	Repo           *repo_model.Repository `xorm:"-"`
31
	Type           structs.TaskType
32
	Status         structs.TaskStatus `xorm:"index"`
33
	StartTime      timeutil.TimeStamp
34
	EndTime        timeutil.TimeStamp
35
	PayloadContent string             `xorm:"TEXT"`
36
	Message        string             `xorm:"TEXT"` // if task failed, saved the error reason, it could be a JSON string of TranslatableMessage or a plain message
37
	Created        timeutil.TimeStamp `xorm:"created"`
38
}
39

40
func init() {
41
	db.RegisterModel(new(Task))
42
}
43

44
// TranslatableMessage represents JSON struct that can be translated with a Locale
45
type TranslatableMessage struct {
46
	Format string
47
	Args   []any `json:"omitempty"`
48
}
49

50
// LoadRepo loads repository of the task
51
func (task *Task) LoadRepo(ctx context.Context) error {
52
	if task.Repo != nil {
53
		return nil
54
	}
55
	var repo repo_model.Repository
56
	has, err := db.GetEngine(ctx).ID(task.RepoID).Get(&repo)
57
	if err != nil {
58
		return err
59
	} else if !has {
60
		return repo_model.ErrRepoNotExist{
61
			ID: task.RepoID,
62
		}
63
	}
64
	task.Repo = &repo
65
	return nil
66
}
67

68
// LoadDoer loads do user
69
func (task *Task) LoadDoer(ctx context.Context) error {
70
	if task.Doer != nil {
71
		return nil
72
	}
73

74
	var doer user_model.User
75
	has, err := db.GetEngine(ctx).ID(task.DoerID).Get(&doer)
76
	if err != nil {
77
		return err
78
	} else if !has {
79
		return user_model.ErrUserNotExist{
80
			UID: task.DoerID,
81
		}
82
	}
83
	task.Doer = &doer
84

85
	return nil
86
}
87

88
// LoadOwner loads owner user
89
func (task *Task) LoadOwner(ctx context.Context) error {
90
	if task.Owner != nil {
91
		return nil
92
	}
93

94
	var owner user_model.User
95
	has, err := db.GetEngine(ctx).ID(task.OwnerID).Get(&owner)
96
	if err != nil {
97
		return err
98
	} else if !has {
99
		return user_model.ErrUserNotExist{
100
			UID: task.OwnerID,
101
		}
102
	}
103
	task.Owner = &owner
104

105
	return nil
106
}
107

108
// UpdateCols updates some columns
109
func (task *Task) UpdateCols(ctx context.Context, cols ...string) error {
110
	_, err := db.GetEngine(ctx).ID(task.ID).Cols(cols...).Update(task)
111
	return err
112
}
113

114
// MigrateConfig returns task config when migrate repository
115
func (task *Task) MigrateConfig() (*migration.MigrateOptions, error) {
116
	if task.Type == structs.TaskTypeMigrateRepo {
117
		var opts migration.MigrateOptions
118
		err := json.Unmarshal([]byte(task.PayloadContent), &opts)
119
		if err != nil {
120
			return nil, err
121
		}
122

123
		// decrypt credentials
124
		if opts.CloneAddrEncrypted != "" {
125
			if opts.CloneAddr, err = secret.DecryptSecret(setting.SecretKey, opts.CloneAddrEncrypted); err != nil {
126
				return nil, err
127
			}
128
		}
129
		if opts.AuthPasswordEncrypted != "" {
130
			if opts.AuthPassword, err = secret.DecryptSecret(setting.SecretKey, opts.AuthPasswordEncrypted); err != nil {
131
				return nil, err
132
			}
133
		}
134
		if opts.AuthTokenEncrypted != "" {
135
			if opts.AuthToken, err = secret.DecryptSecret(setting.SecretKey, opts.AuthTokenEncrypted); err != nil {
136
				return nil, err
137
			}
138
		}
139

140
		return &opts, nil
141
	}
142
	return nil, fmt.Errorf("Task type is %s, not Migrate Repo", task.Type.Name())
143
}
144

145
// ErrTaskDoesNotExist represents a "TaskDoesNotExist" kind of error.
146
type ErrTaskDoesNotExist struct {
147
	ID     int64
148
	RepoID int64
149
	Type   structs.TaskType
150
}
151

152
// IsErrTaskDoesNotExist checks if an error is a ErrTaskDoesNotExist.
153
func IsErrTaskDoesNotExist(err error) bool {
154
	_, ok := err.(ErrTaskDoesNotExist)
155
	return ok
156
}
157

158
func (err ErrTaskDoesNotExist) Error() string {
159
	return fmt.Sprintf("task does not exist [id: %d, repo_id: %d, type: %d]",
160
		err.ID, err.RepoID, err.Type)
161
}
162

163
func (err ErrTaskDoesNotExist) Unwrap() error {
164
	return util.ErrNotExist
165
}
166

167
// GetMigratingTask returns the migrating task by repo's id
168
func GetMigratingTask(ctx context.Context, repoID int64) (*Task, error) {
169
	task := Task{
170
		RepoID: repoID,
171
		Type:   structs.TaskTypeMigrateRepo,
172
	}
173
	has, err := db.GetEngine(ctx).Get(&task)
174
	if err != nil {
175
		return nil, err
176
	} else if !has {
177
		return nil, ErrTaskDoesNotExist{0, repoID, task.Type}
178
	}
179
	return &task, nil
180
}
181

182
// CreateTask creates a task on database
183
func CreateTask(ctx context.Context, task *Task) error {
184
	return db.Insert(ctx, task)
185
}
186

187
// FinishMigrateTask updates database when migrate task finished
188
func FinishMigrateTask(ctx context.Context, task *Task) error {
189
	task.Status = structs.TaskStatusFinished
190
	task.EndTime = timeutil.TimeStampNow()
191

192
	// delete credentials when we're done, they're a liability.
193
	conf, err := task.MigrateConfig()
194
	if err != nil {
195
		return err
196
	}
197
	conf.AuthPassword = ""
198
	conf.AuthToken = ""
199
	conf.CloneAddr = util.SanitizeCredentialURLs(conf.CloneAddr)
200
	conf.AuthPasswordEncrypted = ""
201
	conf.AuthTokenEncrypted = ""
202
	conf.CloneAddrEncrypted = ""
203
	confBytes, err := json.Marshal(conf)
204
	if err != nil {
205
		return err
206
	}
207
	task.PayloadContent = string(confBytes)
208

209
	_, err = db.GetEngine(ctx).ID(task.ID).Cols("status", "end_time", "payload_content").Update(task)
210
	return err
211
}
212

Использование cookies

Мы используем файлы cookie в соответствии с Политикой конфиденциальности и Политикой использования cookies.

Нажимая кнопку «Принимаю», Вы даете АО «СберТех» согласие на обработку Ваших персональных данных в целях совершенствования нашего веб-сайта и Сервиса GitVerse, а также повышения удобства их использования.

Запретить использование cookies Вы можете самостоятельно в настройках Вашего браузера.