You need Java and Maven
to build ModelMesh from source and etcd
to run the unit tests.
To build your custom modelmesh
container image and deploy it to a ModelMesh Serving installation on a Kubernetes cluster,
you need the docker
and
kubectl
CLIs.
On macOS
you can install the required CLIs with Homebrew:
- Java:
brew install java
- Maven:
brew install maven
- Etcd:
brew install etcd
- Docker:
brew install docker
- Kubectl:
brew install kubectl
The gRPC stubs like the ModelMeshGrpc
class have to be generated by the gRPC proto compiler from
the .proto
source files under src/main/proto
.
The generated sources should be created in the target directory target/generated-sources/protobuf/grpc-java
.
To generate the sources run either of the following commands:
mvn package -DskipTests
mvn install -DskipTests
If you are using an IDE like IntelliJ IDEA or Eclipse
to help with your code development you should set up source and target folders so that the IDE's compiler can find all
the source code including the generated sources (after running mvn install -DskipTests
).
For IntelliJ this can be done by going to File > Project Structure ... > Modules:
- Source Folders
- src/main/java
- src/main/proto
- target/generated-sources/protobuf/grpc-java (generated)
- target/generated-sources/protobuf/java (generated)
- Test Source Folders
- src/test/java
- target/generated-test-sources/protobuf/grpc-java (generated)
- target/generated-test-sources/protobuf/java (generated)
- Resource Folders
- src/main/resources
- Test Resource Folders
- src/test/resources
- Excluded Folders
- target
You may also want to increase your Java Heap size to at least 1.5 GB.
Note, before running the test cases, make sure you have etcd
installed (see #prerequisites):
$ etcd --version
etcd Version: 3.5.5
Git SHA: 19002cfc6
Go Version: go1.19.1
Go OS/Arch: darwin/amd64
You can either run all test suites at once. You can use the -q
flag to reduce noise:
mvn test -q
Or you can run individual test cases:
mvn test -Dtest=ModelMeshErrorPropagationTest
mvn test -Dtest=SidecarModelMeshTest,ModelMeshFailureExpiryTest
It can be handy to use grep
to reduce output noise:
mvn test -Dtest=SidecarModelMeshTest,ModelMeshFailureExpiryTest | \
grep -E " Running |\[ERROR\]|Failures|SUCCESS|Skipp|Total time|Finished"
[INFO] Running com.ibm.watson.modelmesh.ModelMeshFailureExpiryTest
[INFO] Tests run: 1, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 10.257 s - in com.ibm.watson.modelmesh.ModelMeshFailureExpiryTest
[INFO] Running com.ibm.watson.modelmesh.SidecarModelMeshTest
[INFO] Tests run: 3, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 17.302 s - in com.ibm.watson.modelmesh.SidecarModelMeshTest
[INFO] Tests run: 4, Failures: 0, Errors: 0, Skipped: 0
[INFO] BUILD SUCCESS
[INFO] Total time: 39.916 s
[INFO] Finished at: 2022-11-01T14:33:33-07:00
After testing your code changes locally, it's time to build a new modelmesh
container image. Replace the value of the
DOCKER_USER
environment variable to your DockerHub user ID and change the IMAGE_TAG
to something meaningful.
export DOCKER_USER="<your-docker-userid>"
export IMAGE_NAME="${DOCKER_USER}/modelmesh"
export IMAGE_TAG="dev"
export GIT_COMMIT=$(git rev-parse HEAD)
export BUILD_ID=$(date '+%Y%m%d')-$(git rev-parse HEAD | cut -c -5)
docker build -t ${IMAGE_NAME}:${IMAGE_TAG} \
--build-arg imageVersion=${IMAGE_TAG} \
--build-arg buildId=${BUILD_ID} \
--build-arg commitSha=${GIT_COMMIT} .
docker push ${IMAGE_NAME}:${IMAGE_TAG}
In order to test the code changes in an existing ModelMesh Serving deployment,
the newly built container image needs to be added to the model-serving-config
ConfigMap.
First, check if your ModelMesh Serving deployment already has an existing model-serving-config
ConfigMap:
kubectl get configmap
NAME DATA AGE
kube-root-ca.crt 1 4d2h
model-serving-config 1 4m14s
model-serving-config-defaults 1 4d2h
tc-config 2 4d2h
If the ConfigMap list contains model-serving-config
, save the contents of your existing configuration
in a local temp file:
mkdir -p temp
kubectl get configmap model-serving-config -o yaml > temp/model-serving-config.yaml
And add the modelMeshImage
property to the config.yaml
string property:
modelMeshImage:
name: <your-docker-userid>/modelmesh
tag: dev
Replace the <your-docker-userid>
placeholder with your Docker username/login.
The complete ConfigMap YAML file might look like this:
apiVersion: v1
kind: ConfigMap
metadata:
name: model-serving-config
namespace: modelmesh-serving
data:
config.yaml: |
podsPerRuntime: 1
restProxy:
enabled: true
scaleToZero:
enabled: false
gracePeriodSeconds: 5
modelMeshImage:
name: <your-docker-userid>/modelmesh
tag: dev
Apply the ConfigMap to your cluster:
kubectl apply -f temp/model-serving-config.yaml
If you are comfortable using vi, you can forgo creating a temp file and edit the ConfigMap directly in the terminal:
kubectl edit configmap model-serving-config
If you did not already have a model-serving-config
ConfigMap on your cluster, you can create one like this:
# export DOCKER_USER="<your-docker-userid>"
# export IMAGE_NAME="${DOCKER_USER}/modelmesh"
# export IMAGE_TAG="dev"
kubectl apply -f - <<EOF
---
apiVersion: v1
kind: ConfigMap
metadata:
name: model-serving-config
data:
config.yaml: |
modelMeshImage:
name: ${IMAGE_NAME}
tag: ${IMAGE_TAG}
EOF
The modelmesh-controller
watches the ConfigMap and responds to updates by automatically restarting the serving runtime
pods using the newly built modelmesh
container image.
You can check which container images are used by running the following command:
kubectl get pods -o jsonpath='{range .items[*]}{"\n"}{.metadata.name}{"\t"}{range .spec.containers[*]}{.image}{", "}{end}{end}' | sort | column -ts $'\t' | sed 's/, *$//g'
etcd-78ff7867d5-45svw quay.io/coreos/etcd:v3.5.4
minio-6ddbfc9665-gtf7x kserve/modelmesh-minio-examples:latest
modelmesh-controller-64f5c8d6d6-k6rzc kserve/modelmesh-controller:latest
modelmesh-serving-mlserver-1.x-84884c6849-s8dw6 kserve/rest-proxy:latest, seldonio/mlserver:1.3.2, kserve/modelmesh-runtime-adapter:latest, kserve/modelmesh:dev
modelmesh-serving-mlserver-1.x-84884c6849-xpdw4 kserve/rest-proxy:latest, seldonio/mlserver:1.3.2, kserve/modelmesh-runtime-adapter:latest, kserve/modelmesh:dev