How to add/replace the module in Vagrant box (Docker image from Docker Hub)
- Natalia Zaitseva
- Viktor Soroka
Step-by-step guide
This instruction is based on modifications made for mod-notes module and pre-built testing-backend Vagrant box
Update the raml file
sample raml file#%RAML 0.8 title: Notes API baseUri: https://github.com/folio-org/mod-notes version: v1 documentation: - title: mod-notes API content: This documents the API calls that can be made to query and manage notes about all kind of objects schemas: - note.json: !include note.json - noteCollection: !include noteCollection.json - errors: !include raml-util/schemas/errors.schema - error.schema: !include raml-util/schemas/error.schema - parameters.schema: !include raml-util/schemas/parameters.schema - raml-util/schemas/metadata.schema: !include raml-util/schemas/metadata.schema traits: - validate: !include raml-util/traits/validation.raml - secured: !include raml-util/traits/auth.raml - language: !include raml-util/traits/language.raml - pageable: !include raml-util/traits/pageable.raml - searchable: !include raml-util/traits/searchable.raml resourceTypes: - collection: !include raml-util/rtypes/collection.raml - collection-item: !include raml-util/rtypes/item-collection.raml /notes: displayName: Notes description: Notes collection type: collection: schemaCollection: noteCollection schemaItem: note.json exampleCollection: !include examples/noteCollection.sample exampleItem: !include examples/note.sample post: is: [ validate ] get: is: [ searchable: {description: "with valid searchable fields: for example link = 1234", example: "link=/users/1234"}, pageable, validate ] responses: /_self: displayName: Notes created by current user type: collection: schemaCollection: noteCollection schemaItem: note.json exampleCollection: !include examples/noteCollection.sample exampleItem: !include examples/note.sample get: is: [ searchable: {description: "with valid searchable fields: for example link = 1234", example: "link=/users/1234"}, pageable, validate ] /{id}: displayName: Notes description: Get, Delete or Update a specific note type: collection-item: schema: note.json exampleItem: !include examples/note.sample get: is: [ validate ] responses: 400: description: "Bad request" body: text/plain: 401: description: "Not authorized to perform requested action" body: text/plain: put: is: [validate] responses: 400: description: "Bad request" body: text/plain: 401: description: "Not authorized to perform requested action" body: text/plain: delete: is: [ validate ] responses: 400: description: "Bad request" body: text/plain: 401: description: "Not authorized to perform requested action" body: text/plain: /natalia: get: responses: 200: body: text/plain: example: "OK" 400: description: "Bad request" body: text/plain: example: "Bad request"
Build the project
mvn clean install
- Update the code of the module to match the changes in raml file
Build the Docker image inside of the module
docker build -t <name> <path> where <path> - location of *-fat.jar file and Dockerfile
info
The command above will tag you image with default 'latest' tag.
To change it use
docker tag image <username>/<repository>:<tag>
example
docker tag d_notes
<username>/<repository>:testCheck local Docker images
docker images
Create an account in the Docker hub and then login in
docker login
Publish the image with following command
docker push username/repository:tag
After successful push you will be able to see following
Run Vagrant box
vagrant up vagrant ssh
Navigate to Vagrant shared folder and pull Docker image
cd /vagrant/.vagrant docker pull <user_name>/<repository> Example: docker pull b3946935/d_notes
Find the Container Id of the module you want to replace
Stop the Docker container
docker stop <container_id>
Publish the Module descriptor
http://localhost:9130/_/proxy/modules
sample Module descriptor{ "id": "mod-notes-2.1.1-SNAPSHOT", "name": "Notes", "requires": [ { "id": "users", "version": "14.0 15.0" }, { "id": "notify", "version": "1.1" } ], "provides": [ { "id": "notes", "version": "1.0", "handlers": [ { "methods": ["GET"], "pathPattern": "/notes", "permissionsRequired": ["notes.collection.get"], "permissionsDesired": ["notes.domain.*", "notes.domain.all"] }, { "methods": ["GET"], "pathPattern": "/notes/natalia" }, { "methods": ["POST"], "pathPattern": "/notes", "permissionsRequired": ["notes.item.post"], "permissionsDesired": ["notes.domain.*", "notes.domain.all"] }, { "methods": ["GET"], "pathPattern": "/notes/_self", "permissionsRequired": ["notes.collection.get"], "permissionsDesired": ["notes.domain.*", "notes.domain.all"] }, { "methods": ["GET"], "pathPattern": "/notes/{id}", "permissionsRequired": ["notes.item.get"], "permissionsDesired": ["notes.domain.*", "notes.domain.all"] }, { "methods": ["PUT"], "pathPattern": "/notes/{id}", "permissionsRequired": ["notes.item.put"], "permissionsDesired": ["notes.domain.*", "notes.domain.all"] }, { "methods": ["DELETE"], "pathPattern": "/notes/{id}", "permissionsRequired": ["notes.item.delete"], "permissionsDesired": ["notes.domain.*", "notes.domain.all"] } ] }, { "id": "_tenant", "version": "1.0", "interfaceType": "system", "handlers": [ { "methods": [ "POST" ], "pathPattern": "/_/tenant" }, { "methods": [ "DELETE" ], "pathPattern": "/_/tenant" } ] } ], "permissionSets": [ { "permissionName": "notes.collection.get", "displayName": "Notes - get notes collection", "description": "Get notes collection" }, { "permissionName": "notes.item.get", "displayName": "Notes - get individual note from storage", "description": "Get individual note" }, { "permissionName": "notes.item.post", "displayName": "Notes - create note", "description": "Create note" }, { "permissionName": "notes.item.put", "displayName": "Notes - modify note", "description": "Modify note" }, { "permissionName": "notes.item.delete", "displayName": "Notes - delete note", "description": "Delete note" }, { "permissionName": "notes.domain.all", "displayName": "Notes - allow access to all domains", "description": "All domains" }, { "permissionName": "notes.allops", "displayName": "Notes module - all CRUD permissions", "description": "Entire set of permissions needed to use the notes modules, but no domain permissions", "subPermissions": [ "notes.collection.get", "notes.item.get", "notes.item.post", "notes.item.put", "notes.item.delete" ], "visible": false }, { "permissionName": "notes.all", "displayName": "Notes module - all permissions and all domains", "description": "Entire set of permissions needed to use the notes modules on any domain", "subPermissions": [ "notes.allops", "notes.domain.all" ], "visible": false } ] }
Publish Deployments descriptor
http://localhost:9130/_/discovery/modules
The Deployment descriptor for Docker image is little different
{ "srvcId" : "mod-notes-2.1.1-SNAPSHOT", "nodeId" : "10.0.2.15", "descriptor" : { "dockerImage" : "b3946935/d_notes:latest", "dockerArgs" : { "HostConfig" : { "PortBindings": { "8081/tcp": [{ "HostPort": "%p" }] } } }, "env" : [ { "name" : "db.host", "value" : "10.0.2.15" }, { "name" : "db.port", "value" : "5432" }, { "name" : "db.username", "value" : "folio_admin" }, { "name" : "db.password", "value" : "folio_admin" }, { "name" : "db.database", "value" : "okapi_modules" }, { "name" : "db.maxPoolSize", "value" : "5" }, { "name" : "JAVA_OPTIONS", "value" : "-Xmx256m" } ], "dockerPull" : false } }
"nodeId" - IP of the running Vagrant instance. You may want to use the following command to find it.
vagrant ssh -c "ip address show eth0 | grep 'inet ' | sed -e 's/^.*inet //' -e 's/\/.*$//'"
"dockerImage" - the source, for docker images built locally use name used for 'docker build -t <name> <path>' command
Deployment descriptors of the modules included into Vagrant box are available in folder
/etc/folio/deployment-descriptors
Enable the module for the tenant
http://localhost:9130/_/proxy/tenants/diku/modules
Check the work of the new endpoint