Пример #1
0
// OpenResourceForUniter returns metadata about the resource and
// a reader for the resource. The resource is associated with
// the unit once the reader is completely exhausted.
func (st resourceState) OpenResourceForUniter(unit resource.Unit, name string) (resource.Resource, io.ReadCloser, error) {
	applicationID := unit.ApplicationName()

	pendingID, err := newPendingID()
	if err != nil {
		return resource.Resource{}, nil, errors.Trace(err)
	}

	resourceInfo, resourceReader, err := st.OpenResource(applicationID, name)
	if err != nil {
		return resource.Resource{}, nil, errors.Trace(err)
	}

	pending := resourceInfo // a copy
	pending.PendingID = pendingID

	if err := st.persist.SetUnitResourceProgress(unit.Name(), pending, 0); err != nil {
		resourceReader.Close()
		return resource.Resource{}, nil, errors.Trace(err)
	}

	resourceReader = &unitSetter{
		ReadCloser: resourceReader,
		persist:    st.persist,
		unit:       unit,
		pending:    pending,
		resource:   resourceInfo,
		clock:      clock.WallClock,
	}

	return resourceInfo, resourceReader, nil
}
Пример #2
0
// OpenResource returns metadata about the resource, and a reader for
// the resource.
func (st resourceState) OpenResource(unit resource.Unit, name string) (resource.Resource, io.ReadCloser, error) {
	serviceID := unit.ServiceName()

	id := newResourceID(serviceID, name)
	resourceInfo, storagePath, err := st.persist.GetResource(id)
	if err != nil {
		return resource.Resource{}, nil, errors.Annotate(err, "while getting resource info")
	}
	if resourceInfo.IsPlaceholder() {
		logger.Tracef("placeholder resource %q treated as not found", name)
		return resource.Resource{}, nil, errors.NotFoundf("resource %q", name)
	}

	resourceReader, resSize, err := st.storage.Get(storagePath)
	if err != nil {
		return resource.Resource{}, nil, errors.Annotate(err, "while retrieving resource data")
	}
	if resSize != resourceInfo.Size {
		msg := "storage returned a size (%d) which doesn't match resource metadata (%d)"
		return resource.Resource{}, nil, errors.Errorf(msg, resSize, resourceInfo.Size)
	}

	resourceReader = unitSetter{
		ReadCloser: resourceReader,
		persist:    st.persist,
		unit:       unit,
		resource:   resourceInfo,
	}

	return resourceInfo, resourceReader, nil
}