package common import ( "encoding/xml" "fmt" "io" "log" "net/http" "net/url" ) type ObsClient struct { baseUrl *url.URL client *http.Client user, password string cookie string } func NewObsClient(host, username, password string) (*ObsClient, error) { baseUrl, err := url.Parse("https://" + host) if err != nil { return nil, err } return &ObsClient{ baseUrl: baseUrl, client: &http.Client{}, user: username, password: password, }, nil } type RepositoryMeta struct { Name string `xml:"name,attr"` Arch []string `xml:"arch"` Path []struct { XMLName xml.Name `xml:"path"` Project string `xml:"project,attr"` Repository string `xml:"repository,attr"` } } type ProjectMeta struct { XMLName xml.Name `xml:"project"` Name string `xml:"name,attr"` Title string `xml:"title"` Description string `xml:"description"` ScmSync string `xml:"xmlsync"` Repositories []Repository `xml:"repository"` } func parseProjectMeta(data []byte) (*ProjectMeta, error) { var meta ProjectMeta err := xml.Unmarshal(data, &meta) if err != nil { return nil, err } return &meta, nil } func (c *ObsClient) GetProjectMeta(project string) (*ProjectMeta, error) { req, err := http.NewRequest("GET", c.baseUrl.JoinPath("source", project, "_meta").String(), nil) if err != nil { return nil, err } req.SetBasicAuth(c.user, c.password) res, err := c.client.Do(req) if err != nil { return nil, err } switch res.StatusCode { case 200: break case 404: return nil, nil default: return nil, fmt.Errorf("Unexpected return code: %d", res.StatusCode) } data, err := io.ReadAll(res.Body) if err != nil { return nil, err } return parseProjectMeta(data) } func (c *ObsClient) DeleteProject(project string) error { req, err := http.NewRequest("DELETE", c.baseUrl.JoinPath("source", project).String(), nil) if err != nil { return err } req.SetBasicAuth(c.user, c.password) res, err := c.client.Do(req) if err != nil { return err } if res.StatusCode != 200 { return fmt.Errorf("Unexpected return code: %d", res.StatusCode) } return nil } type BuildStatus struct { Package string `xml:"package,attr"` Code string `xml:"code,attr"` Details string `xml:"details"` } type BuildResult struct { Project string `xml:"project,attr"` Repository string `xml:"repository,attr"` Arch string `xml:"arch,attr"` Code string `xml:"code,attr"` Status []BuildStatus `xml:"status"` Binaries []BinaryList `xml:"binarylist"` } type Binary struct { Size uint64 `xml:"size,attr"` Filename string `xml:"filename,attr"` Mtime uint64 `xml:"mtime,attr"` } type BinaryList struct { Package string `xml:"package,attr"` Binary []Binary `xml:"binary"` } type BuildResultList struct { XMLName xml.Name `xml:"resultlist"` Result []BuildResult `xml:"result"` } func parseBuildResults(data []byte) (*BuildResultList, error) { result := BuildResultList{} err := xml.Unmarshal(data, &result) if err != nil { return nil, err } return &result, nil } func (c *ObsClient) BuildStatus(project string) (*BuildResultList, error) { u := c.baseUrl.JoinPath("build", project, "_result") query := u.Query() query.Add("view", "status") query.Add("view", "binarylist") query.Add("multibuild", "1") u.RawQuery = query.Encode() req, err := http.NewRequest("GET", u.String(), nil) log.Print(u.String()) if err != nil { return nil, err } req.SetBasicAuth(c.user, c.password) res, err := c.client.Do(req) if err != nil { return nil, err } if res.StatusCode != 200 { return nil, fmt.Errorf("Unexpected return code: %d", res.StatusCode) } data, err := io.ReadAll(res.Body) if err != nil { return nil, err } return parseBuildResults(data) }