forked from snapcore/snapd
/
packages.go
150 lines (128 loc) · 4.05 KB
/
packages.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
// -*- Mode: Go; indent-tabs-mode: t -*-
/*
* Copyright (C) 2015-2016 Canonical Ltd
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 3 as
* published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
package client
import (
"fmt"
"net/url"
"time"
"github.com/snapcore/snapd/snap"
)
// Snap holds the data for a snap as obtained from snapd.
type Snap struct {
ID string `json:"id"`
Summary string `json:"summary"`
Description string `json:"description"`
DownloadSize int64 `json:"download-size"`
Icon string `json:"icon"`
InstalledSize int64 `json:"installed-size"`
InstallDate time.Time `json:"install-date"`
Name string `json:"name"`
Developer string `json:"developer"`
Status string `json:"status"`
Type string `json:"type"`
Version string `json:"version"`
Channel string `json:"channel"`
Revision snap.Revision `json:"revision"`
Confinement string `json:"confinement"`
Private bool `json:"private"`
DevMode bool `json:"devmode"`
TryMode bool `json:"trymode"`
Apps []AppInfo `json:"apps"`
Broken string `json:"broken"`
Prices map[string]float64 `json:"prices"`
}
type AppInfo struct {
Name string `json:"name"`
}
// Statuses and types a snap may have.
const (
StatusAvailable = "available"
StatusInstalled = "installed"
StatusActive = "active"
StatusRemoved = "removed"
TypeApp = "app"
TypeKernel = "kernel"
TypeGadget = "gadget"
TypeOS = "os"
StrictConfinement = "strict"
DevmodeConfinement = "devmode"
)
type ResultInfo struct {
SuggestedCurrency string `json:"suggested-currency"`
}
// FindOptions supports exactly one of the following options:
// - Refresh: only return snaps that are refreshable
// - Query: only return snaps that match the query string
type FindOptions struct {
Refresh bool
Query string
}
// List returns the list of all snaps installed on the system
// with names in the given list; if the list is empty, all snaps.
func (client *Client) List(names []string) ([]*Snap, error) {
snaps, _, err := client.snapsFromPath("/v2/snaps", nil)
if err != nil {
return nil, err
}
if len(names) == 0 {
return snaps, nil
}
wanted := make(map[string]bool, len(names))
for _, name := range names {
wanted[name] = true
}
var result []*Snap
for _, snap := range snaps {
if wanted[snap.Name] {
result = append(result, snap)
}
}
return result, nil
}
// Find returns a list of snaps available for install from the
// store for this system and that match the query
func (client *Client) Find(opts *FindOptions) ([]*Snap, *ResultInfo, error) {
if opts == nil {
opts = &FindOptions{}
}
q := url.Values{}
q.Set("q", opts.Query)
if opts.Refresh {
q.Set("select", "refresh")
}
return client.snapsFromPath("/v2/find", q)
}
func (client *Client) snapsFromPath(path string, query url.Values) ([]*Snap, *ResultInfo, error) {
var snaps []*Snap
ri, err := client.doSync("GET", path, query, nil, nil, &snaps)
if err != nil {
return nil, nil, fmt.Errorf("cannot list snaps: %s", err)
}
return snaps, ri, nil
}
// Snap returns the most recently published revision of the snap with the
// provided name.
func (client *Client) Snap(name string) (*Snap, *ResultInfo, error) {
var snap *Snap
path := fmt.Sprintf("/v2/snaps/%s", name)
ri, err := client.doSync("GET", path, nil, nil, nil, &snap)
if err != nil {
return nil, nil, fmt.Errorf("cannot retrieve snap %q: %s", name, err)
}
return snap, ri, nil
}