Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Jenkins shared library should support monorepo - multi build / deploy #222

Closed
clemensutschig opened this issue Apr 2, 2020 · 10 comments · Fixed by #242
Closed

Jenkins shared library should support monorepo - multi build / deploy #222

clemensutschig opened this issue Apr 2, 2020 · 10 comments · Fixed by #242
Assignees
Labels
enhancement New feature or request

Comments

@clemensutschig
Copy link
Member

clemensutschig commented Apr 2, 2020

Is your feature request related to a problem? Please describe.
Today each repo is bound to a single component - that is set at the root of the shared lib componentId - and subsequently used in all stages, thru context.getComponentId() .

This is for the clean microservice architecture very useful, but less so in case there is more components in a repo (e.g. in case of a vendor supplied repo, that contains say an application and a database)

Describe the solution you'd like
The ability to override a component on a stage, e.g. stageBuildOpenShift(...., "myComponentId") so people can use multiple containers in one dc later .. (or multi dc) - see https://docs.openshift.com/container-platform/3.7/architecture/core_concepts/pods_and_services.html

Describe alternatives you've considered
copying shared lib code into the jenkins file (e.g. https://github.com/opendevstack/ods-quickstarters/blob/master/ds-ml-service/Jenkinsfile.template#L103-L135) - which is not good.

@metmajer @gerardcl @buegelbeatz

@clemensutschig clemensutschig added the enhancement New feature or request label Apr 2, 2020
@clemensutschig clemensutschig added this to To Do in OpenDevStack 3.0 via automation Apr 2, 2020
@metmajer
Copy link
Member

metmajer commented Apr 2, 2020

@clemensutschig Yes!!

@clemensutschig
Copy link
Member Author

@metmajer - I see this a ODS 3 features - for june (which would then support sockshop) ... thoughts?

@michaelsauter
Copy link
Member

Fully agreed, this will be great!

However, I am not sure we should put this into ODS 3 (June). I believe we have some groundwork to do:

  • What does that mean for the provisioning app (quickstarters)?
  • What is the relationship with the MRO? Right now we do not have a defined contract between the MRO and each component. I believe this to be crucial for something like this to work. This contract would be much easier to establish if the MRO were in the shared lib.
  • How does this affect other areas such as environment promotion, JUnit tests, SonarQube scanning, Snyk scanning, etc. There are lots of affected places. Right now I believe we first need to get the building blocks in shape (which I started in Extract stages into classes #221).
  • If we allow multi-deployment configs, maybe we should also allow multiple containers per pod? It's also not possible, and somewhat related. We don't have to do both at once, but it would be good to check if we can find a solution which fits both use cases.

My proposal would be to:

  • Get the groundwork done. This is on track for v3, but I really want to avoid building on top of moving, half-ready things.
  • After we have a solid framework in place, discuss how we want to approach it and have the time to think it through.
  • Roll this out with v4.

@clemensutschig
Copy link
Member Author

I would suggest, ability to build multiple, and deploy multiple - should be given for v3 ... the rest we can discuss :).

@clemensutschig
Copy link
Member Author

@buegelbeatz - we need your input here ... you are the mr multirepo :)

I could envision to provide a list of components to the shared lib config, rather than a singular. and we would execute for a first shot, the stages you provide for the contents of the list ... but I want to hear you :)

@gerardcl
Copy link
Member

gerardcl commented Apr 10, 2020

Hi! I like this and also find this as a missing piece on the ODS library side, so to be able to manage a monorepo project with different components, yes!
I have been thinking about this also many times and I see two sides (as also mentioned):

1 - to simply provide the functionality of building and rollingout one or many components from the ODS (jenkins shared) library by letting the developers extend the param componentId to an object/dict/map that maps componentId with its docker folder and then passed to BuildOpenShiftImageStage, then iterate (default could be as usual one single component map {'componentId': 'docker'}). Same applies for rollout stage.

2 - as mentioned, this should also be provided in the other stages provided by the library. So to be able to define one or many test results folders, sonarqube runs, snyk runs, ...
This also means being able to reuse/loop a stage with a different name so to assure that we do not see the typical NaN/NaN values on jenkins when reusing a stage...

Other thoughts, if many components in a monorepo, one might not always want to build and deploy everything, so maybe we shall detect or flag what to do in a per component basis...

What I have been also thinking sometimes is that we could split the methods a bit more like the build to openshift stage and offer these low level methods into the library in favour of enabling the users to customise if required, if not just use the high level methods already provided (which also make use of the exposed lower level methods). An example could be splitting the build to openshift method into labelling, building, ... and also expose them as library methods.

@clemensutschig
Copy link
Member Author

clemensutschig commented Apr 11, 2020

@gerardcl - I gave this some more thought .. and I think build / scan etc is really a nobrainer (assuming we go with a component list / map) .. deploy is going to be the interesting part ... I guess any of the n components will trigger a redeployment (assume 1 container / n pods)

I think this is also the default setup we would support ... @martsec - what is your usecase?

Update: I gave this some more thought over easter .. here is my proposal based on @gerardcl

  1. we create a quickstarter front / backend multi repo component that looks like this:
    1.1 multiple src & test dirs (e.g src/test-front/backend)
    1.2 2 docker context dirs (docker-front/backend)
    1.3 2 bc / imagestreams (component-id-front/backend) - that already point to the right docker contexts from 1.2
    1.4 1 dc (component-id) - referencing both images from 1.3 - so in this case one pod multiple containers
    1.5 1 sonarqube file
    1.6 x snyk files (@stitakis - what's the deal here, are they name fixed?)

  2. in the jenkinsFile in addition to componentId we add a new piece called ocpRepoAssembly

componentId : 'component-id'
ocpRepoAssembly : {
   buildconfigs : ['frontend', 'backend'],
   deploymentconfigs: ['component-id'],
}

The stages now know that this is a multirepo - and inside the stages instead of just building & deploying the standard one component .. it builds 2 components, based on ocpRepoAssembly /buildconfigs and deploy the one dc based on ocpRepoAssembly / deploymentconfigs.
Sonarqube would only apply to the whole project (which one could configure anyway in sonarqube.properties

There is also big impact to the mro shared lib - we have to return a better structure than today .. so I guess we'd add the above ids / configs to the artifactURIs, so instead of
context.addArtifactURI("OCP Build Id", buildId)

ocpRepoAssembly : {
   buildconfigs : ['frontend', 'backend'],
   builds : ['frontend' : {'buildId' : 'abc-1', 'imageId' : 'sha@....'}],
   deploymentconfigs: ['component-id'], 
   deployments : ['component-id' :  'abc-1']
}

Note: this has also massive impact to the mro promote to env feature ... which relies on the data passed in the artifactURIs map ..

  1. https://github.com/opendevstack/ods-mro-jenkins-shared-library/blob/master/src/org/ods/util/MROPipelineUtil.groovy#L130-L132
  2. https://github.com/opendevstack/ods-mro-jenkins-shared-library/blob/master/src/org/ods/util/MROPipelineUtil.groovy#L223-L229

@buegelbeatz / @martsec - would that make your usecases work?

@clemensutschig
Copy link
Member Author

clemensutschig commented Apr 12, 2020

The other option is a more building block- like lesign.. that is a simple param set (map) for build/deploy stage and a User that needs it just calls it multiple times.. underneath the shared lib would track those builds and deployments in a Structure like above.. this would for sure enable the data science case from @gerardcl

@clemensutschig clemensutschig self-assigned this Apr 13, 2020
@clemensutschig
Copy link
Member Author

clemensutschig commented Apr 13, 2020

@gerardcl - in the new world .. your ml quickstarter would look like this

    odsComponentStageScanWithSonar(context)
    stageBuild(context)
    stageLinter(context)

    odsComponentStageBuildOpenShiftImage (context, [ "componentId" : trainingComponentId])
    def trainingDeployInfo = odsComponentStageRolloutOpenShiftDeployment (context, [ "componentId" : trainingComponentId])
    stageUnitTestsTraining(context, trainingDeployInfo.podName)
    stageTraining(context, trainingDeployInfo.podName)
    stageIntegrationTestTraining(context, trainingDeployInfo.podName)

    odsComponentStageBuildOpenShiftImage (context, [ "componentId" : predictionComponentId])
    odsComponentStageRolloutOpenShiftDeployment (context, [ "componentId" : predictionComponentId])

@gerardcl
Copy link
Member

will take a look! as a first reading looks good!

OpenDevStack 3.0 automation moved this from To Do to Done Apr 20, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
No open projects
Development

Successfully merging a pull request may close this issue.

4 participants