mirror of https://github.com/istio/istio.io.git
Automate Getting Started (#7814)
* Automate Getting Started * Add sleep cleanup * Update cleanup * Ignore not found on cleanup * Review comments * More review comments * Cleanup prior sleep again * Add kiala start/stop
This commit is contained in:
parent
65439241fd
commit
81489373e7
|
|
@ -8,7 +8,7 @@ aliases:
|
|||
- /docs/setup/kubernetes/install/kubernetes/
|
||||
keywords: [getting-started, install, bookinfo, quick-start, kubernetes]
|
||||
owner: istio/wg-environments-maintainers
|
||||
test: no
|
||||
test: yes
|
||||
---
|
||||
|
||||
This guide lets you quickly evaluate Istio. If you are already familiar with
|
||||
|
|
@ -50,7 +50,7 @@ Follow these steps to get started with Istio:
|
|||
1. Move to the Istio package directory. For example, if the package is
|
||||
`istio-{{< istio_full_version >}}`:
|
||||
|
||||
{{< text bash >}}
|
||||
{{< text syntax=bash snip_id=none >}}
|
||||
$ cd istio-{{< istio_full_version >}}
|
||||
{{< /text >}}
|
||||
|
||||
|
|
@ -129,13 +129,13 @@ Follow these steps to get started with Istio:
|
|||
|
||||
{{< text bash >}}
|
||||
$ kubectl get pods
|
||||
NAME READY STATUS RESTARTS AGE
|
||||
details-v1-78d78fbddf-tj56d 0/2 PodInitializing 0 2m30s
|
||||
productpage-v1-85b9bf9cd7-zg7tr 0/2 PodInitializing 0 2m29s
|
||||
ratings-v1-6c9dbf6b45-5djtx 0/2 PodInitializing 0 2m29s
|
||||
reviews-v1-564b97f875-dzdt5 0/2 PodInitializing 0 2m30s
|
||||
reviews-v2-568c7c9d8f-p5wrj 1/2 Running 0 2m29s
|
||||
reviews-v3-67b4988599-7nhwz 0/2 PodInitializing 0 2m29s
|
||||
NAME READY STATUS RESTARTS AGE
|
||||
details-v1-558b8b4b76-2llld 2/2 Running 0 2m41s
|
||||
productpage-v1-6987489c74-lpkgl 2/2 Running 0 2m40s
|
||||
ratings-v1-7dc98c7588-vzftc 2/2 Running 0 2m41s
|
||||
reviews-v1-7f99cc4496-gdxfn 2/2 Running 0 2m41s
|
||||
reviews-v2-7d79d5bd5d-8zzqd 2/2 Running 0 2m41s
|
||||
reviews-v3-7dbcdcbc56-m8dph 2/2 Running 0 2m41s
|
||||
{{< /text >}}
|
||||
|
||||
{{< tip >}}
|
||||
|
|
@ -149,7 +149,7 @@ Follow these steps to get started with Istio:
|
|||
checking for the page title in the response:
|
||||
|
||||
{{< text bash >}}
|
||||
$ kubectl exec -it $(kubectl get pod -l app=ratings -o jsonpath='{.items[0].metadata.name}') -c ratings -- curl productpage:9080/productpage | grep -o "<title>.*</title>"
|
||||
$ kubectl exec "$(kubectl get pod -l app=ratings -o jsonpath='{.items[0].metadata.name}')" -c ratings -- curl -s productpage:9080/productpage | grep -o "<title>.*</title>"
|
||||
<title>Simple Bookstore App</title>
|
||||
{{< /text >}}
|
||||
|
||||
|
|
@ -195,12 +195,12 @@ $ export SECURE_INGRESS_PORT=$(kubectl -n istio-system get service istio-ingress
|
|||
Ensure a port was successfully assigned to each environment variable:
|
||||
|
||||
{{< text bash >}}
|
||||
$ echo $INGRESS_PORT
|
||||
$ echo "$INGRESS_PORT"
|
||||
32194
|
||||
{{< /text >}}
|
||||
|
||||
{{< text bash >}}
|
||||
$ echo $SECURE_INGRESS_PORT
|
||||
$ echo "$SECURE_INGRESS_PORT"
|
||||
31632
|
||||
{{< /text >}}
|
||||
|
||||
|
|
@ -213,7 +213,7 @@ $ export INGRESS_HOST=$(minikube ip)
|
|||
Ensure an IP address was successfully assigned to the environment variable:
|
||||
|
||||
{{< text bash >}}
|
||||
$ echo $INGRESS_HOST
|
||||
$ echo "$INGRESS_HOST"
|
||||
192.168.4.102
|
||||
{{< /text >}}
|
||||
|
||||
|
|
@ -276,22 +276,22 @@ $ export SECURE_INGRESS_PORT=$(kubectl -n istio-system get service istio-ingress
|
|||
_GKE:_
|
||||
|
||||
{{< text bash >}}
|
||||
$ export INGRESS_HOST=<workerNodeAddress>
|
||||
$ export INGRESS_HOST=workerNodeAddress
|
||||
{{< /text >}}
|
||||
|
||||
You need to create firewall rules to allow the TCP traffic to the `ingressgateway` service's ports.
|
||||
Run the following commands to allow the traffic for the HTTP port, the secure port (HTTPS) or both:
|
||||
|
||||
{{< text bash >}}
|
||||
$ gcloud compute firewall-rules create allow-gateway-http --allow tcp:$INGRESS_PORT
|
||||
$ gcloud compute firewall-rules create allow-gateway-https --allow tcp:$SECURE_INGRESS_PORT
|
||||
$ gcloud compute firewall-rules create allow-gateway-http --allow "tcp:$INGRESS_PORT"
|
||||
$ gcloud compute firewall-rules create allow-gateway-https --allow "tcp:$SECURE_INGRESS_PORT"
|
||||
{{< /text >}}
|
||||
|
||||
_IBM Cloud Kubernetes Service:_
|
||||
|
||||
{{< text bash >}}
|
||||
$ ibmcloud ks workers --cluster <cluster-name or id>
|
||||
$ export INGRESS_HOST=<public IP of one of the worker nodes>
|
||||
$ ibmcloud ks workers --cluster cluster-name-or-id
|
||||
$ export INGRESS_HOST=public-IP-of-one-of-the-worker-nodes
|
||||
{{< /text >}}
|
||||
|
||||
_Docker For Desktop:_
|
||||
|
|
@ -319,7 +319,7 @@ $ export INGRESS_HOST=$(kubectl get po -l istio=ingressgateway -n istio-system -
|
|||
1. Ensure an IP address and port were successfully assigned to the environment variable:
|
||||
|
||||
{{< text bash >}}
|
||||
$ echo $GATEWAY_URL
|
||||
$ echo "$GATEWAY_URL"
|
||||
192.168.99.100:32194
|
||||
{{< /text >}}
|
||||
|
||||
|
|
@ -331,7 +331,7 @@ by viewing the Bookinfo product page using a browser.
|
|||
1. Run the following command to retrieve the external address of the Bookinfo application.
|
||||
|
||||
{{< text bash >}}
|
||||
$ echo http://$GATEWAY_URL/productpage
|
||||
$ echo http://"$GATEWAY_URL/productpage"
|
||||
{{< /text >}}
|
||||
|
||||
1. Paste the output from the previous command into your web browser and confirm that the Bookinfo product page is displayed.
|
||||
|
|
@ -402,7 +402,7 @@ under the `istio-system` namespace. It is safe to ignore errors for non-existent
|
|||
resources because they may have been deleted hierarchically.
|
||||
|
||||
{{< text bash >}}
|
||||
$ istioctl manifest generate --set profile=demo | kubectl delete -f -
|
||||
$ istioctl manifest generate --set profile=demo | kubectl delete --ignore-not-found=true -f -
|
||||
{{< /text >}}
|
||||
|
||||
The `istio-system` namespace is not removed by default.
|
||||
|
|
|
|||
|
|
@ -0,0 +1,238 @@
|
|||
#!/bin/bash
|
||||
# shellcheck disable=SC2034,SC2153,SC2155,SC2164
|
||||
|
||||
# Copyright Istio Authors. All Rights Reserved.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
####################################################################################################
|
||||
# WARNING: THIS IS AN AUTO-GENERATED FILE, DO NOT EDIT. PLEASE MODIFY THE ORIGINAL MARKDOWN FILE:
|
||||
# docs/setup/getting-started/index.md
|
||||
####################################################################################################
|
||||
|
||||
snip_download_istio_download_1() {
|
||||
curl -L https://istio.io/downloadIstio | sh -
|
||||
}
|
||||
|
||||
snip_download_istio_download_3() {
|
||||
export PATH=$PWD/bin:$PATH
|
||||
}
|
||||
|
||||
snip_install_istio_install_1() {
|
||||
istioctl install --set profile=demo
|
||||
}
|
||||
|
||||
! read -r -d '' snip_install_istio_install_1_out <<\ENDSNIP
|
||||
✔ Istio core installed
|
||||
✔ Istiod installed
|
||||
✔ Egress gateways installed
|
||||
✔ Ingress gateways installed
|
||||
✔ Installation complete
|
||||
ENDSNIP
|
||||
|
||||
snip_install_istio_install_2() {
|
||||
kubectl label namespace default istio-injection=enabled
|
||||
}
|
||||
|
||||
! read -r -d '' snip_install_istio_install_2_out <<\ENDSNIP
|
||||
namespace/default labeled
|
||||
ENDSNIP
|
||||
|
||||
snip_deploy_the_sample_application_bookinfo_1() {
|
||||
kubectl apply -f samples/bookinfo/platform/kube/bookinfo.yaml
|
||||
}
|
||||
|
||||
! read -r -d '' snip_deploy_the_sample_application_bookinfo_1_out <<\ENDSNIP
|
||||
service/details created
|
||||
serviceaccount/bookinfo-details created
|
||||
deployment.apps/details-v1 created
|
||||
service/ratings created
|
||||
serviceaccount/bookinfo-ratings created
|
||||
deployment.apps/ratings-v1 created
|
||||
service/reviews created
|
||||
serviceaccount/bookinfo-reviews created
|
||||
deployment.apps/reviews-v1 created
|
||||
deployment.apps/reviews-v2 created
|
||||
deployment.apps/reviews-v3 created
|
||||
service/productpage created
|
||||
serviceaccount/bookinfo-productpage created
|
||||
deployment.apps/productpage-v1 created
|
||||
ENDSNIP
|
||||
|
||||
snip_deploy_the_sample_application_bookinfo_2() {
|
||||
kubectl get services
|
||||
}
|
||||
|
||||
! read -r -d '' snip_deploy_the_sample_application_bookinfo_2_out <<\ENDSNIP
|
||||
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
|
||||
details ClusterIP 10.0.0.212 <none> 9080/TCP 29s
|
||||
kubernetes ClusterIP 10.0.0.1 <none> 443/TCP 25m
|
||||
productpage ClusterIP 10.0.0.57 <none> 9080/TCP 28s
|
||||
ratings ClusterIP 10.0.0.33 <none> 9080/TCP 29s
|
||||
reviews ClusterIP 10.0.0.28 <none> 9080/TCP 29s
|
||||
ENDSNIP
|
||||
|
||||
snip_deploy_the_sample_application_bookinfo_3() {
|
||||
kubectl get pods
|
||||
}
|
||||
|
||||
! read -r -d '' snip_deploy_the_sample_application_bookinfo_3_out <<\ENDSNIP
|
||||
NAME READY STATUS RESTARTS AGE
|
||||
details-v1-558b8b4b76-2llld 2/2 Running 0 2m41s
|
||||
productpage-v1-6987489c74-lpkgl 2/2 Running 0 2m40s
|
||||
ratings-v1-7dc98c7588-vzftc 2/2 Running 0 2m41s
|
||||
reviews-v1-7f99cc4496-gdxfn 2/2 Running 0 2m41s
|
||||
reviews-v2-7d79d5bd5d-8zzqd 2/2 Running 0 2m41s
|
||||
reviews-v3-7dbcdcbc56-m8dph 2/2 Running 0 2m41s
|
||||
ENDSNIP
|
||||
|
||||
snip_deploy_the_sample_application_bookinfo_4() {
|
||||
kubectl exec "$(kubectl get pod -l app=ratings -o jsonpath='{.items[0].metadata.name}')" -c ratings -- curl -s productpage:9080/productpage | grep -o "<title>.*</title>"
|
||||
}
|
||||
|
||||
! read -r -d '' snip_deploy_the_sample_application_bookinfo_4_out <<\ENDSNIP
|
||||
<title>Simple Bookstore App</title>
|
||||
ENDSNIP
|
||||
|
||||
snip_open_the_application_to_outside_traffic_ip_1() {
|
||||
kubectl apply -f samples/bookinfo/networking/bookinfo-gateway.yaml
|
||||
}
|
||||
|
||||
! read -r -d '' snip_open_the_application_to_outside_traffic_ip_1_out <<\ENDSNIP
|
||||
gateway.networking.istio.io/bookinfo-gateway created
|
||||
virtualservice.networking.istio.io/bookinfo created
|
||||
ENDSNIP
|
||||
|
||||
snip_open_the_application_to_outside_traffic_ip_2() {
|
||||
istioctl analyze
|
||||
}
|
||||
|
||||
! read -r -d '' snip_open_the_application_to_outside_traffic_ip_2_out <<\ENDSNIP
|
||||
✔ No validation issues found when analyzing namespace: default.
|
||||
ENDSNIP
|
||||
|
||||
snip_determining_the_ingress_ip_and_ports_1() {
|
||||
export INGRESS_PORT=$(kubectl -n istio-system get service istio-ingressgateway -o jsonpath='{.spec.ports[?(@.name=="http2")].nodePort}')
|
||||
export SECURE_INGRESS_PORT=$(kubectl -n istio-system get service istio-ingressgateway -o jsonpath='{.spec.ports[?(@.name=="https")].nodePort}')
|
||||
}
|
||||
|
||||
snip_determining_the_ingress_ip_and_ports_2() {
|
||||
echo "$INGRESS_PORT"
|
||||
}
|
||||
|
||||
! read -r -d '' snip_determining_the_ingress_ip_and_ports_2_out <<\ENDSNIP
|
||||
32194
|
||||
ENDSNIP
|
||||
|
||||
snip_determining_the_ingress_ip_and_ports_3() {
|
||||
echo "$SECURE_INGRESS_PORT"
|
||||
}
|
||||
|
||||
! read -r -d '' snip_determining_the_ingress_ip_and_ports_3_out <<\ENDSNIP
|
||||
31632
|
||||
ENDSNIP
|
||||
|
||||
snip_determining_the_ingress_ip_and_ports_4() {
|
||||
export INGRESS_HOST=$(minikube ip)
|
||||
}
|
||||
|
||||
snip_determining_the_ingress_ip_and_ports_5() {
|
||||
echo "$INGRESS_HOST"
|
||||
}
|
||||
|
||||
! read -r -d '' snip_determining_the_ingress_ip_and_ports_5_out <<\ENDSNIP
|
||||
192.168.4.102
|
||||
ENDSNIP
|
||||
|
||||
snip_determining_the_ingress_ip_and_ports_6() {
|
||||
minikube tunnel
|
||||
}
|
||||
|
||||
snip_determining_the_ingress_ip_and_ports_7() {
|
||||
kubectl get svc istio-ingressgateway -n istio-system
|
||||
}
|
||||
|
||||
! read -r -d '' snip_determining_the_ingress_ip_and_ports_7_out <<\ENDSNIP
|
||||
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
|
||||
istio-ingressgateway LoadBalancer 172.21.109.129 130.211.10.121 80:31380/TCP,443:31390/TCP,31400:31400/TCP 17h
|
||||
ENDSNIP
|
||||
|
||||
snip_determining_the_ingress_ip_and_ports_8() {
|
||||
export INGRESS_HOST=$(kubectl -n istio-system get service istio-ingressgateway -o jsonpath='{.status.loadBalancer.ingress[0].ip}')
|
||||
export INGRESS_PORT=$(kubectl -n istio-system get service istio-ingressgateway -o jsonpath='{.spec.ports[?(@.name=="http2")].port}')
|
||||
export SECURE_INGRESS_PORT=$(kubectl -n istio-system get service istio-ingressgateway -o jsonpath='{.spec.ports[?(@.name=="https")].port}')
|
||||
}
|
||||
|
||||
snip_determining_the_ingress_ip_and_ports_9() {
|
||||
export INGRESS_HOST=$(kubectl -n istio-system get service istio-ingressgateway -o jsonpath='{.status.loadBalancer.ingress[0].hostname}')
|
||||
}
|
||||
|
||||
snip_determining_the_ingress_ip_and_ports_10() {
|
||||
export INGRESS_PORT=$(kubectl -n istio-system get service istio-ingressgateway -o jsonpath='{.spec.ports[?(@.name=="http2")].nodePort}')
|
||||
export SECURE_INGRESS_PORT=$(kubectl -n istio-system get service istio-ingressgateway -o jsonpath='{.spec.ports[?(@.name=="https")].nodePort}')
|
||||
}
|
||||
|
||||
snip_determining_the_ingress_ip_and_ports_11() {
|
||||
export INGRESS_HOST=workerNodeAddress
|
||||
}
|
||||
|
||||
snip_determining_the_ingress_ip_and_ports_12() {
|
||||
gcloud compute firewall-rules create allow-gateway-http --allow "tcp:$INGRESS_PORT"
|
||||
gcloud compute firewall-rules create allow-gateway-https --allow "tcp:$SECURE_INGRESS_PORT"
|
||||
}
|
||||
|
||||
snip_determining_the_ingress_ip_and_ports_13() {
|
||||
ibmcloud ks workers --cluster cluster-name-or-id
|
||||
export INGRESS_HOST=public-IP-of-one-of-the-worker-nodes
|
||||
}
|
||||
|
||||
snip_determining_the_ingress_ip_and_ports_14() {
|
||||
export INGRESS_HOST=127.0.0.1
|
||||
}
|
||||
|
||||
snip_determining_the_ingress_ip_and_ports_15() {
|
||||
export INGRESS_HOST=$(kubectl get po -l istio=ingressgateway -n istio-system -o jsonpath='{.items[0].status.hostIP}')
|
||||
}
|
||||
|
||||
snip_determining_the_ingress_ip_and_ports_16() {
|
||||
export GATEWAY_URL=$INGRESS_HOST:$INGRESS_PORT
|
||||
}
|
||||
|
||||
snip_determining_the_ingress_ip_and_ports_17() {
|
||||
echo "$GATEWAY_URL"
|
||||
}
|
||||
|
||||
! read -r -d '' snip_determining_the_ingress_ip_and_ports_17_out <<\ENDSNIP
|
||||
192.168.99.100:32194
|
||||
ENDSNIP
|
||||
|
||||
snip_verify_external_access_confirm_1() {
|
||||
echo http://"$GATEWAY_URL/productpage"
|
||||
}
|
||||
|
||||
snip_view_the_dashboard_dashboard_1() {
|
||||
kubectl apply -f samples/addons
|
||||
while ! kubectl wait --for=condition=available --timeout=600s deployment/kiali -n istio-system; do sleep 1; done
|
||||
}
|
||||
|
||||
snip_view_the_dashboard_dashboard_2() {
|
||||
istioctl dashboard kiali
|
||||
}
|
||||
|
||||
snip_uninstall_1() {
|
||||
istioctl manifest generate --set profile=demo | kubectl delete --ignore-not-found=true -f -
|
||||
}
|
||||
|
||||
snip_uninstall_2() {
|
||||
kubectl delete namespace istio-system
|
||||
}
|
||||
|
|
@ -0,0 +1,90 @@
|
|||
#!/usr/bin/env bash
|
||||
# shellcheck disable=SC1090,SC2154
|
||||
|
||||
# Copyright Istio Authors
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
set -e
|
||||
set -u
|
||||
set -o pipefail
|
||||
|
||||
source "tests/util/samples.sh"
|
||||
|
||||
# Download Istio
|
||||
# Skipping this as we use the istioctl built from istio/istio reference
|
||||
|
||||
# Install Istio
|
||||
# @setup profile=none
|
||||
snip_install_istio_install_1
|
||||
_wait_for_deployment istio-system istiod
|
||||
|
||||
# Label the namespace
|
||||
# remove the injection label to prevent the following command from failing
|
||||
kubectl label namespace default istio-injection-
|
||||
snip_install_istio_install_2
|
||||
|
||||
# TODO: how to make sure previous tests cleaned up everything?
|
||||
# Cleanup sleep
|
||||
cleanup_sleep_sample
|
||||
|
||||
# Deploy the sample Application
|
||||
snip_deploy_the_sample_application_bookinfo_1
|
||||
|
||||
# Check the services
|
||||
_verify_like snip_deploy_the_sample_application_bookinfo_2 "$snip_deploy_the_sample_application_bookinfo_2_out"
|
||||
|
||||
# Wait for pods to be ready
|
||||
for deploy in "productpage-v1" "details-v1" "ratings-v1" "reviews-v1" "reviews-v2" "reviews-v3"; do
|
||||
_wait_for_deployment default "$deploy"
|
||||
done
|
||||
|
||||
# Check the pods
|
||||
_verify_like snip_deploy_the_sample_application_bookinfo_3 "$snip_deploy_the_sample_application_bookinfo_3_out"
|
||||
|
||||
# Verify connectivity
|
||||
_verify_like snip_deploy_the_sample_application_bookinfo_4 "$snip_deploy_the_sample_application_bookinfo_4_out"
|
||||
|
||||
# Open to outside traffic
|
||||
_verify_contains snip_open_the_application_to_outside_traffic_ip_1 "$snip_open_the_application_to_outside_traffic_ip_1_out"
|
||||
_wait_for_istio gateway default bookinfo-gateway
|
||||
|
||||
# Ensure no issues with configuration - istioctl analyze
|
||||
_verify_contains snip_open_the_application_to_outside_traffic_ip_2 "$snip_open_the_application_to_outside_traffic_ip_2_out"
|
||||
|
||||
# Get GATEWAY_URL
|
||||
# export the INGRESS_ environment variables
|
||||
# TODO make this work more generally. Currently using snips for Kind.
|
||||
snip_determining_the_ingress_ip_and_ports_10
|
||||
snip_determining_the_ingress_ip_and_ports_15
|
||||
snip_determining_the_ingress_ip_and_ports_16
|
||||
|
||||
# Verify external access
|
||||
get_bookinfo_productpage() {
|
||||
curl -s "http://${GATEWAY_URL}/productpage" | grep -o "<title>.*</title>"
|
||||
}
|
||||
_verify_contains get_bookinfo_productpage "<title>Simple Bookstore App</title>"
|
||||
|
||||
# Install addons
|
||||
# TODO Fix this. For now Kiali has a problem being cleaned up: https://github.com/istio/istio/pull/25886
|
||||
snip_view_the_dashboard_dashboard_1
|
||||
|
||||
# Verify Kiala dashboard
|
||||
# TODO Verify the browser output
|
||||
|
||||
# @cleanup
|
||||
set +e # ignore cleanup errors
|
||||
kubectl delete kiali kiali -n istio-system
|
||||
kubectl delete -f samples/addons
|
||||
cleanup_bookinfo_sample
|
||||
snip_uninstall_1
|
||||
|
|
@ -104,6 +104,8 @@ with open(markdown, 'rt', encoding='utf-8') as mdfile:
|
|||
kind = match.group(3)
|
||||
match = snippetid.search(line)
|
||||
if match:
|
||||
if match.group(1) == "none":
|
||||
continue
|
||||
id = "snip_" + match.group(1)
|
||||
else:
|
||||
id = "snip_%s_%d" % (section, snipnum)
|
||||
|
|
|
|||
Loading…
Reference in New Issue