initialise repo
[debian/orchestra.git] / src / submitjob / submitjob.go
1 // submitjob.go
2 //
3 // A sample Orchestra submission client.
4
5 package main
6
7 import (
8         "io"
9         "net"
10         "json"
11         "flag"
12         "fmt"
13         "os"
14 )
15
16 type JobRequest struct {
17         Op      string          `json:"op"`
18         Score   string          `json:"score"`
19         Players []string        `json:"players"`
20         Scope   string          `json:"scope"`
21         Params  map[string]string       `json:"params"`
22 }
23
24 var (
25         AllOf        = flag.Bool("all-of", false, "Send request to all named players")
26         AudienceSock = flag.String("audience-sock", "/var/spool/orchestra/conductor.sock", "Path for the audience submission socket")
27 )
28
29 func NewJobRequest() (jr *JobRequest) {
30         jr = new(JobRequest)
31         jr.Params = make(map[string]string)
32
33         return jr
34 }
35
36 func Usage() {
37         fmt.Fprintf(os.Stderr, "Usage:\n")
38         fmt.Fprintf(os.Stderr, "  %s [<options>] <score> <player1> [<player2>...] [! [<key1> <value1>]...]\n", os.Args[0])
39         flag.PrintDefaults()
40 }
41
42 func main() {
43         flag.Usage = Usage
44         flag.Parse()
45
46         args := flag.Args()
47
48         if len(args) < 2 {
49                 flag.Usage()
50                 os.Exit(1)
51         }
52
53         jr := NewJobRequest()
54         jr.Op = "queue"
55         jr.Score = args[0]
56         if *AllOf {
57                 jr.Scope = "all"
58         } else {
59                 jr.Scope = "one"
60         }
61
62         var k int
63         for k = 1; k < len(args); k++ {
64                 if args[k] == "!" {
65                         break;
66                 }
67                 insertionpoint := 0
68                 if nil == jr.Players {
69                         jr.Players = make([]string, 1)
70                 } else {
71                         insertionpoint = len(jr.Players)
72                         newplayers := make([]string, insertionpoint+1)
73                         copy(newplayers, jr.Players)
74                         jr.Players = newplayers
75                 }
76                 jr.Players[insertionpoint] = args[k]
77         }
78         if (k < len(args)) {
79                 // skip the !
80                 k++
81                 if (len(args) - (k))%2 != 0 {
82                         fmt.Fprintf(os.Stderr, "Error: Odd number of param arguments.\n")
83                         os.Exit(1)
84                 }
85                 for ; k < len(args); k+=2 {
86                         jr.Params[args[k]] = args[k+1]
87                 }
88         }
89         
90         raddr, err := net.ResolveUnixAddr("unix", *AudienceSock)
91         if err != nil {
92                 fmt.Fprintf(os.Stderr, "Failed to resolve sockaddr: %s\n", err)
93                 os.Exit(1)
94         }
95         conn, err := net.DialUnix("unix", nil, raddr)
96         if err != nil {
97                 fmt.Fprintf(os.Stderr, "Failed to connect to sockaddr: %s\n", err)
98                 os.Exit(1)
99         }
100
101         defer conn.Close()
102
103         conn.SetTimeout(0)
104
105         nc := net.Conn(conn)
106
107         r, _ := nc.(io.Reader)
108         w, _ := nc.(io.Writer)
109
110         dec := json.NewDecoder(r)
111         enc := json.NewEncoder(w)
112
113         // send the message
114         err = enc.Encode(jr)
115         if err != nil {
116                 fmt.Fprintf(os.Stderr, "Failed to marshal & send: %s\n", err)
117                 os.Exit(1)
118         }
119
120         response := new([2]interface{})
121         err = dec.Decode(response)
122         if err != nil {
123                 fmt.Fprintf(os.Stderr, "Error decoding response: %s\n", err)
124                 os.Exit(1)
125         }
126         // coerce field 0 back into a string.
127         rerr,ok := response[0].(string)
128         if ok {
129                 if rerr == "OK" {
130                         // all OK!  get the JobID
131                         jobid, _ := response[1].(float64)
132                         fmt.Printf("%d\n", uint64(jobid))
133                         os.Exit(0)
134                 } else {
135                         fmt.Fprintf(os.Stderr, "Server Error: %s\n", rerr)
136                         os.Exit(1)
137                 }
138         } else {
139                 fmt.Fprintf(os.Stderr, "Couldn't unmarshal response correctly.\n");
140                 os.Exit(1)
141         }
142 }