Source code for subuserlib.classes.imageSource

# -*- coding: utf-8 -*-

"""
Images in subuser are built from ImageSource objects.
"""

#external imports
import os
import uuid
#internal imports
from subuserlib.classes.userOwnedObject import UserOwnedObject
from subuserlib.classes.describable import Describable
import subuserlib.permissions
import subuserlib.docker
import subuserlib.classes.docker.dockerDaemon as dockerDaemon
import subuserlib.classes.exceptions as exceptions
import subuserlib.print

[docs]class ImageSource(UserOwnedObject,Describable): def __init__(self,user,repo,name,explicitConfig=None): self.__name = name self.__repo = repo self.__permissions = None self.__explicitConfig = explicitConfig UserOwnedObject.__init__(self,user) def __hash__(self): return hash(self.getIdentifier())
[docs] def getName(self): return self.__name
[docs] def getIdentifier(self): """ Return a standard human readable identifier for an ImageSource. """ return self.getName() + "@" + self.getRepository().getDisplayName()
[docs] def getDockerImageTag(self): longTag = "subuser-" + self.getUser().getEndUser().name + "-" + self.getIdentifier() return subuserlib.docker.buildImageTag(longTag,self.getHash())
[docs] def getRepository(self): """ Get the repository where this ImageSource resides. """ return self.__repo
[docs] def getSubusers(self): """ Get a list of subusers that were built from this ImageSource. """ subusers = [] for subuser in self.getUser().getRegistry().getSubusers(): if subuser.getImageSource()==self: subusers.append(subuser) return subusers
[docs] def getImageDir(self): if self.__explicitConfig: return self.__explicitConfig["build-context"] imageDir = os.path.join(self.getRelativeSourceDir(),"image") # If the image dir does not exist, # Look for the old, deprecated, docker-image dir if not self.getRepository().getFileStructure().exists(imageDir): imageDir = os.path.join(self.getRelativeSourceDir(),"docker-image") if not self.getRepository().getFileStructure().exists(imageDir): raise exceptions.ImageBuildException("Image source "+self.getIdentifier()+ " does not have an image dir with sources from which to build.") return imageDir
[docs] def getSourceDir(self): return os.path.join(self.getRepository().getImageSourcesDir(),self.getName())
[docs] def getRelativeSourceDir(self): return os.path.join(self.getRepository().getRelativeImageSourcesDir(),self.getName())
[docs] def getLatestInstalledImage(self): """ Get the most up-to-date InstalledImage based on this ImageSource. Returns None if no images have been installed from this ImageSource. """ imageCreationDateTimeBestSoFar='' mostUpToDateImage = None for installedImage in self.getInstalledImages(): thisImagesCreationDateTime = installedImage.getCreationDateTime() if thisImagesCreationDateTime > imageCreationDateTimeBestSoFar: mostUpToDateImage = installedImage imageCreationDateTimeBestSoFar = thisImagesCreationDateTime return mostUpToDateImage
[docs] def getInstalledImages(self): """ Return the installed images which are based on this image. """ installedImagesBasedOnThisImageSource = [] for _,installedImage in self.getUser().getInstalledImages().items(): if installedImage.getImageSourceName() == self.getName() and installedImage.getSourceRepoId() == self.getRepository().getName(): installedImagesBasedOnThisImageSource.append(installedImage) return installedImagesBasedOnThisImageSource
[docs] def getPermissionsFilePath(self): relativePath = self.getRelativePermissionsFilePath() return os.path.join(self.getRepository().getRepoPath(),relativePath)
[docs] def getRelativePermissionsFilePath(self): if self.__explicitConfig is not None: return self.__explicitConfig["permissions-file"] if "dependent" in self.getRelativeSourceDir(): raise Exception(str(self.__explicitConfig)+"\n"+self.getName()+str(self.getRepository().keys())) return os.path.join(self.getRelativeSourceDir(),"permissions.json")
[docs] def getPermissions(self): if not self.__permissions: permissionsString = self.getRepository().getFileStructure().read(self.getRelativePermissionsFilePath()) initialPermissions = subuserlib.permissions.load(permissionsString=permissionsString) self.__permissions = subuserlib.classes.permissions.Permissions(self.getUser(),initialPermissions,writePath=self.getPermissionsFilePath()) return self.__permissions
[docs] def describe(self): """ Describe this ImageSource including it's default permissions. Prints to standard output. """ subuserlib.print.printWithoutCrashing(self.getIdentifier()) self.getPermissions().describe()
[docs] def build(self,parent,useCache=False): imageFileType = self.getImageFileType() if imageFileType == "Dockerfile": dockerfileContents = self.getImageFileContents() elif imageFileType == "SubuserImagefile": subuserImagefileContents = self.getImageFileContents() dockerfileContents = "" for line in subuserImagefileContents.split("\n"): if line.startswith("FROM-SUBUSER-IMAGE"): dockerfileContents = "FROM " + parent + "\n" else: dockerfileContents += line + "\n" imageId = self.getUser().getDockerDaemon().build(relativeBuildContextPath=self.getImageDir(),repositoryFileStructure=self.getRepository().getFileStructure(),rm=True,dockerfile=dockerfileContents,useCache=useCache) subuserSetupDockerFile = "" subuserSetupDockerFile += "FROM "+imageId+"\n" subuserSetupDockerFile += "RUN mkdir -p /subuser ; echo "+str(uuid.uuid4())+" > /subuser/uuid\n" # This ensures that all images have unique Ids. Even images that are otherwise the same. return self.getUser().getDockerDaemon().build(dockerfile=subuserSetupDockerFile,tag=self.getDockerImageTag(),useCache=False)
[docs] def getImageFile(self): if self.__explicitConfig: return self.__explicitConfig["image-file"] dockerfilePath = os.path.join(self.getImageDir(),"Dockerfile") if self.getRepository().getFileStructure().exists(dockerfilePath): return dockerfilePath subuserImagefilePath = os.path.join(self.getImageDir(),"SubuserImagefile") if self.getRepository().getFileStructure().exists(subuserImagefilePath): return subuserImagefilePath
[docs] def getImageFileType(self): return os.path.basename(self.getImageFile())
[docs] def getImageFileContents(self): return self.getRepository().getFileStructure().read(self.getImageFile())
[docs] def getDependency(self): """ Returns the dependency of this ImageSource as a ImageSource. Or None if there is no dependency. """ if not self.getImageFileType() == "SubuserImagefile": return None subuserImagefileContents = self.getImageFileContents() lineNumber=0 for line in subuserImagefileContents.split("\n"): if line.startswith("FROM-SUBUSER-IMAGE"): try: import subuserlib.resolve imageURI = line.split(" ")[1] return subuserlib.resolve.resolveImageSource(self.getUser(),imageURI,contextRepository=self.getRepository(),allowLocalRepositories=False) #TODO, ImageSource names with spaces or other funny characters... except IndexError: raise exceptions.ImageBuildException("Syntax error in SubuserImagefile one line "+str(lineNumber)+":\n"+line) except KeyError: raise exceptions.ImageBuildException("Error in "+self.getName()+"'s SubuserImagefile on line "+str(lineNumber)+"\n Subuser image does not exist: \""+imageURI+"\"") lineNumber+=1 return None
[docs] def getHash(self): """ Return the hash of the ``image`` directory. """ return self.getRepository().getFileStructure().hash(self.getImageDir())