Skip to content

Commit

Permalink
chore: use podman-compose for dev environment
Browse files Browse the repository at this point in the history
  • Loading branch information
ShimShtein authored and pvoborni committed Nov 10, 2023
1 parent 136e9c8 commit b50fe0e
Show file tree
Hide file tree
Showing 16 changed files with 345 additions and 279 deletions.
12 changes: 2 additions & 10 deletions .devcontainer/Dockerfile
Original file line number Diff line number Diff line change
@@ -1,11 +1,3 @@
FROM registry.access.redhat.com/ubi7
FROM registry.access.redhat.com/ubi7/go-toolset:1.19

RUN yum install go-toolset-1.19 git make curl gzip tar --enablerepo=rhel-7-server-devtools-rpms -y

COPY ./entrypoint.sh /usr/bin/
RUN chmod +x /usr/bin/entrypoint.sh

COPY ./enable_go_scl.sh /etc/profile.d/
RUN chmod +x /etc/profile.d/enable_go_scl.sh

ENTRYPOINT ["entrypoint.sh"]
ENV IS_IN_CONTAINER=true
19 changes: 19 additions & 0 deletions .devcontainer/commands/prepare_containers.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
#!/bin/bash

pushd $(dirname "$0")/..
DEVCONTAINER_PATH=$(pwd)
popd

LOCAL_COMPOSE_FILE=$DEVCONTAINER_PATH/docker-compose.local.yml

if [ ! -f "$LOCAL_COMPOSE_FILE" ]; then
cat >"$LOCAL_COMPOSE_FILE" <<EOF
version: '3'
services:
host-metering:
build:
context: ${DEVCONTAINER_PATH}
command: /bin/sh -c "while sleep 1000; do :; done"
EOF
fi
23 changes: 16 additions & 7 deletions .devcontainer/devcontainer.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,15 @@
"name": "Go",
// Or use a Dockerfile or Docker Compose file. More info: https://containers.dev/guide/dockerfile
// "image": "mcr.microsoft.com/devcontainers/go:1.19",
"build": {
"dockerfile": "Dockerfile"
},

"workspaceFolder": "/workspace/host-metering",

// to set the local folder prepare_containers script should run first.
// "initializeCommand": "${localWorkspaceFolder}/.devcontainer/commands/prepare_containers.sh",

"dockerComposeFile" : ["./docker-compose.yml", "./docker-compose.local.yml"],
"service" : "host-metering",
"shutdownAction" : "stopCompose",

// Features to add to the dev container. More info: https://containers.dev/features.
"features": {
Expand Down Expand Up @@ -34,8 +40,11 @@
"HOME": "/home",
"WORKDIR": "/workspaces/${localWorkspaceFolderBasename}"
},
"workspaceMount": "",
"runArgs": [
"--volume=${localWorkspaceFolder}:/workspaces/${localWorkspaceFolderBasename}:Z"
]
"customizations": {
"vscode": {
"extensions": [
"golang.go"
]
}
}
}
22 changes: 22 additions & 0 deletions .devcontainer/docker-compose.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
version: '3'

services:
host-metering:
build:
context: ./
dockerfile: ./Dockerfile
volumes:
- ../:/workspace/host-metering:Z

prometheus:
image: prometheus/prometheus
ports:
- 9090:9090
volumes:
- ./local_prometheus/prometheus.yml:/etc/prometheus/prometheus.yml:Z
command:
- '--config.file=/etc/prometheus/prometheus.yml'
- '--storage.tsdb.path=/prometheus'
- '--web.console.libraries=/usr/share/prometheus/console_libraries'
- '--web.console.templates=/usr/share/prometheus/consoles'
- '--web.enable-remote-write-receiver'
11 changes: 6 additions & 5 deletions hack/host-metering.conf → .devcontainer/host-metering.conf
Original file line number Diff line number Diff line change
Expand Up @@ -2,18 +2,19 @@
# and uses a test certificate and key.

# E.g. could be used as:
# ./host-metering -config hack/host-metering.conf daemon
# ./host-metering -config .devcontainer/host-metering.conf daemon
# If a podman-compose is not used, make sure to replace http://prometheus:9090 with localhost

[host-metering]
write_url=http://localhost:9090/api/v1/write
write_url=http://prometheus:9090/api/v1/write
write_interval_sec=5
host_cert_path=./hack/test-cert.crt
host_cert_key_path=./hack/test-cert.key
host_cert_path=./mocks/consumer/cert.pem
host_cert_key_path=./mocks/consumer/key.pem
collect_interval_sec=0
label_refresh_interval_sec=10
write_timeout_sec=1
write_retry_attempts=1
write_retry_max_int_sec=2
metrics_wal_path=./hack/cpumetrics
metrics_wal_path=./mocks/cpumetrics
metrics_max_age_sec=30
log_level=DEBUG
File renamed without changes.
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -16,5 +16,6 @@ node_modules
#dev
mocks/subscription-manager-*
mocks/consumer/
mocks/cpumetrics/
.devcontainer/docker-compose.local.yml
mocks/cpumetrics/
coverage.*
6 changes: 2 additions & 4 deletions .vscode/launch.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,9 @@
"request": "launch",
"mode": "auto",
"program": "${workspaceFolder}/main.go",
"args": ["once"],
"args": ["--config", "${workspaceFolder}/.devcontainer/host-metering.conf", "once"],
"env": {
"HOST_METERING_HOST_CERT_PATH": "${workspaceFolder}/mocks/consumer/cert.pem",
"HOST_METERING_HOST_CERT_KEY_PATH": "${workspaceFolder}/mocks/consumer/key.pem",
"PATH": "${workspaceFolder}/mocks:${env:PATH}"
"PATH": "${workspaceFolder}/mocks:${env:PATH}",
}
}
]
Expand Down
5 changes: 5 additions & 0 deletions .vscode/settings.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"go.alternateTools": {
"go": "/opt/rh/go-toolset-1.19/root/usr/bin/go"
}
}
85 changes: 44 additions & 41 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -13,15 +13,16 @@ RPMTOPDIR := $(DISTDIR)/rpmbuild
GO := go
TESTDIR := $(CURDIR)/test

CONTAINER_POD := host-metering-pod
DASHBOARD_URL = http://localhost:9090/graph?g0.expr=system_cpu_logical_count&g0.tab=0&g0.range_input=1m

MOCKS_DIR = $(TESTDIR)/../mocks

# Test
.PHONY: test
test:
test: vendor
@echo "Running the unit tests..."

PATH=$(TESTDIR)/bin:$(PATH) \
PATH=$(MOCKS_DIR):$(PATH) \
$(GO) test -v \
-coverprofile=coverage.out \
-covermode=atomic \
Expand Down Expand Up @@ -49,55 +50,53 @@ build-selinux:

# Functional testing (manual or automatic)

.PHONY: container-env-setup
container-env-setup:
ifndef IS_IN_CONTAINER
CONTAINER_TARGET = prometheus
PROMETHEUS_ADDRESS = http://localhost:9090/api/v1/write
else
CONTAINER_TARGET =
PROMETHEUS_ADDRESS = http://prometheus:9090/api/v1/write
endif

.PHONY: test-daemon
test-daemon: cert build prometheus
test-daemon: cert build container-env-setup $(CONTAINER_TARGET)
@echo "Running the $(PROJECT) in deamon mode..."

PATH=$(TESTDIR)/bin:$(PATH) \
$(DISTDIR)/$(PROJECT) --config hack/host-metering.conf daemon
PATH=$(MOCKS_DIR):$(PATH) \
HOST_METERING_WRITE_URL=$(PROMETHEUS_ADDRESS) \
$(DISTDIR)/$(PROJECT) --config .devcontainer/host-metering.conf daemon

cert: hack/test-cert.crt hack/test-cert.key
cert: mocks/consumer/cert.pem mocks/consumer/key.pem

hack/test-cert.crt hack/test-cert.key:
mocks/consumer/cert.pem mocks/consumer/key.pem:
@echo "Generating test certificates..."
cd hack && ./create-cert.sh
cd mocks && ./create-cert.sh

# Containers

.PHONY: container-pod
container-pod:
if podman pod exists $(CONTAINER_POD); then \
echo "Pod $(CONTAINER_POD) exists."; \
exit 0; \
else \
echo "Creating the $(CONTAINER_POD)..."; \
podman pod create --replace -p 9090:9090 ${CONTAINER_POD}; \
fi
.PHONY: podman-containers
podman-containers:
podman-compose -f .devcontainer/docker-compose.yml build

.PHONY: prometheus
prometheus: container-pod
prometheus: podman-containers
@echo "See the dashboard at: ${DASHBOARD_URL}"

if podman ps --filter "name=hm-prometheus" --format '{{.Names}}' | grep -q "hm-prometheus"; then \
echo "Prometheus is already running."; \
exit 0; \
else \
echo "Starting Prometheus..."; \
podman run --pod ${CONTAINER_POD} \
--name hm-prometheus \
-d \
-v ./hack/prometheus.yml:/etc/prometheus/prometheus.yml:Z \
prometheus/prometheus \
--config.file=/etc/prometheus/prometheus.yml \
--storage.tsdb.path=/prometheus \
--web.console.libraries=/usr/share/prometheus/console_libraries \
--web.console.templates=/usr/share/prometheus/consoles \
--web.enable-remote-write-receiver; \
fi
podman-compose -f .devcontainer/docker-compose.yml up -d prometheus

.PHONY: prometheus-stop
prometheus-stop:
podman-compose -f .devcontainer/docker-compose.yml stop prometheus

.PHONY: podman-%
podman-%:
podman-compose -f .devcontainer/docker-compose.yml run -u root host-metering bash -c "cd /workspace/host-metering && make $(subst podman-,,$@)"

.PHONY: clean-pod
clean-pod:
podman pod rm -f ${CONTAINER_POD}
podman-compose -f .devcontainer/docker-compose.yml down

# Release
.PHONY: version
Expand All @@ -115,13 +114,18 @@ distdir:
@echo "Creating the destination directory..."
mkdir -p $(DISTDIR)

.PHONY: vendor
# Ensure vendor was run at least once
vendor:
$(MAKE) force-vendor

# refresh vendor cache
.PHONY: force-vendor
force-vendor:
@echo "Downloading go dependencies..."
$(GO) mod tidy && $(GO) mod vendor

.PHONY: tarball
tarball: distdir vendor
tarball: distdir force-vendor
@echo "Creating a tarball with the source code..."
git archive \
--format="tar" \
Expand Down Expand Up @@ -188,9 +192,8 @@ clean:
rm -rf $(CURDIR)/$(PROJECT)
rm -rf $(CURDIR)/contrib/selinux/tmp
rm -rf $(CURDIR)/contrib/selinux/*.pp
rm -rf $(CURDIR)/hack/cpumetrics
rm -f $(CURDIR)/hack/test-cert.crt
rm -f $(CURDIR)/hack/test-cert.key
rm -rf $(MOCKS_DIR)/cpumetrics
rm -rf $(MOCKS_DIR)/consumer

.PHONY: clean-node
clean-node:
Expand Down
20 changes: 17 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -89,12 +89,26 @@ $ make clean-pod # destroy podman pod

## Running in a container
This project has configuration for running inside VSCode container.
### Prerequisites:
1. It requires podman and podman-compose to be installed on the host machine.
To install podman-compose, please run
```
sudo dnf install podman-compose
```
2. Make sure to add the following settings to user's settings.json (`ctrl+shift+P` -> `Preferences: Open user settings (JSON)`). This will set up the dev containers plugin to work with `podman` and `podman-compose`
```
"dev.containers.dockerComposePath": "podman-compose",
"dev.containers.dockerPath": "podman"
```
3. Execute `.devcontainer/commands/prepare_containers.sh`. It will create `docker-compose.local.yml` file that will be used to run the container properly.

You have to have a system with `subscription-manager` installed and registered correctly to use the UBI image (which is the base for this Dockerfile) and to have access to the relevan Red Hat repositories.
### Running make commands in a container
There is an option to run make commands inside the `docker-compose` generated environment. Just prefix a make command you would like to run with `podman-`. e.g. to run `make test` in a container, use `make podman-test`.

## Mocking subscription-manager commands
`mocked_run.sh` is a wrapper of `go run main.go` to execute the command in mocked context.
`mocked_run.sh` is a shortcut to running `go run main.go` with mocked context.

### Preparing the mocks
Inside the `mocks` folder run `./prepare_mock.sh` to generate outputs that will be used as mocks.
Inside the `mocks` folder run `./mock_from_host.sh` to generate outputs that will be used as mocks.
You have to have a system with `subscription-manager` installed and registered correctly to generate the mocks.

12 changes: 9 additions & 3 deletions hack/create-cert.sh → mocks/create-cert.sh
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,19 @@
# Execute this script in the directory with test-cert.cnf
# Purpose: Create a self-signed certificate for testing

openssl genrsa -out test-cert.key
if [ -d consumer ]; then
rm -rf consumer
fi

mkdir consumer

openssl genrsa -out consumer/key.pem

# To create a CSR for submitting to CA
# openssl req -new -key test-cert.key -out test-cert.csr -config test-cert.cnf

# Create a self-signed certificate
openssl req -x509 -new -key test-cert.key -out test-cert.crt -config test-cert.cnf
openssl req -x509 -new -key consumer/key.pem -out consumer/cert.pem -config mock-cert.cnf

# Show the certificate
openssl x509 -in test-cert.crt -text -noout
openssl x509 -in consumer/cert.pem -text -noout
File renamed without changes.
File renamed without changes.
Loading

0 comments on commit b50fe0e

Please sign in to comment.