Skip to content

Commit

Permalink
Merge pull request #11424 from lavalamp/mungePreformatted
Browse files Browse the repository at this point in the history
Munge preformatted
  • Loading branch information
ArtfulCoder committed Jul 17, 2015
2 parents 3ae4a02 + 2c04668 commit 816f18a
Show file tree
Hide file tree
Showing 95 changed files with 629 additions and 23 deletions.
1 change: 1 addition & 0 deletions cmd/mungedocs/mungedocs.go
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ Examples:
allMunges = []munge{
{"table-of-contents", updateTOC},
{"check-links", checkLinks},
{"blank-lines-surround-preformatted", checkPreformatted},
{"unversioned-warning", updateUnversionedWarning},
{"analytics", checkAnalytics},
{"kubectl-dash-f", checkKubectlFileTargets},
Expand Down
57 changes: 57 additions & 0 deletions cmd/mungedocs/preformatted.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
/*
Copyright 2015 The Kubernetes 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.
*/

package main

import (
"bytes"
)

// Blocks of ``` need to have blank lines on both sides or they don't look
// right in HTML.
func checkPreformatted(filePath string, fileBytes []byte) ([]byte, error) {
f := splitByPreformatted(fileBytes)
f = append(fileBlocks{{false, []byte{}}}, f...)
f = append(f, fileBlock{false, []byte{}})

output := []byte(nil)
for i := 1; i < len(f)-1; i++ {
prev := &f[i-1]
block := &f[i]
next := &f[i+1]
if !block.preformatted {
continue
}
neededSuffix := []byte("\n\n")
for !bytes.HasSuffix(prev.data, neededSuffix) {
prev.data = append(prev.data, '\n')
}
for !bytes.HasSuffix(block.data, neededSuffix) {
block.data = append(block.data, '\n')
if bytes.HasPrefix(next.data, []byte("\n")) {
// don't change the number of newlines unless needed.
next.data = next.data[1:]
if len(next.data) == 0 {
f = append(f[:i+1], f[i+2:]...)
}
}
}
}
for _, block := range f {
output = append(output, block.data...)
}
return output, nil
}
53 changes: 39 additions & 14 deletions cmd/mungedocs/util.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,9 @@ import (

var (
// Finds all preformatted block start/stops.
preformatRE = regexp.MustCompile("^```.*")
preformatRE = regexp.MustCompile("^[\\s]*```.*")
notPreformatRE = regexp.MustCompile("^[\\s]*```.*```.*")
preformatEndRE = regexp.MustCompile(".*```.*")
)

// Splits a document up into a slice of lines.
Expand Down Expand Up @@ -120,35 +122,58 @@ func endMungeTag(desc string) string {
// Calls 'replace' for all sections of the document not in ``` / ``` blocks. So
// that you don't have false positives inside those blocks.
func replaceNonPreformatted(input []byte, replace func([]byte) []byte) []byte {
f := splitByPreformatted(input)
output := []byte(nil)
for _, block := range f {
if block.preformatted {
output = append(output, block.data...)
} else {
output = append(output, replace(block.data)...)
}
}
return output
}

type fileBlock struct {
preformatted bool
data []byte
}

type fileBlocks []fileBlock

func splitByPreformatted(input []byte) fileBlocks {
f := fileBlocks{}

cur := []byte(nil)
keepBlock := true
preformatted := false
// SplitAfter keeps the newline, so you don't have to worry about
// omitting it on the last line or anything. Also, the documentation
// claims it's unicode safe.
for _, line := range bytes.SplitAfter(input, []byte("\n")) {
if keepBlock {
if preformatRE.Match(line) {
cur = replace(cur)
output = append(output, cur...)
if !preformatted {
if preformatRE.Match(line) && !notPreformatRE.Match(line) {
if len(cur) > 0 {
f = append(f, fileBlock{false, cur})
}
cur = []byte{}
keepBlock = false
preformatted = true
}
cur = append(cur, line...)
} else {
cur = append(cur, line...)
if preformatRE.Match(line) {
output = append(output, cur...)
if preformatEndRE.Match(line) {
if len(cur) > 0 {
f = append(f, fileBlock{true, cur})
}
cur = []byte{}
keepBlock = true
preformatted = false
}
}
}
if keepBlock {
cur = replace(cur)
if len(cur) > 0 {
f = append(f, fileBlock{preformatted, cur})
}
output = append(output, cur...)
return output
return f
}

// As above, but further uses exp to parse the non-preformatted sections.
Expand Down
4 changes: 2 additions & 2 deletions cmd/mungedocs/util_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -161,8 +161,8 @@ func TestReplaceNonPreformattedCallOrder(t *testing.T) {
{"aoeu\n\n```\n\naoeu\n\n```\n\naoeu", []string{"aoeu\n\n", "\naoeu"}},
{"ao\neu\n```\naoeu\n\n\n", []string{"ao\neu\n"}},
{"aoeu ```aoeu``` aoeu", []string{"aoeu ```aoeu``` aoeu"}},
{"aoeu\n```\naoeu\n```", []string{"aoeu\n", ""}},
{"aoeu\n```\naoeu\n```\n", []string{"aoeu\n", ""}},
{"aoeu\n```\naoeu\n```", []string{"aoeu\n"}},
{"aoeu\n```\naoeu\n```\n", []string{"aoeu\n"}},
{"aoeu\n```\naoeu\n```\n\n", []string{"aoeu\n", "\n"}},
}

Expand Down
2 changes: 2 additions & 0 deletions docs/admin/authorization.md
Original file line number Diff line number Diff line change
Expand Up @@ -116,11 +116,13 @@ To permit an action Policy with an unset namespace applies regardless of namespa

Other implementations can be developed fairly easily.
The APIserver calls the Authorizer interface:

```go
type Authorizer interface {
Authorize(a Attributes) error
}
```

to determine whether or not to allow each API action.

An authorization plugin is a module that implements this interface.
Expand Down
1 change: 1 addition & 0 deletions docs/admin/cluster-large.md
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@ To avoid running into cloud provider quota issues, when creating a cluster with
To prevent memory leaks or other resource issues in [cluster addons](../../cluster/addons/) from consuming all the resources available on a node, Kubernetes sets resource limits on addon containers to limit the CPU and Memory resources they can consume (See PR [#10653](https://github.com/GoogleCloudPlatform/kubernetes/pull/10653/files) and [#10778](https://github.com/GoogleCloudPlatform/kubernetes/pull/10778/files)).

For example:

```YAML
containers:
- image: gcr.io/google_containers/heapster:v0.15.0
Expand Down
1 change: 1 addition & 0 deletions docs/admin/cluster-troubleshooting.md
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ You may also visit [troubleshooting document](../troubleshooting.md) for more in
The first thing to debug in your cluster is if your nodes are all registered correctly.

Run

```
kubectl get nodes
```
Expand Down
6 changes: 4 additions & 2 deletions docs/admin/high-availability.md
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,7 @@ for ```${NODE_IP}``` on each machine.

#### Validating your cluster
Once you copy this into all three nodes, you should have a clustered etcd set up. You can validate with

```
etcdctl member list
```
Expand Down Expand Up @@ -209,11 +210,12 @@ master election. On each of the three apiserver nodes, we run a small utility a
election protocol using etcd "compare and swap". If the apiserver node wins the election, it starts the master component it is managing (e.g. the scheduler), if it
loses the election, it ensures that any master components running on the node (e.g. the scheduler) are stopped.

In the future, we expect to more tightly integrate this lease-locking into the scheduler and controller-manager binaries directly, as described in the [high availability design proposal](proposals/high-availability.md)
In the future, we expect to more tightly integrate this lease-locking into the scheduler and controller-manager binaries directly, as described in the [high availability design proposal](../proposals/high-availability.md)

### Installing configuration files

First, create empty log files on each node, so that Docker will mount the files not make new directories:

```
touch /var/log/kube-scheduler.log
touch /var/log/kube-controller-manager.log
Expand Down Expand Up @@ -244,7 +246,7 @@ set the ```--apiserver``` flag to your replicated endpoint.

##Vagrant up!

We indeed have an initial proof of concept tester for this, which is available [here](../examples/high-availability/).
We indeed have an initial proof of concept tester for this, which is available [here](../../examples/high-availability/).

It implements the major concepts (with a few minor reductions for simplicity), of the podmaster HA implementation alongside a quick smoke test using k8petstore.

Expand Down
1 change: 1 addition & 0 deletions docs/admin/networking.md
Original file line number Diff line number Diff line change
Expand Up @@ -152,6 +152,7 @@ outbound internet access. A linux bridge (called `cbr0`) is configured to exist
on that subnet, and is passed to docker's `--bridge` flag.

We start Docker with:

```
DOCKER_OPTS="--bridge=cbr0 --iptables=false --ip-masq=false"
```
Expand Down
5 changes: 5 additions & 0 deletions docs/admin/node.md
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,7 @@ setting the Status of the condition, has not heard from the
node recently (currently 40 seconds).
Node condition is represented as a json object. For example,
the following conditions mean the node is in sane state:

```json
"conditions": [
{
Expand Down Expand Up @@ -133,6 +134,7 @@ or from your pool of physical or virtual machines. What this means is that when
Kubernetes creates a node, it is really just creating an object that represents the node in its internal state.
After creation, Kubernetes will check whether the node is valid or not.
For example, if you try to create a node from the following content:

```json
{
"kind": "Node",
Expand Down Expand Up @@ -204,6 +206,7 @@ Making a node unscheduleable will prevent new pods from being scheduled to that
node, but will not affect any existing pods on the node. This is useful as a
preparatory step before a node reboot, etc. For example, to mark a node
unschedulable, run this command:

```
kubectl replace nodes 10.1.2.3 --patch='{"apiVersion": "v1", "unschedulable": true}'
```
Expand All @@ -222,6 +225,7 @@ processes not in containers.

If you want to explicitly reserve resources for non-Pod processes, you can create a placeholder
pod. Use the following template:

```
apiVersion: v1
kind: Pod
Expand All @@ -236,6 +240,7 @@ spec:
cpu: 100m
memory: 100Mi
```

Set the `cpu` and `memory` values to the amount of resources you want to reserve.
Place the file in the manifest directory (`--config=DIR` flag of kubelet). Do this
on each kubelet where you want to reserve resources.
Expand Down
1 change: 1 addition & 0 deletions docs/admin/resource-quota.md
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,7 @@ This means the resource must have a fully-qualified name (i.e. mycompany.org/shi

## Viewing and Setting Quotas
Kubectl supports creating, updating, and viewing quotas

```
$ kubectl namespace myspace
$ cat <<EOF > quota.json
Expand Down
1 change: 1 addition & 0 deletions docs/admin/salt.md
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ Each salt-minion service is configured to interact with the **salt-master** serv
[root@kubernetes-master] $ cat /etc/salt/minion.d/master.conf
master: kubernetes-master
```

The salt-master is contacted by each salt-minion and depending upon the machine information presented, the salt-master will provision the machine as either a kubernetes-master or kubernetes-minion with all the required capabilities needed to run Kubernetes.

If you are running the Vagrant based environment, the **salt-api** service is running on the kubernetes-master. It is configured to enable the vagrant user to introspect the salt cluster in order to find out about machines in the Vagrant environment via a REST API.
Expand Down
1 change: 1 addition & 0 deletions docs/admin/service-accounts-admin.md
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,7 @@ $ kubectl describe secret mysecretname
```

#### To delete/invalidate a service account token

```
kubectl delete secret mysecretname
```
Expand Down
2 changes: 1 addition & 1 deletion docs/design/admission_control_limit_range.md
Original file line number Diff line number Diff line change
Expand Up @@ -164,7 +164,7 @@ It is expected we will want to define limits for particular pods or containers b
To make a **LimitRangeItem** more restrictive, we will intend to add these additional restrictions at a future point in time.

## Example
See the [example of Limit Range](../user-guide/limitrange) for more information.
See the [example of Limit Range](../user-guide/limitrange/) for more information.


<!-- BEGIN MUNGE: GENERATED_ANALYTICS -->
Expand Down
2 changes: 1 addition & 1 deletion docs/design/admission_control_resource_quota.md
Original file line number Diff line number Diff line change
Expand Up @@ -185,7 +185,7 @@ services 3 5
```

## More information
See [resource quota document](../admin/resource-quota.md) and the [example of Resource Quota](../user-guide/resourcequota) for more information.
See [resource quota document](../admin/resource-quota.md) and the [example of Resource Quota](../user-guide/resourcequota/) for more information.


<!-- BEGIN MUNGE: GENERATED_ANALYTICS -->
Expand Down
1 change: 1 addition & 0 deletions docs/design/event_compression.md
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,7 @@ Each binary that generates events:

## Example
Sample kubectl output

```
FIRSTSEEN LASTSEEN COUNT NAME KIND SUBOBJECT REASON SOURCE MESSAGE
Thu, 12 Feb 2015 01:13:02 +0000 Thu, 12 Feb 2015 01:13:02 +0000 1 kubernetes-minion-4.c.saad-dev-vms.internal Minion starting {kubelet kubernetes-minion-4.c.saad-dev-vms.internal} Starting kubelet.
Expand Down
7 changes: 7 additions & 0 deletions docs/design/resources.md
Original file line number Diff line number Diff line change
Expand Up @@ -87,23 +87,27 @@ Internally (i.e., everywhere else), Kubernetes will represent resource quantitie
Both users and a number of system components, such as schedulers, (horizontal) auto-scalers, (vertical) auto-sizers, load balancers, and worker-pool managers need to reason about resource requirements of workloads, resource capacities of nodes, and resource usage. Kubernetes divides specifications of *desired state*, aka the Spec, and representations of *current state*, aka the Status. Resource requirements and total node capacity fall into the specification category, while resource usage, characterizations derived from usage (e.g., maximum usage, histograms), and other resource demand signals (e.g., CPU load) clearly fall into the status category and are discussed in the Appendix for now.

Resource requirements for a container or pod should have the following form:

```
resourceRequirementSpec: [
request: [ cpu: 2.5, memory: "40Mi" ],
limit: [ cpu: 4.0, memory: "99Mi" ],
]
```

Where:
* _request_ [optional]: the amount of resources being requested, or that were requested and have been allocated. Scheduler algorithms will use these quantities to test feasibility (whether a pod will fit onto a node). If a container (or pod) tries to use more resources than its _request_, any associated SLOs are voided &mdash; e.g., the program it is running may be throttled (compressible resource types), or the attempt may be denied. If _request_ is omitted for a container, it defaults to _limit_ if that is explicitly specified, otherwise to an implementation-defined value; this will always be 0 for a user-defined resource type. If _request_ is omitted for a pod, it defaults to the sum of the (explicit or implicit) _request_ values for the containers it encloses.

* _limit_ [optional]: an upper bound or cap on the maximum amount of resources that will be made available to a container or pod; if a container or pod uses more resources than its _limit_, it may be terminated. The _limit_ defaults to "unbounded"; in practice, this probably means the capacity of an enclosing container, pod, or node, but may result in non-deterministic behavior, especially for memory.

Total capacity for a node should have a similar structure:

```
resourceCapacitySpec: [
total: [ cpu: 12, memory: "128Gi" ]
]
```

Where:
* _total_: the total allocatable resources of a node. Initially, the resources at a given scope will bound the resources of the sum of inner scopes.

Expand Down Expand Up @@ -149,6 +153,7 @@ rather than decimal ones: "64MiB" rather than "64MB".

## Resource metadata
A resource type may have an associated read-only ResourceType structure, that contains metadata about the type. For example:

```
resourceTypes: [
"kubernetes.io/memory": [
Expand Down Expand Up @@ -194,6 +199,7 @@ resourceStatus: [
```

where a `<CPU-info>` or `<memory-info>` structure looks like this:

```
{
mean: <value> # arithmetic mean
Expand All @@ -209,6 +215,7 @@ where a `<CPU-info>` or `<memory-info>` structure looks like this:
]
}
```

All parts of this structure are optional, although we strongly encourage including quantities for 50, 90, 95, 99, 99.5, and 99.9 percentiles. _[In practice, it will be important to include additional info such as the length of the time window over which the averages are calculated, the confidence level, and information-quality metrics such as the number of dropped or discarded data points.]_
and predicted

Expand Down
1 change: 1 addition & 0 deletions docs/design/security_context.md
Original file line number Diff line number Diff line change
Expand Up @@ -179,6 +179,7 @@ type SELinuxOptions struct {
Level string
}
```

### Admission

It is up to an admission plugin to determine if the security context is acceptable or not. At the
Expand Down
1 change: 1 addition & 0 deletions docs/design/service_accounts.md
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@ A service account binds together several things:
## Design Discussion

A new object Kind is added:

```go
type ServiceAccount struct {
TypeMeta `json:",inline" yaml:",inline"`
Expand Down
Loading

0 comments on commit 816f18a

Please sign in to comment.