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

feat: use RELATED_IMAGES_ environment variables to configure operand's images #812

Open
wants to merge 3 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 5 additions & 5 deletions .github/workflows/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ jobs:
go-version: ${{ env.GO_VERSION }}

- name: Replace images
run: make dev-images && cat internal/controller/constants/images.go
run: make dev-images && cat internal/images/images.env

- name: Build operator container
run: make docker-build docker-push
Expand All @@ -51,7 +51,7 @@ jobs:
uses: actions/checkout@v4

- name: Replace images
run: make dev-images && cat internal/controller/constants/images.go
run: make dev-images && cat internal/images/images.env

- name: Build operator bundle
run: make bundle bundle-build bundle-push
Expand Down Expand Up @@ -228,7 +228,7 @@ jobs:
run: go install github.com/sigstore/cosign/v2/cmd/[email protected]

- name: Replace images
run: make dev-images && cat internal/controller/constants/images.go
run: make dev-images && cat internal/images/images.env

- name: Run tests
run: make test-e2e
Expand Down Expand Up @@ -300,7 +300,7 @@ jobs:
run: go install github.com/sigstore/cosign/v2/cmd/[email protected]

- name: Replace images
run: make dev-images && cat internal/controller/constants/images.go
run: make dev-images && cat internal/images/images.env

- name: Run tests
env:
Expand Down Expand Up @@ -365,7 +365,7 @@ jobs:
sudo echo "127.0.0.1 fulcio-server.local tuf.local rekor-server.local rekor-search-ui.local cli-server.local" | sudo tee -a /etc/hosts

- name: Replace images
run: make dev-images && cat internal/controller/constants/images.go
run: make dev-images && cat internal/images/images.env

- name: Run tests
env:
Expand Down
22 changes: 14 additions & 8 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,11 @@ SHELL = /usr/bin/env bash -o pipefail

OPENSHIFT ?= true

CONFIG_DEFAULT=config/env/kubernetes
ifeq ($(OPENSHIFT), true)
CONFIG_DEFAULT=config/env/openshift
endif

.PHONY: all
all: build

Expand Down Expand Up @@ -136,9 +141,9 @@ test-e2e:
.PHONY: dev-images
dev-images:
@if [ "$(shell uname)" = "Darwin" ]; then \
sed -E -i '' -f ci/dev-images.sed internal/controller/constants/images.go; \
sed -E -i '' -f ci/dev-images.sed internal/images/images.env; \
else \
sed -E -i -f ci/dev-images.sed internal/controller/constants/images.go; \
sed -E -i -f ci/dev-images.sed internal/images/images.env; \
fi

.PHONY: lint
Expand Down Expand Up @@ -195,7 +200,8 @@ docker-buildx: ## Build and push docker image for the manager for cross-platform
build-installer: manifests generate kustomize ## Generate a consolidated YAML with CRDs and deployment.
mkdir -p dist
cd config/manager && $(KUSTOMIZE) edit set image controller=${IMG}
$(KUSTOMIZE) build config/default > dist/install.yaml
cp internal/images/images.env config/default/images.env
$(KUSTOMIZE) build ${CONFIG_DEFAULT} > dist/install.yaml

##@ Deployment

Expand All @@ -214,14 +220,13 @@ uninstall: manifests kustomize ## Uninstall CRDs from the K8s cluster specified
.PHONY: deploy
deploy: manifests kustomize ## Deploy controller to the K8s cluster specified in ~/.kube/config.
cd config/manager && $(KUSTOMIZE) edit set image controller=${IMG}
$(KUSTOMIZE) build config/default | $(KUBECTL) apply -f -
@if [ "$(OPENSHIFT)" == "false" ]; then \
$(KUBECTL) patch deploy -n openshift-rhtas-operator -p '{"spec": {"template": {"spec": {"containers": [{"name": "manager","env": [{"name": "OPENSHIFT","value":"false"}]}]}}}}' rhtas-operator-controller-manager; \
fi
cp internal/images/images.env config/default/images.env
$(KUSTOMIZE) build ${CONFIG_DEFAULT} | $(KUBECTL) apply -f -


.PHONY: undeploy
undeploy: kustomize ## Undeploy controller from the K8s cluster specified in ~/.kube/config. Call with ignore-not-found=true to ignore resource not found errors during deletion.
$(KUSTOMIZE) build config/default | $(KUBECTL) delete --ignore-not-found=$(ignore-not-found) -f -
$(KUSTOMIZE) build ${CONFIG_DEFAULT} | $(KUBECTL) delete --ignore-not-found=$(ignore-not-found) -f -

##@ Dependencies

Expand Down Expand Up @@ -298,6 +303,7 @@ endif
bundle: manifests kustomize operator-sdk ## Generate bundle manifests and metadata, then validate generated files.
$(OPERATOR_SDK) generate kustomize manifests -q
cd config/manager && $(KUSTOMIZE) edit set image controller=$(IMG)
cp internal/images/images.env config/default/images.env
$(KUSTOMIZE) build config/manifests | $(OPERATOR_SDK) generate bundle $(BUNDLE_GEN_FLAGS)
$(OPERATOR_SDK) bundle validate ./bundle

Expand Down
63 changes: 62 additions & 1 deletion bundle/manifests/rhtas-operator.clusterserviceversion.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -297,7 +297,7 @@ metadata:
]
capabilities: Seamless Upgrades
containerImage: registry.redhat.io/rhtas/rhtas-rhel9-operator@sha256:52ba6cd82bc400a08c6f89811e8086126596a873b9b12619de8c5064a2d4faf7
createdAt: "2024-11-07T12:56:22Z"
createdAt: "2025-01-16T14:07:22Z"
features.operators.openshift.io/cnf: "false"
features.operators.openshift.io/cni: "false"
features.operators.openshift.io/csi: "false"
Expand Down Expand Up @@ -892,6 +892,36 @@ spec:
env:
- name: OPENSHIFT
value: "true"
- name: RELATED_IMAGE_TRILLIAN_LOG_SIGNER
value: registry.redhat.io/rhtas/trillian-logsigner-rhel9@sha256:2d707d12e4f65e1a92b4de11465a5976d55e15ad6c9fefe994646ccd44c83840
- name: RELATED_IMAGE_TRILLIAN_LOG_SERVER
value: registry.redhat.io/rhtas/trillian-logserver-rhel9@sha256:7af78c7bc4df097ffeeef345f1d13289695f715221957579ee65daeef2fa3f5b
- name: RELATED_IMAGE_TRILLIAN_DB
value: registry.redhat.io/rhtas/trillian-database-rhel9@sha256:501612745e63e5504017079388bec191ffacf00ffdebde7be6ca5b8e4fd9d323
- name: RELATED_IMAGE_TRILLIAN_NETCAT
value: registry.redhat.io/openshift4/ose-tools-rhel8@sha256:486b4d2dd0d10c5ef0212714c94334e04fe8a3d36cf619881986201a50f123c7
- name: RELATED_IMAGE_FULCIO_SERVER
value: registry.redhat.io/rhtas/fulcio-rhel9@sha256:4b5765bbfd3dac5fa027d2fb3d672b6ebffbc573b9413ab4cb189c50fa6f9a09
- name: RELATED_IMAGE_REKOR_REDIS
value: registry.redhat.io/rhtas/trillian-redis-rhel9@sha256:18820b1fbdbc2cc3e917822974910332d937b03cfe781628bd986fd6a5ee318e
- name: RELATED_IMAGE_REKOR_SERVER
value: registry.redhat.io/rhtas/rekor-server-rhel9@sha256:81e10e34f02b21bb8295e7b5c93797fc8c0e43a1a0d8304cca1b07415a3ed6f5
- name: RELATED_IMAGE_REKOR_SEARCH_UI
value: registry.redhat.io/rhtas/rekor-search-ui-rhel9@sha256:3c93c15fc5c918a91b3da9f5bf2276e4d46d881b1031287e6ab28e6aeb23e019
- name: RELATED_IMAGE_BACKFILL_REDIS
value: registry.redhat.io/rhtas/rekor-backfill-redis-rhel9@sha256:6aa3ca40e0f9e32a0a211a930b21ff009b83e46609bfa5bb328979e4799d13c7
- name: RELATED_IMAGE_TUF
value: registry.redhat.io/rhtas/tuffer-rhel9@sha256:79340be7918034c68a334a210ab872161827c99c2a1551a4fce8d5d27560a234
- name: RELATED_IMAGE_CTLOG
value: registry.redhat.io/rhtas/certificate-transparency-rhel9@sha256:31e7318a9b19ed04ef0f25949f1f1709d293b532316b27a06f83fa5174547b17
- name: RELATED_IMAGE_HTTP_SERVER
value: registry.access.redhat.com/ubi9/httpd-24@sha256:7874b82335a80269dcf99e5983c2330876f5fe8bdc33dc6aa4374958a2ffaaee
- name: RELATED_IMAGE_SEGMENT_REPORTING
value: registry.redhat.io/rhtas/segment-reporting-rhel9@sha256:1b87ff1ad02c476c08e06038a26af7abe61f177e491a9ff42d507550a8587ac8
- name: RELATED_IMAGE_TIMESTAMP_AUTHORITY
value: registry.redhat.io/rhtas/timestamp-authority-rhel9@sha256:fce0a22c8872309554236bab3457715dda0a83eb40dc6a9ecd3477b8023369d0
- name: RELATED_IMAGE_CLIENT_SERVER
value: registry.redhat.io/rhtas/client-server-rhel9@sha256:9537329d0166b8d41ffd5f5d79c052fc27abe426a20cba5733c84030013c4e29
image: registry.redhat.io/rhtas/rhtas-rhel9-operator@sha256:52ba6cd82bc400a08c6f89811e8086126596a873b9b12619de8c5064a2d4faf7
livenessProbe:
httpGet:
Expand Down Expand Up @@ -998,4 +1028,35 @@ spec:
provider:
name: Red Hat
url: https://github.com/securesign/secure-sign-operator
relatedImages:
- image: registry.redhat.io/rhtas/trillian-logsigner-rhel9@sha256:2d707d12e4f65e1a92b4de11465a5976d55e15ad6c9fefe994646ccd44c83840
name: trillian-log-signer
- image: registry.redhat.io/rhtas/trillian-logserver-rhel9@sha256:7af78c7bc4df097ffeeef345f1d13289695f715221957579ee65daeef2fa3f5b
name: trillian-log-server
- image: registry.redhat.io/rhtas/trillian-database-rhel9@sha256:501612745e63e5504017079388bec191ffacf00ffdebde7be6ca5b8e4fd9d323
name: trillian-db
- image: registry.redhat.io/openshift4/ose-tools-rhel8@sha256:486b4d2dd0d10c5ef0212714c94334e04fe8a3d36cf619881986201a50f123c7
name: trillian-netcat
- image: registry.redhat.io/rhtas/fulcio-rhel9@sha256:4b5765bbfd3dac5fa027d2fb3d672b6ebffbc573b9413ab4cb189c50fa6f9a09
name: fulcio-server
- image: registry.redhat.io/rhtas/trillian-redis-rhel9@sha256:18820b1fbdbc2cc3e917822974910332d937b03cfe781628bd986fd6a5ee318e
name: rekor-redis
- image: registry.redhat.io/rhtas/rekor-server-rhel9@sha256:81e10e34f02b21bb8295e7b5c93797fc8c0e43a1a0d8304cca1b07415a3ed6f5
name: rekor-server
- image: registry.redhat.io/rhtas/rekor-search-ui-rhel9@sha256:3c93c15fc5c918a91b3da9f5bf2276e4d46d881b1031287e6ab28e6aeb23e019
name: rekor-search-ui
- image: registry.redhat.io/rhtas/rekor-backfill-redis-rhel9@sha256:6aa3ca40e0f9e32a0a211a930b21ff009b83e46609bfa5bb328979e4799d13c7
name: backfill-redis
- image: registry.redhat.io/rhtas/tuffer-rhel9@sha256:79340be7918034c68a334a210ab872161827c99c2a1551a4fce8d5d27560a234
name: tuf
- image: registry.redhat.io/rhtas/certificate-transparency-rhel9@sha256:31e7318a9b19ed04ef0f25949f1f1709d293b532316b27a06f83fa5174547b17
name: ctlog
- image: registry.access.redhat.com/ubi9/httpd-24@sha256:7874b82335a80269dcf99e5983c2330876f5fe8bdc33dc6aa4374958a2ffaaee
name: http-server
- image: registry.redhat.io/rhtas/segment-reporting-rhel9@sha256:1b87ff1ad02c476c08e06038a26af7abe61f177e491a9ff42d507550a8587ac8
name: segment-reporting
- image: registry.redhat.io/rhtas/timestamp-authority-rhel9@sha256:fce0a22c8872309554236bab3457715dda0a83eb40dc6a9ecd3477b8023369d0
name: timestamp-authority
- image: registry.redhat.io/rhtas/client-server-rhel9@sha256:9537329d0166b8d41ffd5f5d79c052fc27abe426a20cba5733c84030013c4e29
name: client-server
version: 1.2.0
20 changes: 20 additions & 0 deletions bundle/manifests/rhtas-related-images_v1_configmap.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
apiVersion: v1
data:
RELATED_IMAGE_BACKFILL_REDIS: registry.redhat.io/rhtas/rekor-backfill-redis-rhel9@sha256:6aa3ca40e0f9e32a0a211a930b21ff009b83e46609bfa5bb328979e4799d13c7
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I know that this is needed by Kustomize but I don't think it is necessary to keep it as part of the bundle. Maybe we can add it to .gitignore WDYT?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think that it will be better to keep it. It will be better to try keep kustomize output as close to bundle/. For example make build-installer will generate resources with that config.

RELATED_IMAGE_CLIENT_SERVER: registry.redhat.io/rhtas/client-server-rhel9@sha256:9537329d0166b8d41ffd5f5d79c052fc27abe426a20cba5733c84030013c4e29
RELATED_IMAGE_CTLOG: registry.redhat.io/rhtas/certificate-transparency-rhel9@sha256:31e7318a9b19ed04ef0f25949f1f1709d293b532316b27a06f83fa5174547b17
RELATED_IMAGE_FULCIO_SERVER: registry.redhat.io/rhtas/fulcio-rhel9@sha256:4b5765bbfd3dac5fa027d2fb3d672b6ebffbc573b9413ab4cb189c50fa6f9a09
RELATED_IMAGE_HTTP_SERVER: registry.access.redhat.com/ubi9/httpd-24@sha256:7874b82335a80269dcf99e5983c2330876f5fe8bdc33dc6aa4374958a2ffaaee
RELATED_IMAGE_REKOR_REDIS: registry.redhat.io/rhtas/trillian-redis-rhel9@sha256:18820b1fbdbc2cc3e917822974910332d937b03cfe781628bd986fd6a5ee318e
RELATED_IMAGE_REKOR_SEARCH_UI: registry.redhat.io/rhtas/rekor-search-ui-rhel9@sha256:3c93c15fc5c918a91b3da9f5bf2276e4d46d881b1031287e6ab28e6aeb23e019
RELATED_IMAGE_REKOR_SERVER: registry.redhat.io/rhtas/rekor-server-rhel9@sha256:81e10e34f02b21bb8295e7b5c93797fc8c0e43a1a0d8304cca1b07415a3ed6f5
RELATED_IMAGE_SEGMENT_REPORTING: registry.redhat.io/rhtas/segment-reporting-rhel9@sha256:1b87ff1ad02c476c08e06038a26af7abe61f177e491a9ff42d507550a8587ac8
RELATED_IMAGE_TIMESTAMP_AUTHORITY: registry.redhat.io/rhtas/timestamp-authority-rhel9@sha256:fce0a22c8872309554236bab3457715dda0a83eb40dc6a9ecd3477b8023369d0
RELATED_IMAGE_TRILLIAN_DB: registry.redhat.io/rhtas/trillian-database-rhel9@sha256:501612745e63e5504017079388bec191ffacf00ffdebde7be6ca5b8e4fd9d323
RELATED_IMAGE_TRILLIAN_LOG_SERVER: registry.redhat.io/rhtas/trillian-logserver-rhel9@sha256:7af78c7bc4df097ffeeef345f1d13289695f715221957579ee65daeef2fa3f5b
RELATED_IMAGE_TRILLIAN_LOG_SIGNER: registry.redhat.io/rhtas/trillian-logsigner-rhel9@sha256:2d707d12e4f65e1a92b4de11465a5976d55e15ad6c9fefe994646ccd44c83840
RELATED_IMAGE_TRILLIAN_NETCAT: registry.redhat.io/openshift4/ose-tools-rhel8@sha256:486b4d2dd0d10c5ef0212714c94334e04fe8a3d36cf619881986201a50f123c7
RELATED_IMAGE_TUF: registry.redhat.io/rhtas/tuffer-rhel9@sha256:79340be7918034c68a334a210ab872161827c99c2a1551a4fce8d5d27560a234
kind: ConfigMap
metadata:
name: rhtas-related-images
54 changes: 54 additions & 0 deletions ci/related-image-patch.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
#!/bin/bash
#
# Usage: ./related-image-patch.sh inputfile
osmman marked this conversation as resolved.
Show resolved Hide resolved
#
# This script reads an input file containing lines like:
# VARIABLE_NAME=value
#
# It outputs a JSON object where each variable becomes an entry in
# the "env" array with its name and corresponding value.
#

# Check that exactly one argument is provided.
if [ "$#" -ne 1 ]; then
echo "Usage: $0 inputfile"
exit 1
fi

inputfile="$1"

# Start outputting the JSON structure.
output='{"spec": {"config": {"env": ['

first_entry=1

# Process the file line by line.
while IFS= read -r line || [ -n "$line" ]; do
# Skip empty lines or lines without an '=' character.
if [ -z "$line" ] || [[ "$line" != *"="* ]]; then
continue
fi

# Split the line into key and value.
key="${line%%=*}"
value="${line#*=}"

# Print a comma before each JSON object except the first.
if [ $first_entry -eq 0 ]; then
output+=","
fi

# Append a newline to have each record on its own line.
output+=$'\n'

# Output the JSON object for this environment variable.
output+="{\"name\": \"$key\", \"value\": \"$value\"}"

first_entry=0
done < "$inputfile"

# Close the JSON structure.
output+=$'\n'
output+=']}}}'

echo "$output"
32 changes: 17 additions & 15 deletions cmd/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@ import (
"crypto/tls"
"flag"

"github.com/securesign/operator/internal/images"

"net/http"
"os"
"strconv"
Expand Down Expand Up @@ -104,22 +106,22 @@ func main() {
"If set, HTTP/2 will be enabled for the metrics and webhook servers")
flag.Int64Var(&constants.CreateTreeDeadline, "create-tree-deadline", constants.CreateTreeDeadline, "The time allowance (in seconds) for the create tree job to run before failing.")
utils.BoolFlagOrEnv(&constants.Openshift, "openshift", "OPENSHIFT", false, "Enable to ensures the operator applies OpenShift specific configurations.")
utils.StringFlagOrEnv(&constants.TrillianLogSignerImage, "trillian-log-signer-image", "TRILLIAN_LOG_SIGNER_IMAGE", constants.TrillianLogSignerImage, "The image used for trillian log signer.")
utils.StringFlagOrEnv(&constants.TrillianServerImage, "trillian-log-server-image", "TRILLIAN_LOG_SERVER_IMAGE", constants.TrillianServerImage, "The image used for trillian log server.")
utils.StringFlagOrEnv(&constants.TrillianDbImage, "trillian-db-image", "TRILLIAN_DB_IMAGE", constants.TrillianDbImage, "The image used for trillian's database.")
utils.StringFlagOrEnv(&constants.TrillianNetcatImage, "trillian-netcat-image", "TRILLIAN_NETCAT_IMAGE", constants.TrillianNetcatImage, "The image used for trillian netcat.")
utils.StringFlagOrEnv(&constants.FulcioServerImage, "fulcio-server-image", "FULCIO_SERVER_IMAGE", constants.FulcioServerImage, "The image used for the fulcio server.")
utils.StringFlagOrEnv(&constants.RekorRedisImage, "rekor-redis-image", "REKOR_REDIS_IMAGE", constants.RekorRedisImage, "The image used for redis.")
utils.StringFlagOrEnv(&constants.RekorServerImage, "rekor-server-image", "REKOR_SERVER_IMAGE", constants.RekorServerImage, "The image used for rekor server.")
utils.StringFlagOrEnv(&constants.RekorSearchUiImage, "rekor-search-ui-image", "REKOR_SEARCH_UI_IMAGE", constants.RekorSearchUiImage, "The image used for rekor search ui.")
utils.StringFlagOrEnv(&constants.BackfillRedisImage, "backfill-redis-image", "BACKFILL_REDIS_IMAGE", constants.BackfillRedisImage, "The image used for backfill redis.")
utils.StringFlagOrEnv(&constants.TufImage, "tuf-image", "TUF_IMAGE", constants.TufImage, "The image used for TUF.")
utils.StringFlagOrEnv(&constants.CTLogImage, "ctlog-image", "CTLOG_IMAGE", constants.CTLogImage, "The image used for ctlog.")
utils.StringFlagOrEnv(&constants.HttpServerImage, "http-server-image", "HTTP_SERVER_IMAGE", constants.HttpServerImage, "The image used to serve our cli binary's.")
utils.StringFlagOrEnv(&constants.ClientServerImage, "client-server-image", "CLIENT_SERVER_IMAGE", constants.ClientServerImage, "The image used to serve cosign and gitsign.")
utils.StringFlagOrEnv(&constants.SegmentBackupImage, "segment-backup-job-image", "SEGMENT_BACKUP_JOB_IMAGE", constants.SegmentBackupImage, "The image used for the segment backup job")
utils.RelatedImageFlag("trillian-log-signer-image", images.TrillianLogSigner, "The image used for trillian log signer.")
utils.RelatedImageFlag("trillian-log-server-image", images.TrillianServer, "The image used for trillian log server.")
utils.RelatedImageFlag("trillian-db-image", images.TrillianDb, "The image used for trillian's database.")
utils.RelatedImageFlag("trillian-netcat-image", images.TrillianNetcat, "The image used for trillian netcat.")
utils.RelatedImageFlag("fulcio-server-image", images.FulcioServer, "The image used for the fulcio server.")
utils.RelatedImageFlag("rekor-redis-image", images.RekorRedis, "The image used for redis.")
utils.RelatedImageFlag("rekor-server-image", images.RekorServer, "The image used for rekor server.")
utils.RelatedImageFlag("rekor-search-ui-image", images.RekorSearchUi, "The image used for rekor search ui.")
utils.RelatedImageFlag("backfill-redis-image", images.BackfillRedis, "The image used for backfill redis.")
utils.RelatedImageFlag("tuf-image", images.Tuf, "The image used for TUF.")
utils.RelatedImageFlag("ctlog-image", images.CTLog, "The image used for ctlog.")
utils.RelatedImageFlag("http-server-image", images.HttpServer, "The image used to serve our cli binary's.")
utils.RelatedImageFlag("client-server-image", images.ClientServer, "The image used to serve cosign and gitsign.")
utils.RelatedImageFlag("segment-backup-job-image", images.SegmentBackup, "The image used for the segment backup job")
utils.RelatedImageFlag("timestamp-authority-image", images.TimestampAuthority, "The image used for Timestamp Authority")
flag.StringVar(&clidownload.CliHostName, "cli-server-hostname", "", "The hostname for the cli server")
utils.StringFlagOrEnv(&constants.TimestampAuthorityImage, "timestamp-authority-image", "TIMESTAMP_AUTHORITY_IMAGE", constants.TimestampAuthorityImage, "The image used for Timestamp Authority")

klog.InitFlags(flag.CommandLine)
flag.Parse()
Expand Down
Loading
Loading