Skip to content

Commit d19f055

Browse files
author
Alexander Indenbaum
committed
build: add build-time protobuf generation infrastructure
Signed-off-by: Alexander Indenbaum <[email protected]>
1 parent 1f2706f commit d19f055

File tree

4 files changed

+208
-5
lines changed

4 files changed

+208
-5
lines changed

Makefile

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -168,11 +168,15 @@ commitlint:
168168
@test $(REBASE) -eq 0 || git -c user.name=commitlint -c user.email=commitline@localhost rebase FETCH_HEAD
169169
commitlint --verbose --from $(GIT_SINCE)
170170

171-
.PHONY: cephcsi
172-
cephcsi: check-env
171+
.PHONY: cephcsi generate-proto
172+
cephcsi: check-env generate-proto
173173
if [ ! -d ./vendor ]; then (go mod tidy && go mod vendor); fi
174174
GOOS=linux go build $(GO_TAGS) -mod vendor -a -ldflags '$(LDFLAGS)' -o _output/cephcsi ./cmd/
175175

176+
generate-proto: check-env
177+
@echo "Generating protobuf stubs..."
178+
./scripts/generate-proto.sh
179+
176180
e2e.test: check-env
177181
cd e2e && go test $(GO_TAGS) -mod=vendor -c -o ../e2e.test ./
178182

@@ -217,6 +221,9 @@ containerized-build: TARGET = cephcsi
217221
containerized-build: .container-cmd .devel-container-id
218222
$(CONTAINER_CMD) run --rm -v $(CURDIR):/go/src/github.com/ceph/ceph-csi$(SELINUX_VOL_FLAG) $(CSI_IMAGE_NAME):devel make $(TARGET) CONTAINERIZED=yes
219223

224+
containerized-generate-proto: .container-cmd .devel-container-id
225+
$(CONTAINER_CMD) run --rm -v $(CURDIR):/go/src/github.com/ceph/ceph-csi$(SELINUX_VOL_FLAG) $(CSI_IMAGE_NAME):devel make generate-proto CONTAINERIZED=yes
226+
220227
containerized-test: TARGET = test
221228
containerized-test: REBASE ?= 0
222229
containerized-test: .container-cmd .test-container-id
@@ -272,6 +279,8 @@ clean:
272279
rm -f _output/cephcsi
273280
$(RM) scripts/golangci.yml
274281
$(RM) e2e.test
282+
rm -rf internal/proto/generated
283+
rm -f internal/proto/*.proto
275284
[ ! -f .devel-container-id ] || $(CONTAINER_CMD) rmi $(CSI_IMAGE_NAME):devel
276285
$(RM) .devel-container-id
277286
[ ! -f .test-container-id ] || $(CONTAINER_CMD) rmi $(CSI_IMAGE_NAME):test

deploy/cephcsi/image/Dockerfile

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@ RUN dnf -y install --nodocs \
4848
/usr/bin/cc \
4949
make \
5050
git \
51+
protobuf-compiler \
5152
&& dnf clean all \
5253
&& rm -rf /var/cache/yum \
5354
&& true
@@ -60,6 +61,9 @@ ENV GOROOT=${GOROOT} \
6061
ENV_CSI_IMAGE_NAME="${CSI_IMAGE_NAME}" \
6162
PATH="${GOROOT}/bin:${GOPATH}/bin:${PATH}"
6263

64+
# Install Go protobuf plugins
65+
RUN ${GOROOT}/bin/go install google.golang.org/protobuf/cmd/protoc-gen-go@latest \
66+
&& ${GOROOT}/bin/go install google.golang.org/grpc/cmd/protoc-gen-go-grpc@latest
6367

6468
WORKDIR ${SRC_DIR}
6569

scripts/Dockerfile.devel

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -29,19 +29,21 @@ RUN true \
2929

3030
RUN mkdir -p /etc/selinux && touch /etc/selinux/config
3131

32-
# other/conflicting versions of protobuf get installed as dependency
33-
RUN dnf -y remove protobuf
34-
3532
RUN dnf -y install \
3633
git \
3734
make \
3835
gcc \
3936
librados-devel \
4037
libcephfs-devel \
4138
librbd-devel \
39+
protobuf-compiler \
4240
&& dnf -y --nobest update \
4341
&& dnf clean all \
4442
&& rm -rf /var/cache/yum \
4543
&& true
4644

45+
# Install Go protobuf plugins
46+
RUN go install google.golang.org/protobuf/cmd/protoc-gen-go@latest \
47+
&& go install google.golang.org/grpc/cmd/protoc-gen-go-grpc@latest
48+
4749
WORKDIR "/go/src/github.com/ceph/ceph-csi"

scripts/generate-proto.sh

Lines changed: 188 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,188 @@
1+
#!/bin/bash
2+
3+
# Copyright 2025 The Ceph-CSI Authors.
4+
#
5+
# Licensed under the Apache License, Version 2.0 (the "License");
6+
# you may not use this file except in compliance with the License.
7+
# You may obtain a copy of the License at
8+
#
9+
# http://www.apache.org/licenses/LICENSE-2.0
10+
#
11+
# Unless required by applicable law or agreed to in writing, software
12+
# distributed under the License is distributed on an "AS IS" BASIS,
13+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
# See the License for the specific language governing permissions and
15+
# limitations under the License.
16+
17+
set -e
18+
19+
# Script to fetch protobuf files from ceph-nvmeof project and generate Go stubs using protoc.
20+
21+
# Configuration
22+
CEPH_NVMEOF_REPO="https://github.com/ceph/ceph-nvmeof"
23+
CEPH_NVMEOF_BRANCH="devel"
24+
PROTO_DIR="internal/proto"
25+
PROTO_FILES=(
26+
"control/proto/gateway.proto"
27+
# Add more proto files as needed
28+
)
29+
30+
# Logging functions (plain text, no color)
31+
log_info() {
32+
echo "[INFO] $1"
33+
}
34+
35+
log_warn() {
36+
echo "[WARN] $1"
37+
}
38+
39+
log_error() {
40+
echo "[ERROR] $1"
41+
}
42+
43+
# Check if protoc is installed
44+
check_protoc() {
45+
if ! command -v protoc &> /dev/null; then
46+
log_error "protoc is not installed. Please install Protocol Buffers compiler."
47+
log_info "Installation instructions:"
48+
log_info " Ubuntu/Debian: sudo apt-get install protobuf-compiler"
49+
log_info " CentOS/RHEL: sudo yum install protobuf"
50+
log_info " macOS: brew install protobuf"
51+
exit 1
52+
fi
53+
54+
# Check protoc version
55+
PROTOC_VERSION=$(protoc --version | cut -d' ' -f2)
56+
log_info "Using protoc version: $PROTOC_VERSION"
57+
}
58+
59+
# Check if go is installed
60+
check_go() {
61+
if ! command -v go &> /dev/null; then
62+
log_error "go is not installed. Please install Go."
63+
exit 1
64+
fi
65+
66+
GO_VERSION=$(go version | cut -d' ' -f3)
67+
log_info "Using Go version: $GO_VERSION"
68+
69+
# Add Go bin directory to PATH if not already there
70+
if [[ ":$PATH:" != *":$GOPATH/bin:"* ]]; then
71+
export PATH="$GOPATH/bin:$PATH"
72+
log_info "Added $GOPATH/bin to PATH"
73+
fi
74+
}
75+
76+
# Create proto directory
77+
create_proto_dir() {
78+
if [ ! -d "$PROTO_DIR" ]; then
79+
log_info "Creating proto directory: $PROTO_DIR"
80+
mkdir -p "$PROTO_DIR"
81+
fi
82+
}
83+
84+
# Fetch proto file from ceph-nvmeof repository
85+
fetch_proto_file() {
86+
local proto_file="$1"
87+
local local_path
88+
local_path="$PROTO_DIR/$(basename "$proto_file")"
89+
90+
log_info "Fetching $proto_file from $CEPH_NVMEOF_REPO..."
91+
92+
# Use the raw.githubusercontent.com URL directly
93+
local url="https://raw.githubusercontent.com/ceph/ceph-nvmeof/refs/heads/$CEPH_NVMEOF_BRANCH/$proto_file"
94+
95+
if curl -f -L -s -o "$local_path" "$url"; then
96+
log_info "Successfully fetched $proto_file"
97+
else
98+
log_error "Failed to fetch $proto_file from $url"
99+
return 1
100+
fi
101+
}
102+
103+
# Generate Go stubs from proto file
104+
generate_go_stubs() {
105+
local proto_file="$1"
106+
local local_path
107+
local_path="$PROTO_DIR/$(basename "$proto_file")"
108+
109+
if [ ! -f "$local_path" ]; then
110+
log_error "Proto file not found: $local_path"
111+
return 1
112+
fi
113+
114+
log_info "Generating Go stubs from $local_path..."
115+
116+
# Create output directory for generated files
117+
local output_dir="$PROTO_DIR/generated"
118+
mkdir -p "$output_dir"
119+
120+
# Add go_package option if not present
121+
if ! grep -q "go_package" "$local_path"; then
122+
log_info "Adding go_package option to $local_path"
123+
# Add go_package option after the syntax line
124+
sed -i '/^syntax = "proto3";$/a option go_package = "github.com/ceph/ceph-csi/internal/proto/generated/gateway";' "$local_path"
125+
fi
126+
127+
# Generate Go stubs
128+
if protoc \
129+
--experimental_allow_proto3_optional \
130+
--go_out="$output_dir" \
131+
--go_opt=paths=source_relative \
132+
--go-grpc_out="$output_dir" \
133+
--go-grpc_opt=paths=source_relative \
134+
--proto_path="$PROTO_DIR" \
135+
"$local_path"; then
136+
log_info "Successfully generated Go stubs for $proto_file"
137+
else
138+
log_error "Failed to generate Go stubs for $proto_file"
139+
return 1
140+
fi
141+
}
142+
143+
# Clean up old generated files
144+
cleanup_old_files() {
145+
local output_dir="$PROTO_DIR/generated"
146+
if [ -d "$output_dir" ]; then
147+
log_info "Cleaning up old generated files..."
148+
rm -rf "$output_dir"
149+
fi
150+
}
151+
152+
# Main function
153+
main() {
154+
log_info "Starting protobuf generation process..."
155+
156+
# Check prerequisites
157+
check_protoc
158+
check_go
159+
160+
# Create proto directory
161+
create_proto_dir
162+
163+
# Clean up old files
164+
cleanup_old_files
165+
166+
# Process each proto file
167+
for proto_file in "${PROTO_FILES[@]}"; do
168+
log_info "Processing $proto_file..."
169+
170+
if fetch_proto_file "$proto_file"; then
171+
if generate_go_stubs "$proto_file"; then
172+
log_info "Successfully processed $proto_file"
173+
else
174+
log_error "Failed to generate stubs for $proto_file"
175+
exit 1
176+
fi
177+
else
178+
log_error "Failed to fetch $proto_file"
179+
exit 1
180+
fi
181+
done
182+
183+
log_info "Protobuf generation completed successfully!"
184+
log_info "Generated files are available in: $PROTO_DIR/generated"
185+
}
186+
187+
# Run main function
188+
main "$@"

0 commit comments

Comments
 (0)