github.com/masahide/goansible@v0.0.0-20160116054156-01eac649e9f2/package/apt/apt.go (about) 1 package apt 2 3 import ( 4 "fmt" 5 "github.com/masahide/goansible" 6 "io/ioutil" 7 "os" 8 "path/filepath" 9 "regexp" 10 "time" 11 ) 12 13 type Apt struct { 14 Pkg string `goansible:"pkg"` 15 State string `goansible:"state" enum:"present,install,absent,remove"` 16 Cache bool `goansible:"update_cache"` 17 CacheTime string `goansible:"cache_time"` 18 Dry bool `goansible:"dryrun"` 19 } 20 21 var installed = regexp.MustCompile(`Installed: ([^\n]+)`) 22 var candidate = regexp.MustCompile(`Candidate: ([^\n]+)`) 23 24 func (a *Apt) Run(env *goansible.CommandEnv) (*goansible.Result, error) { 25 state := a.State 26 if state == "" { 27 state = "present" 28 } 29 30 if a.Cache { 31 home, err := goansible.HomeDir() 32 if err != nil { 33 return nil, err 34 } 35 36 checkFile := filepath.Join(home, ".goansible", "apt-cache-timestamp") 37 38 runUpdate := true 39 40 if a.CacheTime != "" { 41 fi, err := os.Stat(checkFile) 42 if err == nil { 43 dur, err := time.ParseDuration(a.CacheTime) 44 if err != nil { 45 return nil, fmt.Errorf("cache_time was not in the proper format") 46 } 47 48 runUpdate = time.Now().After(fi.ModTime().Add(dur)) 49 } 50 } 51 52 if runUpdate { 53 _, err := goansible.RunCommand(env, "apt-get", "update") 54 if err != nil { 55 return nil, err 56 } 57 ioutil.WriteFile(checkFile, []byte(``), 0666) 58 } 59 } 60 61 if a.Pkg == "" { 62 simp := goansible.NewResult(true) 63 simp.Add("cache", "updated") 64 65 return simp, nil 66 } 67 68 out, err := goansible.RunCommand(env, "apt-cache", "policy", a.Pkg) 69 if err != nil { 70 return nil, err 71 } 72 73 res := installed.FindSubmatch(out.Stdout) 74 if res == nil { 75 return nil, fmt.Errorf("No package '%s' available", a.Pkg) 76 } 77 78 curVer := string(res[1]) 79 if curVer == "(none)" { 80 curVer = "" 81 } 82 83 res = candidate.FindSubmatch(out.Stdout) 84 if res == nil { 85 return nil, fmt.Errorf("Error parsing apt-cache output") 86 } 87 88 canVer := string(res[1]) 89 90 if state == "absent" { 91 rd := goansible.ResultData{} 92 93 if curVer == "" { 94 return goansible.WrapResult(false, rd), nil 95 } 96 97 rd.Set("removed", curVer) 98 99 _, err = goansible.RunCommand(env, "apt-get", "remove", "-y", a.Pkg) 100 101 if err != nil { 102 return nil, err 103 } 104 105 return goansible.WrapResult(true, rd), nil 106 } 107 108 rd := goansible.ResultData{} 109 rd.Set("installed", curVer) 110 rd.Set("candidate", canVer) 111 112 if state == "present" && curVer == canVer { 113 return goansible.WrapResult(false, rd), nil 114 } 115 116 if a.Dry { 117 rd.Set("dryrun", true) 118 return goansible.WrapResult(true, rd), nil 119 } 120 121 e := append(os.Environ(), "DEBIAN_FRONTEND=noninteractive", "DEBIAN_PRIORITY=critical") 122 123 _, err = goansible.RunCommandInEnv(env, e, "apt-get", "install", "-y", a.Pkg) 124 if err != nil { 125 return nil, err 126 } 127 128 rd.Set("installed", canVer) 129 130 return goansible.WrapResult(true, rd), nil 131 } 132 133 func init() { 134 goansible.RegisterCommand("apt", &Apt{}) 135 }