11package cvm
22
3- /*
4- #include <unistd.h>
5- #include <stdio.h>
6- #include <stdlib.h>
7- */
8- import "C"
93import (
4+ "apploader/internal/config"
105 "apploader/internal/secret"
6+ "apploader/pkg/command"
117 "apploader/pkg/conversion"
128 "apploader/pkg/file"
139 "fmt"
1410 "log"
1511 "os"
16- "os/exec"
1712 "path"
1813 "strings"
19- "syscall"
2014 "text/template"
21- "time"
22- "unsafe"
2315
2416 "gopkg.in/yaml.v3"
2517)
2618
2719const (
28- JOB = "job"
29- SERVER = "server"
30- DockerApp = "dockerApp"
31- APP = "app"
20+ JOB = "job"
21+ SERVER = "server"
3222)
3323
34- const (
35- SUPERVISOR_PATH = "/workplace/supervisord/apploader"
36- )
37-
38- func DoJob (ca * TaskInfo ) error {
39- if ca .Type != JOB {
40- return fmt .Errorf ("this task is not a job" )
41- }
42-
43- envs := make ([]string , 0 )
44- for k , v := range secret .Secret {
45- envs = append (envs , fmt .Sprintf ("%s=%s" , k , v ))
46- }
47-
48- if ca .Env != nil {
49- userEnv , ok := ca .Env .(map [string ]interface {})
50- if ! ok {
51- return fmt .Errorf ("user env format error" )
52- }
53-
54- for k , v := range userEnv {
55- envs = append (envs , fmt .Sprintf ("%s=%s" , k , v ))
56- }
57- }
58-
59- log .Printf ("entrypoint is %s" , ca .Entrypoint )
60- return RunCommand (ca .Entrypoint , envs , ca .Args ... )
61-
24+ type CvmBootManager interface {
25+ Start ()
6226}
6327
64- func RunCommand (name string , envs []string , arg ... string ) error {
65- cmd := exec .Command (name , arg ... )
28+ type cvmBootManager struct {
29+ config * config.CvmConfig
30+ cvmBootSequence * CvmBootSequence
31+ }
6632
67- cmd .Dir = path .Dir (name )
68- //
69- stdout , err := cmd .StdoutPipe ()
70- cmd .Stderr = cmd .Stdout
71- cmd .Env = envs
33+ // NewCvmBootManager creates a new cvm service
34+ func NewCvmBootManager (config * config.CvmConfig ) (CvmBootManager , error ) {
35+ service := & cvmBootManager {config : config }
36+ cvmBootSequence , err := service .loadConfig ()
7237 if err != nil {
73- return err
74- }
75- if err = cmd .Start (); err != nil {
76- return err
77- }
78- //
79- for {
80- tmp := make ([]byte , 128 )
81- _ , err := stdout .Read (tmp )
82- fmt .Print (string (tmp ))
83- if err != nil {
84- break
85- }
38+ return nil , err
8639 }
87- if err = cmd .Wait (); err != nil {
88- if ex , ok := err .(* exec.ExitError ); ok {
89- cmdExitStatus := ex .Sys ().(syscall.WaitStatus ).ExitStatus ()
90- log .Println (cmdExitStatus )
91- }
92- log .Println (err )
93- return err
94- }
95- return nil
40+ service .cvmBootSequence = cvmBootSequence
41+ return service , nil
9642}
9743
98- func Execv ( main string , args ... string ) {
99- workdir := path . Dir ( main )
100- if err := os . Chdir ( workdir ); err != nil {
101- log . Fatalf ( "change to work dir failed, error: %s \n " , err . Error () )
102- }
44+ // Start starts the cvm service
45+ func ( s * cvmBootManager ) Start () {
46+ s . startTask ( s . cvmBootSequence . CvmAssistants )
47+ s . startTask ( s . cvmBootSequence . AppInfo )
48+ }
10349
104- sizeOfArgs_C := len (args ) + 2 // +2 for [0]=main [1:end]=args [end]=nil
105- Args_C := make ([]* C.char , sizeOfArgs_C )
106- Args_C [0 ] = C .CString (main )
107- defer C .free (unsafe .Pointer (Args_C [0 ]))
108- for i , arg := range args {
109- Args_C [i + 1 ] = C .CString (arg )
110- defer C .free (unsafe .Pointer (Args_C [i + 1 ]))
50+ // loadConfig loads the cvm app config
51+ func (cbm * cvmBootManager ) loadConfig () (* CvmBootSequence , error ) {
52+ appfile , err := os .ReadFile (cbm .config .ConfigPath )
53+ if err != nil {
54+ return nil , fmt .Errorf ("read %s failed, error: %s" , cbm .config .ConfigPath , err .Error ())
11155 }
112- Args_C [ sizeOfArgs_C - 1 ] = nil
113- re := C . execv ( C . CString ( main ), ( * * C . char )( unsafe . Pointer ( & Args_C [ 0 ])) )
114- if re != 0 {
115- log . Fatalf ( "execv %s failed, code is %d \n " , main , re )
56+ cvmBootSequence := new ( CvmBootSequence )
57+ err = yaml . Unmarshal ( appfile , & cvmBootSequence )
58+ if err != nil {
59+ return nil , fmt . Errorf ( "unmarshal %s failed, error: %s " , cbm . config . ConfigPath , err . Error () )
11660 }
117- return
61+ return cvmBootSequence , nil
11862}
11963
120- func ExecvDockerApp ( ca * TaskInfo ) {
121- if ca .Type != DockerApp {
122- log . Fatalf ( " task is not a docker app " )
64+ func ( cbm * cvmBootManager ) DoJob ( taskInfo * TaskInfo ) error {
65+ if taskInfo .Type != JOB {
66+ return fmt . Errorf ( "this task is not a job " )
12367 }
12468
69+ envs := make ([]string , 0 )
12570 for k , v := range secret .Secret {
126- err := os .Setenv (k , v )
127- if err != nil {
128- log .Fatalf ("set secret env failed, error: %s\n " , err .Error ())
129- }
71+ envs = append (envs , fmt .Sprintf ("%s=%s" , k , v ))
13072 }
13173
132- if ca .Env != nil {
133- userEnv , ok := ca .Env .(map [string ]interface {})
74+ if taskInfo .Env != nil {
75+ userEnv , ok := taskInfo .Env .(map [string ]interface {})
13476 if ! ok {
135- log . Fatalf ("user env format error" )
77+ return fmt . Errorf ("user env format error" )
13678 }
13779
13880 for k , v := range userEnv {
139- err := os .Setenv (k , v .(string ))
140- if err != nil {
141- log .Fatalf ("set app env failed, error: %s\n " , err .Error ())
142- }
81+ envs = append (envs , fmt .Sprintf ("%s=%s" , k , v ))
14382 }
14483 }
14584
146- Execv (ca .Entrypoint , ca .Args ... )
85+ log .Printf ("entrypoint is %s" , taskInfo .Entrypoint )
86+ return command .RunCommand (taskInfo .Entrypoint , envs , taskInfo .Args ... )
87+
14788}
14889
149- func CreateSevers (ca * TaskInfo ) error {
150- if ca .Type != SERVER {
90+ func ( cbm * cvmBootManager ) CreateSevers (taskInfo * TaskInfo ) error {
91+ if taskInfo .Type != SERVER {
15192 return fmt .Errorf ("task is not a server" )
15293 }
15394
@@ -158,8 +99,8 @@ func CreateSevers(ca *TaskInfo) error {
15899 // envs = append(envs, fmt.Sprintf("%s=%s", k, v))
159100 //}
160101
161- if ca .Env != nil {
162- userEnv , ok := ca .Env .(map [string ]interface {})
102+ if taskInfo .Env != nil {
103+ userEnv , ok := taskInfo .Env .(map [string ]interface {})
163104 if ! ok {
164105 return fmt .Errorf ("user env format error" )
165106 }
@@ -170,84 +111,61 @@ func CreateSevers(ca *TaskInfo) error {
170111 }
171112
172113 sConf := new (SupervisorConf )
173- sConf .Name = ca .Name
174- sConf .Command = ca .Entrypoint + " " + strings .Join (ca .Args , " " )
175- sConf .Workplace = path .Dir (ca .Entrypoint )
114+ sConf .Name = taskInfo .Name
115+ sConf .Command = taskInfo .Entrypoint + " " + strings .Join (taskInfo .Args , " " )
116+ sConf .Workplace = path .Dir (taskInfo .Entrypoint )
176117 sConf .Environment = strings .Join (envs , "," )
177- sConf .Priority = ca .Priority
118+ sConf .Priority = taskInfo .Priority
178119
179- tmpl , err := template .ParseFiles ("conf/supervisord.ini.template" )
120+ tmpl , err := template .ParseFiles (cbm . config . SupervisorTemplatePath )
180121 if err != nil {
181- return fmt .Errorf ("parse supervisord template file failed, error: %s\n " , err .Error ())
122+ return fmt .Errorf ("parse %s failed, error: %s" , cbm . config . SupervisorTemplatePath , err .Error ())
182123 }
183124
184- supervisordINIPath := path .Join (SUPERVISOR_PATH , fmt .Sprintf ("%s.ini" , ca .Name ))
125+ supervisordINIPath := path .Join (cbm . config . SupervisorPath , fmt .Sprintf ("%s.ini" , taskInfo .Name ))
185126 if file .IsFile (supervisordINIPath ) {
186127 os .RemoveAll (supervisordINIPath )
187128 }
188129
189130 f , err := os .Create (supervisordINIPath )
190131 if err != nil {
191- return fmt .Errorf ("create supervisord.ini failed, error: %s\n " , err .Error ())
132+ return fmt .Errorf ("create %s failed, error: %s" , supervisordINIPath , err .Error ())
192133 }
193134 defer f .Close ()
194135
195136 if err := tmpl .Execute (f , sConf ); err != nil {
196- return fmt .Errorf ("file the supervisord.ini failed, error: %s\n " , err .Error ())
137+ return fmt .Errorf ("fill the %s failed, error: %s" , supervisordINIPath , err .Error ())
197138 }
198139
199140 return nil
200141}
201142
202- func Start () {
203- appfile , err := os .ReadFile ("conf/app.yml" )
204- if err != nil {
205- log .Fatalf ("read app.yml failed, error: %s\n " , err .Error ())
206- }
207- cvmApp := new (CvmApp )
208- err = yaml .Unmarshal (appfile , & cvmApp )
209- if err != nil {
210- log .Fatalf ("unmarshal app.yml failed, error: %s\n " , err .Error ())
211- }
212- time .Sleep (5 * time .Second )
213-
214- log .Println ("do all the job over" )
215-
216- startTask (cvmApp .CvmAssistants )
217-
218- startTask (cvmApp .AppInfo )
219- }
220-
221- func startTask (tasks []* TaskInfo ) {
143+ func (cbm * cvmBootManager ) startTask (tasks []* TaskInfo ) {
222144 for i , t := range tasks {
223145 switch t .Type {
224146 case JOB :
225147 log .Printf ("begin to do job %s\n " , t .Name )
226- err := DoJob (t )
148+ err := cbm . DoJob (t )
227149 if err != nil {
228150 log .Fatalf ("do job %s failed, error: %s\n " , t .Name , err .Error ())
229151 }
230152 log .Printf ("end to do job %s\n " , t .Name )
231153 case SERVER :
232154 log .Printf ("begin to deploy server %s\n " , t .Name )
233155 t .Priority = i + 2
234- err := CreateSevers (t )
156+ err := cbm . CreateSevers (t )
235157 if err != nil {
236158 log .Fatalf ("deploy server %s failed, error: %s\n " , t .Name , err )
237159 }
238- err = RunCommand ("supervisorctl" , nil , "update" )
160+ err = command . RunCommand ("supervisorctl" , nil , "update" )
239161 if err != nil {
240162 log .Fatalf ("update supervisor conf failed, error: %s" , err .Error ())
241163 }
242- err = RunCommand ("supervisorctl" , nil , "start" , t .Name )
164+ err = command . RunCommand ("supervisorctl" , nil , "start" , t .Name )
243165 if err != nil {
244166 log .Fatalf ("start %s failed, error: %s" , t .Name , err .Error ())
245167 }
246168 log .Printf ("end to deply server %s\n " , t .Name )
247- case DockerApp :
248- log .Printf ("begin to run docker app %s\n " , t .Name )
249- log .Printf ("docker app will only run the first app\n " )
250- ExecvDockerApp (t )
251169 default :
252170 log .Fatalf ("task type: %s does not support" , t .Type )
253171 }
0 commit comments