func appIconGet(c *Command, r *http.Request) Response { vars := muxVars(r) name := vars["name"] origin := vars["origin"] lock, err := lockfile.Lock(dirs.SnapLockFile, true) if err != nil { return InternalError(err, "Unable to acquire lock") } defer lock.Unlock() bag := lightweight.PartBagByName(name, origin) if bag == nil || len(bag.Versions) == 0 { return NotFound } part := bag.LoadBest() if part == nil { return NotFound } path := filepath.Clean(part.Icon()) if !strings.HasPrefix(path, dirs.SnapAppsDir) && !strings.HasPrefix(path, dirs.SnapOemDir) { return BadRequest } return FileResponse(path) }
func getPackageInfo(c *Command, r *http.Request) Response { vars := muxVars(r) name := vars["name"] origin := vars["origin"] repo := newRemoteRepo() var part snappy.Part if parts, _ := repo.Details(name, origin); len(parts) > 0 { part = parts[0] } bag := lightweight.PartBagByName(name, origin) if bag == nil && part == nil { return NotFound } route := c.d.router.Get(c.Path) if route == nil { return InternalError(nil, "router can't find route for package %s.%s", name, origin) } url, err := route.URL("name", name, "origin", origin) if err != nil { return InternalError(err, "route can't build URL for package %s.%s: %v", name, origin, err) } result := webify(bag.Map(part), url.String()) return SyncResponse(result) }
func packageConfig(c *Command, r *http.Request) Response { vars := muxVars(r) name := vars["name"] origin := vars["origin"] if name == "" || origin == "" { return BadRequest(nil, "missing name or origin") } pkgName := name + "." + origin lock, err := lockfile.Lock(dirs.SnapLockFile, true) if err != nil { return InternalError(err, "Unable to acquire lock") } defer lock.Unlock() bag := lightweight.PartBagByName(name, origin) if bag == nil { return NotFound } idx := bag.ActiveIndex() if idx < 0 { return BadRequest } part, err := bag.Load(idx) if err != nil { return InternalError(err, "unable to get load active package: %v", err) } bs, err := ioutil.ReadAll(r.Body) if err != nil { return BadRequest(err, "reading config request body gave %v", err) } config, err := part.Config(bs) if err != nil { return InternalError(err, "unable to retrieve config for %s: %v", pkgName, err) } return SyncResponse(config) }
func appIconGet(c *Command, r *http.Request) Response { vars := muxVars(r) name := vars["name"] origin := vars["origin"] bag := lightweight.PartBagByName(name, origin) if bag == nil || len(bag.Versions) == 0 { return NotFound } part := bag.LoadBest() if part == nil { return NotFound } path := filepath.Clean(part.Icon()) if !strings.HasPrefix(path, dirs.SnapAppsDir) && !strings.HasPrefix(path, dirs.SnapOemDir) { return BadRequest } return FileResponse(path) }
func packageService(c *Command, r *http.Request) Response { route := c.d.router.Get(operationCmd.Path) if route == nil { return InternalError(nil, "router can't find route for operation") } vars := muxVars(r) name := vars["name"] origin := vars["origin"] if name == "" || origin == "" { return BadRequest(nil, "missing name or origin") } svcName := vars["service"] pkgName := name + "." + origin action := "status" if r.Method != "GET" { decoder := json.NewDecoder(r.Body) var cmd map[string]string if err := decoder.Decode(&cmd); err != nil { return BadRequest(err, "can't decode request body into service command: %v", err) } action = cmd["action"] } switch action { case "status", "start", "stop", "restart", "enable", "disable": // ok default: return BadRequest(nil, "unknown action %s", action) } bag := lightweight.PartBagByName(name, origin) idx := bag.ActiveIndex() if idx < 0 { return NotFound } ipart, err := bag.Load(idx) if err != nil { return InternalError(err, "unable to get load active package: %v", err) } part, ok := ipart.(*snappy.SnapPart) if !ok { return InternalError(nil, "active package is not a *snappy.SnapPart: %T", ipart) } svcs := part.ServiceYamls() if len(svcs) == 0 { return NotFound(nil, "package %q has no services", pkgName) } svcmap := make(map[string]*svcDesc, len(svcs)) for i := range svcs { svcmap[svcs[i].Name] = &svcDesc{Spec: &svcs[i], Op: action} } if svcName != "" && svcmap[svcName] == nil { return NotFound(nil, "package %q has no service %q", pkgName, svcName) } // note findServices takes the *bare* name actor, err := findServices(name, svcName, &progress.NullProgress{}) if err != nil { return InternalError(err, "no services for %q [%q] found: %v", pkgName, svcName, err) } f := func() interface{} { status, err := actor.ServiceStatus() if err != nil { logger.Noticef("unable to get status for %q [%q]: %v", pkgName, svcName, err) return err } for i := range status { if desc, ok := svcmap[status[i].ServiceName]; ok { desc.Status = status[i] } else { // shouldn't really happen, but can't hurt svcmap[status[i].ServiceName] = &svcDesc{Status: status[i]} } } if svcName == "" { return svcmap } return svcmap[svcName] } if action == "status" { return SyncResponse(f()) } return AsyncResponse(c.d.AddTask(func() interface{} { switch action { case "start": err = actor.Start() case "stop": err = actor.Stop() case "enable": err = actor.Enable() case "disable": err = actor.Disable() case "restart": err = actor.Restart() } if err != nil { logger.Noticef("unable to %s %q [%q]: %v\n", action, pkgName, svcName, err) return err } return f() }).Map(route)) }