Glance-v2-community-image-visibility-design

This is the design discussion for the full specification: https://wiki.openstack.org/wiki/Glance-v2-community-image-sharing

Values for 'visibility'
The image JSON schema will be changed so that the enum for 'visibility' is: [ 'public', 'private', 'shared', 'community' ]

Storage in the Database
'visibility' will be stored in the database in the images table with one of the values in the above enum. The default value is: 'private'

Note: the current DB schema has the 'is_public' column defined as a tinyint. Should we use tinyint values instead of strings for faster db queries? Do we rename the 'is_public' column to 'visibility' ?

Visibility Semantics
Here are the semantics for visibility:
 * 1) visibility is orthogonal to ownership
 * 2) semantics for each of the values
 * 3) * public: all users:
 * 4) ** have this image in default image-list
 * 5) ** can see image-detail for this image
 * 6) ** can boot from this image
 * 7) * private: users with tenantId == tenantId(owner) only:
 * 8) ** have this image in the default image-list
 * 9) ** see image-detail for this image
 * 10) ** can boot from this image
 * 11) * shared:
 * 12) ** users with tenantId == tenantId(owner)
 * 13) *** have this image in the default image-list
 * 14) *** see image-detail for this image
 * 15) *** can boot from this image
 * 16) ** users with tenantId in the member-list of the image
 * 17) *** can see image-detail for this image
 * 18) *** can boot from this image
 * 19) ** users with tenantId in the member-list with member_status == 'accepted'
 * 20) *** have this image in their default image-list
 * 21) * community:
 * 22) ** all users
 * 23) *** can see image-detail for this image
 * 24) *** can boot from this image
 * 25) ** users with tenantId in the member-list of the image with member_status == 'accepted'
 * 26) *** have this image in their default image-list
 * 27) NOTE: it's possible for an image to have 'visibility' == 'shared' but have an empty member-list

Changing Image Visibility

 * 1) changed by PATCH
 * 2) "publicizing" an image is protected by policy (default: admin-only operation)
 * 3) QUESTION: what about "un-publicizing"?  should this also be protected by policy, or just allow the owner to do it?

Transitions
NOTE: some transitions will delete all image members. Make sure the docs note this and suggest that the user get and save member list before changing image visibility.


 * 1) private → public
 * 2) * DELETE ALL MEMBERS ON IMAGE
 * 3) private → community
 * 4) * no change to image member-list
 * 5) private → shared
 * 6) * no change to image member-list
 * 7) public → private
 * 8) * (no members on image so nothing to do about members)
 * 9) public → community
 * 10) * (no members on image so nothing to do about members)
 * 11) public → shared
 * 12) * (no members on image so nothing to do about members)
 * 13) community → private
 * 14) * no change to image member-list
 * 15) * (list will have no effect but is saved in case image is later made 'shared' or 'community')
 * 16) community → public
 * 17) * DELETE ALL MEMBERS ON IMAGE
 * 18) community → shared
 * 19) * no change to image member-list
 * 20) shared → public
 * 21) * DELETE ALL MEMBERS ON IMAGE
 * 22) shared → private
 * 23) * no change to image member-list
 * 24) * (list will have no effect but is saved in case image is later made 'shared' or 'community')
 * 25) shared → community
 * 26) * no change to image member-list

Database Migration

 * 1) all rows with is_public == 1: visibility ← public
 * 2) for all unique image_id in image_members where deleted != 1: visibility ← shared
 * 3) for all rows with visibility == null: visibility ← private
 * 4) (there are no community images yet, so nothing to do for them)

Impact on v1

 * 1) If the 'visibility' of an image is 'public', then v1.is_public ← True, else v1.is_public ← False.
 * 2) the v1 image sharing code will need to be modified as follows:
 * 3) * in addition to adding the image member with status 'pending' (as done currently), will have to change the image's visibility ← shared
 * 4) ** note: I'm pretty sure that the v1 image list code treats 'pending' the same as 'accepted' for backward compatibility (there's no concept of member status in v1)
 * 5) * when a member is deleted, check if member-list has become empty; if so, change visibility ← private
 * 6) * v1 doesn't have the concept of a "community" image. Since is_public is False for all images with visibility != public, such images will be hidden from users.
 * 7) ** a user could use the v2 API to add themselves as the member of a community image ... I guess that's OK?

Open Questions

 * 1) Should "un-publicizing" an image be controlled by policy, or should the image owner always be able to do it?
 * 2) The visibility transitions to 'public' delete all image members ... is this desirable behavior?