From c0e33050ab6d84a12fcc121b1934d3605f33d2d0 Mon Sep 17 00:00:00 2001 From: Ahmet Alp Balkan Date: Fri, 18 Aug 2017 17:19:11 -0700 Subject: [PATCH] Stop importing tutorials from k/examples repo Signed-off-by: Ahmet Alp Balkan --- .../stateful-application/cassandra.md | 65 ++------ .../{ => cassandra}/cassandra-service.yaml | 0 .../cassandra-statefulset.yaml | 0 .../mysql-wordpress-persistent-volume.md | 63 ++------ .../stateless-application/guestbook.md | 68 ++------ update-imported-tutorials.py | 149 ------------------ 6 files changed, 40 insertions(+), 305 deletions(-) rename docs/tutorials/stateful-application/{ => cassandra}/cassandra-service.yaml (100%) rename docs/tutorials/stateful-application/{ => cassandra}/cassandra-statefulset.yaml (100%) delete mode 100755 update-imported-tutorials.py diff --git a/docs/tutorials/stateful-application/cassandra.md b/docs/tutorials/stateful-application/cassandra.md index d17d6d9be6..c7d23d0be3 100644 --- a/docs/tutorials/stateful-application/cassandra.md +++ b/docs/tutorials/stateful-application/cassandra.md @@ -1,48 +1,13 @@ --- title: "Example: Deploying Cassandra with Stateful Sets" +assignees: +- ahmetb --- - - - {% capture overview %} This tutorial shows you how to develop a native cloud [Cassandra](http://cassandra.apache.org/) deployment on Kubernetes. In this instance, a custom Cassandra `SeedProvider` enables Cassandra to discover new Cassandra nodes as they join the cluster. -Deploying stateful distributed applications, like Cassandra, within a clustered environment can be challenging. StatefulSets greatly simplify this process. Please read about [StatefulSets](https://kubernetes.io/docs/concepts/workloads/controllers/statefulset/) for more information about the features used in this tutorial. +Deploying stateful distributed applications, like Cassandra, within a clustered environment can be challenging. StatefulSets greatly simplify this process. Please read about [StatefulSets](/docs/concepts/workloads/controllers/statefulset/) for more information about the features used in this tutorial. **Cassandra Docker** @@ -67,20 +32,20 @@ The docker is based on `debian:jessie` and includes OpenJDK 8. This image includ {% endcapture %} {% capture prerequisites %} -To complete this tutorial, you should already have a basic familiarity with [Pods](https://kubernetes.io/docs/concepts/workloads/pods/pod/), [Services](https://kubernetes.io/docs/concepts/services-networking/service/), and [StatefulSets](https://kubernetes.io/docs/concepts/workloads/controllers/statefulset/). In addition, you should: +To complete this tutorial, you should already have a basic familiarity with [Pods](/docs/concepts/workloads/pods/pod/), [Services](/docs/concepts/services-networking/service/), and [StatefulSets](/docs/concepts/workloads/controllers/statefulset/). In addition, you should: -* [Install and Configure](https://kubernetes.io/docs/tasks/tools/install-kubectl/) the `kubectl` command line +* [Install and Configure](/docs/tasks/tools/install-kubectl/) the `kubectl` command line -* Download [cassandra-service.yaml](https://kubernetes.io/docs/tutorials/stateful-application/cassandra-service.yaml) and [cassandra-statefulset.yaml](https://kubernetes.io/docs/tutorials/stateful-application/cassandra-statefulset.yaml) +* Download [cassandra-service.yaml](/docs/tutorials/stateful-application/cassandra/cassandra-service.yaml) and [cassandra-statefulset.yaml](/docs/tutorials/stateful-application/cassandra/cassandra-statefulset.yaml) * Have a supported Kubernetes Cluster running -**Note:** Please read the [getting started guides](https://kubernetes.io/docs/setup/pick-right-solution/) if you do not already have a cluster. +**Note:** Please read the [getting started guides](/docs/setup/pick-right-solution/) if you do not already have a cluster. {: .note} ### Additional Minikube Setup Instructions -**Caution:** [Minikube](https://kubernetes.io/docs/getting-started-guides/minikube/) defaults to 1024MB of memory and 1 CPU which results in an insufficient resource errors during this tutorial. +**Caution:** [Minikube](/docs/getting-started-guides/minikube/) defaults to 1024MB of memory and 1 CPU which results in an insufficient resource errors during this tutorial. {: .caution} To avoid these errors, run minikube with: @@ -91,7 +56,7 @@ To avoid these errors, run minikube with: {% capture lessoncontent %} ## Creating a Cassandra Headless Service -A Kubernetes [Service](https://kubernetes.io/docs/concepts/services-networking/service/) describes a set of [Pods](https://kubernetes.io/docs/concepts/workloads/pods/pod/) that perform the same task. +A Kubernetes [Service](/docs/concepts/services-networking/service/) describes a set of [Pods](/docs/concepts/workloads/pods/pod/) that perform the same task. The following `Service` is used for DNS lookups between Cassandra Pods and clients within the Kubernetes Cluster. @@ -100,7 +65,7 @@ The following `Service` is used for DNS lookups between Cassandra Pods and clien kubectl create -f cassandra-service.yaml -{% include code.html language="yaml" file="cassandra-service.yaml" ghlink="/docs/tutorials/stateful-application/cassandra-service.yaml" %} +{% include code.html language="yaml" file="cassandra/cassandra-service.yaml" ghlink="/docs/tutorials/stateful-application/cassandra/cassandra-service.yaml" %} ### Validating (optional) @@ -113,7 +78,7 @@ The response should be NAME CLUSTER-IP EXTERNAL-IP PORT(S) AGE cassandra None 9042/TCP 45s -If anything else returns, the service was not successfully created. Read [Debug Services](https://kubernetes.io/docs/tasks/debug-application-cluster/debug-service/) for common issues. +If anything else returns, the service was not successfully created. Read [Debug Services](/docs/tasks/debug-application-cluster/debug-service/) for common issues. ## Using a StatefulSet to Create a Cassandra Ring @@ -127,7 +92,7 @@ The StatefulSet manifest, included below, creates a Cassandra ring that consists kubectl create -f cassandra-statefulset.yaml -{% include code.html language="yaml" file="cassandra-statefulset.yaml" ghlink="/docs/tutorials/stateful-application/cassandra-statefulset.yaml" %} +{% include code.html language="yaml" file="cassandra/cassandra-statefulset.yaml" ghlink="/docs/tutorials/stateful-application/cassandra/cassandra-statefulset.yaml" %} ## Validating The Cassandra StatefulSet @@ -246,14 +211,10 @@ Deleting or scaling a StatefulSet down does not delete the volumes associated wi {% endcapture %} {% capture whatsnext %} -* Learn how to [Scale a StatefulSet](https://kubernetes.io/docs/tasks/run-application/scale-stateful-set/). +* Learn how to [Scale a StatefulSet](/docs/tasks/run-application/scale-stateful-set/). * Learn more about the [KubernetesSeedProvider](https://github.com/kubernetes/examples/blob/master/cassandra/java/src/main/java/io/k8s/cassandra/KubernetesSeedProvider.java) * See more custom [Seed Provider Configurations](https://git.k8s.io/examples/cassandra/java/README.md) {% endcapture %} {% include templates/tutorial.md %} - - -[![Analytics](https://kubernetes-site.appspot.com/UA-36037335-10/GitHub/cassandra/README.md?pixel)]() - \ No newline at end of file diff --git a/docs/tutorials/stateful-application/cassandra-service.yaml b/docs/tutorials/stateful-application/cassandra/cassandra-service.yaml similarity index 100% rename from docs/tutorials/stateful-application/cassandra-service.yaml rename to docs/tutorials/stateful-application/cassandra/cassandra-service.yaml diff --git a/docs/tutorials/stateful-application/cassandra-statefulset.yaml b/docs/tutorials/stateful-application/cassandra/cassandra-statefulset.yaml similarity index 100% rename from docs/tutorials/stateful-application/cassandra-statefulset.yaml rename to docs/tutorials/stateful-application/cassandra/cassandra-statefulset.yaml diff --git a/docs/tutorials/stateful-application/mysql-wordpress-persistent-volume.md b/docs/tutorials/stateful-application/mysql-wordpress-persistent-volume.md index 22cb8bd142..3dab51db28 100644 --- a/docs/tutorials/stateful-application/mysql-wordpress-persistent-volume.md +++ b/docs/tutorials/stateful-application/mysql-wordpress-persistent-volume.md @@ -1,48 +1,13 @@ --- title: "Example: Deploying WordPress and MySQL with Persistent Volumes" +assignees: +- ahmetb --- - - - {% capture overview %} This tutorial shows you how to deploy a WordPress site and a MySQL database using Minikube. Both applications use PersistentVolumes and PersistentVolumeClaims to store data. -A [PersistentVolume](https://kubernetes.io/docs/concepts/storage/persistent-volumes/) (PV) is a piece of storage in the cluster that has been provisioned by an administrator, and a [PeristentVolumeClaim](https://kubernetes.io/docs/concepts/storage/persistent-volumes/#persistentvolumeclaims) (PVC) is a set amout of storage in a PV. PersistentVolumes and PeristentVolumeClaims are independent from Pod lifecycles and preserve data through restarting, rescheduling, and even deleting Pods. +A [PersistentVolume](/docs/concepts/storage/persistent-volumes/) (PV) is a piece of storage in the cluster that has been provisioned by an administrator, and a [PeristentVolumeClaim](/docs/concepts/storage/persistent-volumes/#persistentvolumeclaims) (PVC) is a set amout of storage in a PV. PersistentVolumes and PeristentVolumeClaims are independent from Pod lifecycles and preserve data through restarting, rescheduling, and even deleting Pods. **Warning:** This deployment is not suitable for production use cases, as it uses single instance WordPress and MySQL Pods. Consider using [WordPress Helm Chart](https://github.com/kubernetes/charts/tree/master/stable/wordpress) to deploy WordPress in production. {: .warning} @@ -64,11 +29,11 @@ A [PersistentVolume](https://kubernetes.io/docs/concepts/storage/persistent-volu Download the following configuration files: -1. [local-volumes.yaml](https://kubernetes.io/docs/tutorials/stateful-application/mysql-wordpress-persistent-volume/local-volumes.yaml) +1. [local-volumes.yaml](/docs/tutorials/stateful-application/mysql-wordpress-persistent-volume/local-volumes.yaml) -1. [mysql-deployment.yaml](https://kubernetes.io/docs/tutorials/stateful-application/mysql-wordpress-persistent-volume/mysql-deployment.yaml) +1. [mysql-deployment.yaml](/docs/tutorials/stateful-application/mysql-wordpress-persistent-volume/mysql-deployment.yaml) -1. [wordpress-deployment.yaml](https://kubernetes.io/docs/tutorials/stateful-application/mysql-wordpress-persistent-volume//wordpress-deployment.yaml) +1. [wordpress-deployment.yaml](/docs/tutorials/stateful-application/mysql-wordpress-persistent-volume/wordpress-deployment.yaml) {% endcapture %} @@ -76,7 +41,7 @@ Download the following configuration files: ## Create a PersistentVolume -MySQL and Wordpress each use a PersistentVolume to store data. While Kubernetes supports many different [types of PersistentVolumes](https://kubernetes.io/docs/concepts/storage/persistent-volumes/#types-of-persistent-volumes), this tutorial covers [hostPath](https://kubernetes.io/docs/concepts/storage/volumes/#hostpath). +MySQL and Wordpress each use a PersistentVolume to store data. While Kubernetes supports many different [types of PersistentVolumes](/docs/concepts/storage/persistent-volumes/#types-of-persistent-volumes), this tutorial covers [hostPath](/docs/concepts/storage/volumes/#hostpath). **Note:** If you have a Kubernetes cluster running on Google Container Engine, please follow [this guide](https://cloud.google.com/container-engine/docs/tutorials/persistent-disk). {: .note} @@ -109,7 +74,7 @@ A `hostPath` mounts a file or directory from the host node’s filesystem into y ## Create a Secret for MySQL Password -A [Secret](https://kubernetes.io/docs/concepts/configuration/secret/) is an object that stores a piece of sensitive data like a password or key. The manifest files are already configured to use a Secret, but you have to create your own Secret. +A [Secret](/docs/concepts/configuration/secret/) is an object that stores a piece of sensitive data like a password or key. The manifest files are already configured to use a Secret, but you have to create your own Secret. 1. Create the Secret object from the following command: @@ -216,15 +181,11 @@ The following manifest describes a single-instance WordPress Deployment and Serv {% capture whatsnext %} -* Learn more about [Introspection and Debugging](https://kubernetes.io/docs/tasks/debug-application-cluster/debug-application-introspection/) -* Learn more about [Jobs](https://kubernetes.io/docs/concepts/workloads/controllers/jobs-run-to-completion/) -* Learn more about [Port Forwarding](https://kubernetes.io/docs/tasks/access-application-cluster/port-forward-access-application-cluster/) -* Learn how to [Get a Shell to a Container](https://kubernetes.io/docs/tasks/debug-application-cluster/get-shell-running-container/) +* Learn more about [Introspection and Debugging](/docs/tasks/debug-application-cluster/debug-application-introspection/) +* Learn more about [Jobs](/docs/concepts/workloads/controllers/jobs-run-to-completion/) +* Learn more about [Port Forwarding](/docs/tasks/access-application-cluster/port-forward-access-application-cluster/) +* Learn how to [Get a Shell to a Container](/docs/tasks/debug-application-cluster/get-shell-running-container/) {% endcapture %} {% include templates/tutorial.md %} - - -[![Analytics](https://kubernetes-site.appspot.com/UA-36037335-10/GitHub/examples/mysql-wordpress-pd/README.md?pixel)]() - \ No newline at end of file diff --git a/docs/tutorials/stateless-application/guestbook.md b/docs/tutorials/stateless-application/guestbook.md index ca47e5d16e..ec394ecb72 100644 --- a/docs/tutorials/stateless-application/guestbook.md +++ b/docs/tutorials/stateless-application/guestbook.md @@ -1,44 +1,9 @@ --- title: "Example: Deploying PHP Guestbook application with Redis" +assignees: +- ahmetb --- - - - {% capture overview %} This tutorial shows you how to build and deploy a simple, multi-tier web application using Kubernetes and [Docker](https://www.docker.com/). This example consists of the following components: @@ -61,12 +26,12 @@ This tutorial shows you how to build and deploy a simple, multi-tier web applica {% include task-tutorial-prereqs.md %} Download the following configuration files: -1. [redis-master-deployment.yaml](https://kubernetes.io/docs/tutorials/stateless-application/guestbook/redis-master-deployment.yaml) -1. [redis-master-service.yaml](https://kubernetes.io/docs/tutorials/stateless-application/guestbook/redis-master-service.yaml) -1. [redis-slave-deployment.yaml](https://kubernetes.io/docs/tutorials/stateless-application/guestbook/redis-slave-deployment.yaml) -1. [redis-slave-service.yaml](https://kubernetes.io/docs/tutorials/stateless-application/guestbook/redis-slave-service.yaml) -1. [frontend-deployment.yaml](https://kubernetes.io/docs/tutorials/stateless-application/guestbook/frontend-deployment.yaml) -1. [frontend-service.yaml](https://kubernetes.io/docs/tutorials/stateless-application/guestbook/frontend-service.yaml) +1. [redis-master-deployment.yaml](/docs/tutorials/stateless-application/guestbook/redis-master-deployment.yaml) +1. [redis-master-service.yaml](/docs/tutorials/stateless-application/guestbook/redis-master-service.yaml) +1. [redis-slave-deployment.yaml](/docs/tutorials/stateless-application/guestbook/redis-slave-deployment.yaml) +1. [redis-slave-service.yaml](/docs/tutorials/stateless-application/guestbook/redis-slave-service.yaml) +1. [frontend-deployment.yaml](/docs/tutorials/stateless-application/guestbook/frontend-deployment.yaml) +1. [frontend-service.yaml](/docs/tutorials/stateless-application/guestbook/frontend-service.yaml) {% endcapture %} @@ -105,7 +70,7 @@ The manifest file, included below, specifies a Deployment controller that runs a ### Creating the Redis Master Service -The guestbook applications needs to communicate to the Redis master to write its data. You need to apply a [Service](https://kubernetes.io/docs/concepts/services-networking/service/) to proxy the traffic to the Redis master Pod. A Service defines a policy to access the Pods. +The guestbook applications needs to communicate to the Redis master to write its data. You need to apply a [Service](/docs/concepts/services-networking/service/) to proxy the traffic to the Redis master Pod. A Service defines a policy to access the Pods. 1. Apply the Redis Master Service from the following `redis-master-service.yaml` file: @@ -199,7 +164,7 @@ The guestbook application has a web frontend serving the HTTP requests written i ### Creating the Frontend Service -The `redis-slave` and `redis-master` Services you applied are only accessible within the container cluster because the default type for a Service is [ClusterIP](https://kubernetes.io/docs/concepts/services-networking/service/#publishing-services---service-types). `ClusterIP` provides a single IP address for the set of Pods the Service is pointing to. This IP address is accessible only within the cluster. +The `redis-slave` and `redis-master` Services you applied are only accessible within the container cluster because the default type for a Service is [ClusterIP](/docs/concepts/services-networking/service/#publishing-services---service-types). `ClusterIP` provides a single IP address for the set of Pods the Service is pointing to. This IP address is accessible only within the cluster. If you want guests to be able to access your guestbook, you must configure the frontend Service to be externally visible, so a client can request the Service from outside the container cluster. Minikube can only expose Services through `NodePort`. @@ -326,13 +291,10 @@ Deleting the Deployments and Services also deletes any running Pods. Use labels {% endcapture %} {% capture whatsnext %} -* Complete the [Kubernetes Basics](https://kubernetes.io//docs/tutorials/kubernetes-basics/) Interactive Tutorials -* Use Kubernetes to create a blog using [Persistant Volumes for MySQL and Wordpress](https://kubernetes.io/docs/tutorials/stateful-application/mysql-wordpress-persistent-volume/#visit-your-new-wordpress-blog) -* Read more about [connecting applications](https://kubernetes.io/docs/concepts/services-networking/connect-applications-service/) -* Read more about [Managing Resources](https://kubernetes.io/docs/concepts/cluster-administration/manage-deployment/#using-labels-effectively) +* Complete the [Kubernetes Basics](/docs/tutorials/kubernetes-basics/) Interactive Tutorials +* Use Kubernetes to create a blog using [Persistant Volumes for MySQL and Wordpress](/docs/tutorials/stateful-application/mysql-wordpress-persistent-volume/#visit-your-new-wordpress-blog) +* Read more about [connecting applications](/docs/concepts/services-networking/connect-applications-service/) +* Read more about [Managing Resources](/docs/concepts/cluster-administration/manage-deployment/#using-labels-effectively) {% endcapture %} -{% include templates/tutorial.md %} - -[![Analytics](https://kubernetes-site.appspot.com/UA-36037335-10/GitHub/examples/guestbook/README.md?pixel)]() - +{% include templates/tutorial.md %} diff --git a/update-imported-tutorials.py b/update-imported-tutorials.py deleted file mode 100755 index 81b14181f6..0000000000 --- a/update-imported-tutorials.py +++ /dev/null @@ -1,149 +0,0 @@ -#!/usr/bin/env python3 -# -*- coding: utf-8 -*- - -# Copyright 2017 The Kubernetes 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. - -"""This program imports the tutorials from -https://github.com/kubernetes/examples and makes necessary modifications to -check them in as Jekyll-compatible documentation pages. -""" - -import os.path -import shutil -import urllib.request - -SRC_REPO = 'kubernetes/examples' -SRC_TREE = 'master' - -# mapping of tutorials in kubernetes/examples to their -# equivalent files here: (examples-path, docs-path, new-title, imports-map) -TUTORIALS = [ - ('guestbook/README.md', - './docs/tutorials/stateless-application/guestbook.md', - "Example: Deploying PHP Guestbook application with Redis", { - "guestbook/redis-master-deployment.yaml" : "./docs/tutorials/stateless-application/guestbook/redis-master-deployment.yaml", - "guestbook/redis-master-service.yaml" : "./docs/tutorials/stateless-application/guestbook/redis-master-service.yaml", - "guestbook/redis-slave-deployment.yaml" : "./docs/tutorials/stateless-application/guestbook/redis-slave-deployment.yaml", - "guestbook/redis-slave-service.yaml" : "./docs/tutorials/stateless-application/guestbook/redis-slave-service.yaml", - "guestbook/frontend-deployment.yaml" : "./docs/tutorials/stateless-application/guestbook/frontend-deployment.yaml", - "guestbook/frontend-service.yaml" : "./docs/tutorials/stateless-application/guestbook/frontend-service.yaml", - }), - ('mysql-wordpress-pd/README.md', - './docs/tutorials/stateful-application/mysql-wordpress-persistent-volume.md', - "Example: Deploying WordPress and MySQL with Persistent Volumes", - { - "mysql-wordpress-pd/local-volumes.yaml": "./docs/tutorials/stateful-application/mysql-wordpress-persistent-volume/local-volumes.yaml", - "mysql-wordpress-pd/mysql-deployment.yaml": "./docs/tutorials/stateful-application/mysql-wordpress-persistent-volume/mysql-deployment.yaml", - "mysql-wordpress-pd/wordpress-deployment.yaml": "./docs/tutorials/stateful-application/mysql-wordpress-persistent-volume/wordpress-deployment.yaml", - }), - ('cassandra/README.md', - './docs/tutorials/stateful-application/cassandra.md', - "Example: Deploying Cassandra with Stateful Sets", - { - "cassandra/cassandra-service.yaml": "./docs/tutorials/stateful-application/cassandra-service.yaml", - "cassandra/cassandra-statefulset.yaml": "./docs/tutorials/stateful-application/cassandra-statefulset.yaml", - }), -] - - -def main(): - for (src_path, dst_path, new_title, imports) in TUTORIALS: - print('Processing {0}'.format(src_path)) - - imports[src_path] = dst_path # add source itself as import file - for src_path, dst_path in imports.items(): - src_url = 'https://github.com/{0}/raw/{1}/{2}'.format(SRC_REPO, - SRC_TREE, src_path) - dst_dir = os.path.dirname(dst_path) - if not os.path.exists(dst_dir): - print('Creating directory {0}.'.format(dst_dir)) - os.makedirs(dst_dir) - - print('Downloading {0}'.format(src_url)) - with urllib.request.urlopen(src_url) as resp, \ - open(dst_path, 'wb') as out_file: - shutil.copyfileobj(resp, out_file) - print('Saved to {0}'.format(dst_path)) - - print('Processing {0}'.format(dst_path)) - remove_excluded_snippets(dst_path) - insert_do_not_update(dst_path) - insert_title(dst_path, new_title) - print('Processed {0}'.format(dst_path)) - - -def remove_excluded_snippets(path): - """Remove content between '' and - '' markers (including the markers) - in the specified file. Markers must appear on their own lines.""" - - marker_begin = '\n' - marker_end = '\n' - - new_lines = [] - started = False - excluded_blocks = 0 - with open(path, 'r') as f: - for line_no, line in enumerate(f): - ref = '{0}:{1}'.format(path, line_no) - if (marker_begin.rstrip('\n') in line and - (line != marker_begin and line != marker_end.rstrip('\n'))) or \ - (marker_end.rstrip('\n') in line and (line != marker_end and - line != marker_end.rstrip('\n'))): - raise Exception('{0}: EXCLUDE_FROM_DOCS marker must be on its own line'.format(ref)) - if not started: - if line == marker_end: - raise Exception('{0}: encountered END before BEGIN'.format(ref)) - elif line == marker_begin: - started = True - else: - new_lines.append(line.rstrip('\n')) - else: - if line == marker_begin: - raise Exception('{0}: encountered BEGIN again before END'.format(ref)) - elif line == marker_end: - started = False - excluded_blocks += 1 - else: - continue - if started: - raise Exception('encountered EOF before END') - print('{0} EXCLUDE_FROM_DOCS blocks removed.'.format(excluded_blocks)) - with open(path, 'w') as f: - f.write('\n'.join(new_lines)) - - -def insert_title(path, title): - """Inserts title in Jekyll metadata format to the file.""" - prepend_file(path, '---\ntitle: "{0}"\n---\n\n'.format(title)) - - -def insert_do_not_update(path): - notice = '\n\n' - prepend_file(path, notice) - - -def prepend_file(path, ss): - with open(path, 'r') as f: - for line in f: - ss += line - with open(path, 'w') as f: - f.write(ss) - -if __name__ == '__main__': - main()