Search in sources :

Example 1 with PythonDep

use of io.hops.hopsworks.persistence.entity.python.PythonDep in project hopsworks by logicalclocks.

the class LibraryResource method install.

@ApiOperation(value = "Install a python library in the environment")
@POST
@Consumes(MediaType.APPLICATION_JSON)
@Produces(MediaType.APPLICATION_JSON)
@Path("{library}")
@AllowedProjectRoles({ AllowedProjectRoles.DATA_OWNER, AllowedProjectRoles.DATA_SCIENTIST })
@JWTRequired(acceptedTokens = { Audience.API }, allowedUserRoles = { "HOPS_ADMIN", "HOPS_USER" })
@ApiKeyRequired(acceptedScopes = { ApiScope.PYTHON }, allowedUserRoles = { "HOPS_ADMIN", "HOPS_USER" })
public Response install(LibrarySpecification librarySpecification, @PathParam("library") String library, @Context UriInfo uriInfo, @Context HttpServletRequest req, @Context SecurityContext sc) throws ServiceException, GenericException, PythonException, DatasetException {
    Users user = jwtHelper.getUserPrincipal(req);
    environmentController.checkCondaEnabled(project, pythonVersion, true);
    PackageSource packageSource = librarySpecification.getPackageSource();
    if (packageSource == null) {
        throw new PythonException(RESTCodes.PythonErrorCode.INSTALL_TYPE_NOT_SUPPORTED, Level.FINE);
    }
    switch(packageSource) {
        case PIP:
            validateLibrary(librarySpecification, library);
            librarySpecification.setChannelUrl("pypi");
            break;
        case CONDA:
            validateLibrary(librarySpecification, library);
            break;
        case EGG:
        case WHEEL:
        case REQUIREMENTS_TXT:
        case ENVIRONMENT_YAML:
            validateBundledDependency(user, librarySpecification);
            break;
        case GIT:
            validateGitURL(librarySpecification.getDependencyUrl());
            break;
        default:
            throw new PythonException(RESTCodes.PythonErrorCode.INSTALL_TYPE_NOT_SUPPORTED, Level.FINE);
    }
    environmentController.checkCondaEnvExists(project, user);
    PythonDep dep = libraryController.installLibrary(project, user, CondaInstallType.valueOf(packageSource.name().toUpperCase()), librarySpecification.getChannelUrl(), library, librarySpecification.getVersion(), librarySpecification.getDependencyUrl(), librarySpecification.getGitBackend(), librarySpecification.getGitApiKey());
    ResourceRequest resourceRequest = new ResourceRequest(ResourceRequest.Name.LIBRARIES);
    LibraryDTO libraryDTO = librariesBuilder.build(uriInfo, resourceRequest, dep, project);
    return Response.created(libraryDTO.getHref()).entity(libraryDTO).build();
}
Also used : PackageSource(io.hops.hopsworks.common.python.library.PackageSource) PythonDep(io.hops.hopsworks.persistence.entity.python.PythonDep) PythonException(io.hops.hopsworks.exceptions.PythonException) Users(io.hops.hopsworks.persistence.entity.user.Users) ResourceRequest(io.hops.hopsworks.common.api.ResourceRequest) Path(javax.ws.rs.Path) POST(javax.ws.rs.POST) Consumes(javax.ws.rs.Consumes) Produces(javax.ws.rs.Produces) JWTRequired(io.hops.hopsworks.jwt.annotation.JWTRequired) ApiOperation(io.swagger.annotations.ApiOperation) ApiKeyRequired(io.hops.hopsworks.api.filter.apiKey.ApiKeyRequired) AllowedProjectRoles(io.hops.hopsworks.api.filter.AllowedProjectRoles)

Example 2 with PythonDep

use of io.hops.hopsworks.persistence.entity.python.PythonDep in project hopsworks by logicalclocks.

the class LibraryResource method getByName.

@ApiOperation(value = "Get a python library installed in this environment", response = LibraryDTO.class)
@GET
@Path("{library}")
@Produces(MediaType.APPLICATION_JSON)
@AllowedProjectRoles({ AllowedProjectRoles.DATA_OWNER, AllowedProjectRoles.DATA_SCIENTIST })
@JWTRequired(acceptedTokens = { Audience.API }, allowedUserRoles = { "HOPS_ADMIN", "HOPS_USER" })
@ApiKeyRequired(acceptedScopes = { ApiScope.PYTHON }, allowedUserRoles = { "HOPS_ADMIN", "HOPS_USER" })
public Response getByName(@PathParam("library") String library, @BeanParam LibraryExpansionBeanParam expansions, @Context UriInfo uriInfo, @Context SecurityContext sc) throws PythonException {
    validatePattern(library);
    environmentController.checkCondaEnabled(project, pythonVersion, true);
    PythonDep dep = libraryController.getPythonDep(library, project);
    ResourceRequest resourceRequest = new ResourceRequest(ResourceRequest.Name.LIBRARIES);
    if (expansions != null) {
        resourceRequest.setExpansions(expansions.getResources());
    }
    LibraryDTO libraryDTO = librariesBuilder.buildItem(uriInfo, resourceRequest, dep, project);
    return Response.ok().entity(libraryDTO).build();
}
Also used : PythonDep(io.hops.hopsworks.persistence.entity.python.PythonDep) ResourceRequest(io.hops.hopsworks.common.api.ResourceRequest) Path(javax.ws.rs.Path) Produces(javax.ws.rs.Produces) GET(javax.ws.rs.GET) JWTRequired(io.hops.hopsworks.jwt.annotation.JWTRequired) ApiOperation(io.swagger.annotations.ApiOperation) ApiKeyRequired(io.hops.hopsworks.api.filter.apiKey.ApiKeyRequired) AllowedProjectRoles(io.hops.hopsworks.api.filter.AllowedProjectRoles)

Example 3 with PythonDep

use of io.hops.hopsworks.persistence.entity.python.PythonDep in project hopsworks by logicalclocks.

the class CommandsController method condaOp.

public PythonDep condaOp(CondaOp op, Users user, CondaInstallType installType, Project proj, String channelUrl, String lib, String version, String arg, GitBackend gitBackend, String apiKeyName) throws GenericException, ServiceException {
    if (Strings.isNullOrEmpty(version) && CondaOp.isLibraryOp(op)) {
        version = Settings.UNKNOWN_LIBRARY_VERSION;
    }
    // If there is an already ongoing command to uninstall the same library, allow the queuing of a new install op
    List<CondaStatus> statuses = new ArrayList<>();
    statuses.add(CondaStatus.NEW);
    statuses.add(CondaStatus.ONGOING);
    List<CondaCommands> uninstallCommands = condaCommandFacade.findByStatusAndCondaOpAndProject(statuses, CondaOp.UNINSTALL, proj);
    // Get current uninstall operations for this project
    List<CondaCommands> ongoingUninstall = uninstallCommands.stream().filter(c -> c.getLib().equalsIgnoreCase(lib) && c.getInstallType().equals(installType)).collect(Collectors.toList());
    // Get currently installed library with the same name and package manager if it exists
    Optional<PythonDep> installedDep = proj.getPythonDepCollection().stream().filter(d -> d.getDependency().equalsIgnoreCase(lib) && d.getInstallType().equals(installType)).findFirst();
    if (op == CondaOp.INSTALL && installedDep.isPresent() && ongoingUninstall.isEmpty()) {
        throw new ServiceException(RESTCodes.ServiceErrorCode.ANACONDA_DEP_INSTALL_FORBIDDEN, Level.FINE, "dep: " + lib);
    }
    PythonDep dep;
    try {
        // 1. test if anacondaRepoUrl exists. If not, add it.
        AnacondaRepo repo = libraryFacade.getRepo(channelUrl, true);
        // 2. Test if pythonDep exists. If not, add it.
        dep = libraryFacade.getOrCreateDep(repo, installType, lib, version, true, false);
        Collection<PythonDep> depsInProj = proj.getPythonDepCollection();
        // 3. Add the python library to the join table for the project
        if (op == CondaOp.INSTALL) {
            // if upgrade
            depsInProj.remove(dep);
            depsInProj.add(dep);
        }
        proj.setPythonDepCollection(depsInProj);
        projectFacade.update(proj);
        CondaCommands cc = new CondaCommands(user, op, CondaStatus.NEW, installType, proj, lib, version, channelUrl, new Date(), arg, null, false, gitBackend, apiKeyName);
        condaCommandFacade.save(cc);
    } catch (Exception ex) {
        throw new GenericException(RESTCodes.GenericErrorCode.UNKNOWN_ERROR, Level.SEVERE, "condaOp failed", ex.getMessage(), ex);
    }
    return dep;
}
Also used : ProjectFacade(io.hops.hopsworks.common.dao.project.ProjectFacade) CondaOp(io.hops.hopsworks.persistence.entity.python.CondaOp) Date(java.util.Date) CondaCommands(io.hops.hopsworks.persistence.entity.python.CondaCommands) LibraryFacade(io.hops.hopsworks.common.dao.python.LibraryFacade) Project(io.hops.hopsworks.persistence.entity.project.Project) CondaInstallType(io.hops.hopsworks.persistence.entity.python.CondaInstallType) ArrayList(java.util.ArrayList) Level(java.util.logging.Level) Strings(com.google.common.base.Strings) Settings(io.hops.hopsworks.common.util.Settings) TransactionAttributeType(javax.ejb.TransactionAttributeType) Matcher(java.util.regex.Matcher) TransactionAttribute(javax.ejb.TransactionAttribute) ProjectException(io.hops.hopsworks.exceptions.ProjectException) PythonDep(io.hops.hopsworks.persistence.entity.python.PythonDep) GitBackend(io.hops.hopsworks.persistence.entity.jupyter.config.GitBackend) EJB(javax.ejb.EJB) Stateless(javax.ejb.Stateless) CondaStatus(io.hops.hopsworks.persistence.entity.python.CondaStatus) Collection(java.util.Collection) RESTCodes(io.hops.hopsworks.restutils.RESTCodes) Logger(java.util.logging.Logger) AnacondaRepo(io.hops.hopsworks.persistence.entity.python.AnacondaRepo) Collectors(java.util.stream.Collectors) ServiceException(io.hops.hopsworks.exceptions.ServiceException) List(java.util.List) GenericException(io.hops.hopsworks.exceptions.GenericException) Optional(java.util.Optional) Pattern(java.util.regex.Pattern) CondaCommandFacade(io.hops.hopsworks.common.dao.python.CondaCommandFacade) Users(io.hops.hopsworks.persistence.entity.user.Users) AnacondaRepo(io.hops.hopsworks.persistence.entity.python.AnacondaRepo) CondaCommands(io.hops.hopsworks.persistence.entity.python.CondaCommands) ArrayList(java.util.ArrayList) GenericException(io.hops.hopsworks.exceptions.GenericException) CondaStatus(io.hops.hopsworks.persistence.entity.python.CondaStatus) Date(java.util.Date) ProjectException(io.hops.hopsworks.exceptions.ProjectException) ServiceException(io.hops.hopsworks.exceptions.ServiceException) GenericException(io.hops.hopsworks.exceptions.GenericException) ServiceException(io.hops.hopsworks.exceptions.ServiceException) PythonDep(io.hops.hopsworks.persistence.entity.python.PythonDep)

Example 4 with PythonDep

use of io.hops.hopsworks.persistence.entity.python.PythonDep in project hopsworks by logicalclocks.

the class EnvironmentController method updateInstalledDependencies.

public Project updateInstalledDependencies(Project project) throws ServiceException, IOException {
    try {
        String condaListOutput = libraryController.condaList(projectUtils.getFullDockerImageName(project, false));
        Collection<PythonDep> projectDeps = libraryController.parseCondaList(condaListOutput);
        projectDeps = libraryController.persistAndMarkImmutable(projectDeps);
        project = libraryController.syncProjectPythonDepsWithEnv(project, projectDeps);
        project = libraryController.addOngoingOperations(project);
        return project;
    } catch (ServiceDiscoveryException e) {
        throw new ServiceException(RESTCodes.ServiceErrorCode.SERVICE_DISCOVERY_ERROR, Level.SEVERE, null, e.getMessage(), e);
    }
}
Also used : ServiceException(io.hops.hopsworks.exceptions.ServiceException) PythonDep(io.hops.hopsworks.persistence.entity.python.PythonDep) ServiceDiscoveryException(com.logicalclocks.servicediscoverclient.exceptions.ServiceDiscoveryException)

Example 5 with PythonDep

use of io.hops.hopsworks.persistence.entity.python.PythonDep in project hopsworks by logicalclocks.

the class LibraryController method addOngoingOperations.

public Project addOngoingOperations(Project project) throws ServiceException {
    Collection<CondaCommands> commands = project.getCondaCommandsCollection();
    for (CondaCommands condaCommand : commands) {
        if (condaCommand.getInstallType().equals(CondaInstallType.ENVIRONMENT))
            continue;
        PythonDep pythonDep = new PythonDep();
        pythonDep.setDependency(condaCommand.getLib());
        pythonDep.setInstallType(condaCommand.getInstallType());
        pythonDep.setPreinstalled(false);
        AnacondaRepo repo = libraryFacade.getRepo(condaCommand.getChannelUrl(), false);
        pythonDep.setRepoUrl(repo);
        pythonDep.setVersion(condaCommand.getVersion());
        pythonDep = libraryFacade.getOrCreateDep(pythonDep);
        if (!project.getPythonDepCollection().contains(pythonDep)) {
            project.getPythonDepCollection().add(pythonDep);
        }
    }
    return projectFacade.update(project);
}
Also used : AnacondaRepo(io.hops.hopsworks.persistence.entity.python.AnacondaRepo) CondaCommands(io.hops.hopsworks.persistence.entity.python.CondaCommands) PythonDep(io.hops.hopsworks.persistence.entity.python.PythonDep)

Aggregations

PythonDep (io.hops.hopsworks.persistence.entity.python.PythonDep)12 ProjectException (io.hops.hopsworks.exceptions.ProjectException)3 Project (io.hops.hopsworks.persistence.entity.project.Project)3 AnacondaRepo (io.hops.hopsworks.persistence.entity.python.AnacondaRepo)3 CondaCommands (io.hops.hopsworks.persistence.entity.python.CondaCommands)3 ArrayList (java.util.ArrayList)3 AllowedProjectRoles (io.hops.hopsworks.api.filter.AllowedProjectRoles)2 ApiKeyRequired (io.hops.hopsworks.api.filter.apiKey.ApiKeyRequired)2 ResourceRequest (io.hops.hopsworks.common.api.ResourceRequest)2 ServiceException (io.hops.hopsworks.exceptions.ServiceException)2 JWTRequired (io.hops.hopsworks.jwt.annotation.JWTRequired)2 CondaInstallType (io.hops.hopsworks.persistence.entity.python.CondaInstallType)2 Users (io.hops.hopsworks.persistence.entity.user.Users)2 ApiOperation (io.swagger.annotations.ApiOperation)2 Path (javax.ws.rs.Path)2 Produces (javax.ws.rs.Produces)2 Strings (com.google.common.base.Strings)1 ServiceDiscoveryException (com.logicalclocks.servicediscoverclient.exceptions.ServiceDiscoveryException)1 ProjectFacade (io.hops.hopsworks.common.dao.project.ProjectFacade)1 CondaCommandFacade (io.hops.hopsworks.common.dao.python.CondaCommandFacade)1