示例#1
0
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)
}
示例#2
0
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)
}
示例#3
0
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)
}
示例#4
0
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)
}
示例#5
0
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))
}