Tipps und Tricks für Entwickler und IT-Interessierte
The javascript library jsPDF, is a Client-side JavaScript PDF generation for everyone.
With a npm-Module, you can integrate this functionality into your Ionic App.
This Git Repository with the code for this blog is here.
❯ mkdir Ionic_Working-with_jsPDF ❯ cd Ionic_Working-with_jsPDF
❯ ionic start app sidemenu --type angular √ Preparing directory .app in 2.63ms √ Downloading and extracting sidemenu starter in 665.67ms ? Integrate your new app with Capacitor to target native iOS and Android? No
❯ cd app
❯ npm install jspdf ❯ npm install @types/jspdf
oder
❯ yarn add jspdf ❯ yarn add @types/jspdf
❯ vscode . ❯ ionic serve
❯ ionic generate page pages/PDF
Edit app.components.t
s
public appPages = [ { title: 'PDF', url: '/pdf', icon: print' }, { title: 'Inbox', url: '/folder/Inbox', icon: 'mail', },
Add jspfs reference to pages/pdf/pdf.page.ts
import { jsPDF } from 'jspdf';
Create a function for converting to PDF
public downloadPDF() { var data = document.getElementById('printcontent') as HTMLElement; let pdf = new jsPDF('p', 'mm', 'a4'); pdf.html(data, { callback: (pdf) => {pdf.output('dataurlnewwindow');} }); }
Change pages/pdf/pdfhtml
<div> <input type="button" value="Convert" (click)="downloadPDF()" /> </div>
A lot more examples could be found in my repository. Just create a starter app with this template and begin to play
❯ pip install django==3.2.8
❯ pip install --pre django
❯ python -m django --version
❯ django-admin.exe version
The following steps are based on a summary of the Django Tutorial
django-admin startproject main cd working_with_django python manage.py migrate python manage.py runserver 8080 python manage.py startapp app_base
from django.http import HttpResponse def index(request): return HttpResponse("Hello, world. You're at the polls index.")
from django.urls import path from . import views urlpatterns = [ path('', views.index, name='index'), ]
from django.contrib import admin from django.urls import include, path urlpatterns = [ path('admin/', admin.site.urls), path('app_base/', include('app_base.urls')), ]
$ python manage.py createsuperuser Username (leave blank to use 'user'): admin Email address: admin@localhost Password: Password (again): Superuser created successfully.
from django.db import models class Question(models.Model): question_text = models.CharField(max_length=200) pub_date = models.DateTimeField('date published') class Choice(models.Model): question = models.ForeignKey(Question, on_delete=models.CASCADE) choice_text = models.CharField(max_length=200) votes = models.IntegerField(default=0)
INSTALLED_APPS = [ 'app_base.apps.AppBaseConfig', 'django.contrib.admin', 'django.contrib.auth', 'django.contrib.contenttypes', 'django.contrib.sessions', 'django.contrib.messages', 'django.contrib.staticfiles', ]
$ python manage.py makemigrations app_base $ python manage.py sqlmigrate app_base 0001
from django.contrib import admin from .models import Question admin.site.register(Question)
def detail(request, question_id): return HttpResponse("You're looking at question def results(request, question_id): response = "You're looking at the results of question return HttpResponse(response def vote(request, question_id): return HttpResponse("You're voting on question
app_base/urls.py
from django.urls import path from . import views urlpatterns = [ path('', views.index, name='index'), path('<int:question_id>/', views.detail, name='detail'), path('<int:question_id>/results/', views.results, name='results'), path('<int:question_id>/vote/', views.vote, name='vote'), ]
<ul> <li><a href="/polls/{{ question.id }}/">{{ question.question_text }}</a></li> </ul> <p>No polls are available.</p>Modify view in app_base/views.py
from django.shortcuts import render ... def index(request): latest_question_list = Question.objects.order_by('-pub_date')[:5] context = {'latest_question_list': latest_question_list} return render(request, 'polls/index.html', context)Raising a 404 error in app_base/views.py
from django.http import HttpResponse from django.shortcuts import render, get_object_or_404 from .models import Question # ... def detail(request, question_id): question = get_object_or_404(Question, pk=question_id) return render(request, 'polls/detail.html', {'question': question})Create template
app_base/templates/polls/detail.html
<h1>{{ question.question_text }}</h1> <ul> <li>{{ choice.choice_text }}</li> </ul>Removing hardcoded URLs in
app_base/templates/polls/index.html
<li> <a href=" </li>The way this works is by looking up the URL definition as specified in the app_base/urs.py
... # the 'name' value as called by the path('<int:question_id>/', views.detail, name='detail'), ...Namespacing URL names in
app_base/urls.py
app_name = 'app_base' urlpatterns = [ ...Then, modify link in
app_base/templates/polls/index.html
from url ‘detail’ to url ‘app_base:detail’
<li> <a href=" </li>Use generic views: Less code is better
Create class in
a
pp_views/views.pyclass HomeView(generic.TemplateView): template_name = 'index.html'Create template
app_views/templates/index.html
<h1>App Views:</h1> WelcomeModify
app_views/urls.py
urlpatterns = [ path('', views.HomeView.as_view(), name='home'), ]Add another app to main project
Create app
$ python manage.py startapp app_viewModify
main/urls.py
urlpatterns = [ path('admin/', admin.site.urls), path('app_base/', include('app_base.urls')), path('app_views/', include('app_views.urls')), ]Add data model in
app_views/models.py
from django.db import models class DataItem(models.Model): text = models.CharField(max_length=200) data = models.IntegerField(default=0) def __str__(self): return self.textRegister data in
app_views/admin.py
from django.contrib import admin from .models import DataItem admin.site.register(DataItem)Activate models
$ python manage.py makemigrations app_views $ python manage.py sqlmigrate app_views 0001 $ python manage.py migrate app_viewsNavigation / Redirection
Set root page of Django project
When accessing your Django project, the root page will normaly doesn’n show your app homepage.
To change this, you hate to modiy the url handling.
In the following sample, replace <appname> with the name of your app
Define a redirection view in your app (/<appname>/urls.py)
def redirect_to_home(request): return redirect('/<appname>')Define path in the global urls.py (/main/urls.py)
from django.contrib import admin from django.urls import include, path from django.shortcuts import redirect from <appname> import views urlpatterns = [ path('', views.redirect_to_home, name='home'), path('<appname>/', include('<appname>.urls')), path('admin/', admin.site.urls) ]Highlight current page in navigation menu
<div class="list-group"> <a href=" Basic Upload </a> <a href=" Progress Bar Upload </a> </div>Using PostgresSQL Database
Install PostgresSQL
Create Superuser
createuser.exe --interactive --pwpromptLogging
Additional reading
Tutorials
The template system is using a search approach to find the specified template file, e.g. ‘home.html’.
If you created more than one apps with the same filenames for templates, the first one will be used.
Change the template folders and add the app name, e.g.
template/ app_base/ home.html
One reason for this error is the usage of a namespace in a link.
Back to <a href="If you want to use this way of links, you have to define the namespace/appname in your
<app>/urls.py
fileapp_name = 'app_views' urlpatterns = [ path('', views.HomeView.as_view(), name='home'), ]dependencies reference nonexistent parent node
$ python manage.py makemigrations $ python manage migrate
$ python manage.py makemigrations
PREFIX_PKG := app default: grep -E ':\s+#' Makefile clearcache: # Clear Cache python3 manage.py clearcache run: # Run Server python3 manage.py runserver 8000 deploy: # Deploy rm -rf dist $(PREFIX_PKG)* rm -rf polls.dist cd polls && python3 setup.py sdist mkdir polls.dist && mv polls/dist/* polls/$(PREFIX_PKG)* polls.dist install_bootstrap: # Install Bootstrap Library cd .. && yarn add bootstrap rm -rf polls/static/bootstrap mkdir polls/static/bootstrap cp -R ../node_modules/bootstrap/dist/* polls/static/bootstrap install_jquery: # Install jQuery Library cd .. && yarn add jquery rm -rf polls/static/jquery mkdir polls/static/jquery cp ../node_modules/jquery/dist/* polls/static/jquery install_bootstrap_from_source: # Install Bootstrap from Source mkdir -p install && \ wget https://github.com/twbs/bootstrap/releases/download/v4.1.3/bootstrap-4.1.3-dist.zip -O install/bootstrap-4.1.3-dist.zip && \ unzip install/bootstrap-4.1.3-dist.zip -d polls/static/bootstrap/4.1.3
ng new app
cd app
npm install jspdf --save npm install types/jspdf --save
ng generate component pages/PDF
src/app/app-routing.modules.ts
import { NgModule } from '@angular/core'; import { Routes, RouterModule } from '@angular/router'; import { PDFComponent } from './pages/pdf/component'; const routes: Routes = [ { path: '', redirectTo: 'pdf', pathMatch: 'full', }, { path: 'pdf', component: PDFComponent, }, ]; @NgModule({ imports: [RouterModule.forRoot(routes)], exports: [RouterModule], }) export class AppRoutingModule {}
src/app/pages/pdf/pdf.component.html
src/app/pages/pdf/pdf.component.ts
Add import for jsPDF
import { jsPDF } from 'jspdf';
source < (kubectl completion bash) # setup autocomplete in bash into the current shell, bash-completion package should be installed first. echo "source <(kubectl completion bash)" >> ~/.bashrc
You can also use a shorthand alias for kubectl
that also works with completion:
alias k=kubectl complete -F __start_kubectl k
source <(kubectl completion zsh) # setup autocomplete in zsh into the current shell echo "[[ $commands[kubectl] ]] && source <(kubectl completion zsh)" >> ~/.zshrc # add autocomplete permanently to your zsh shell
Set which Kubernetes cluster kubectl
communicates with and modifies configuration information. See Authenticating Across Clusters with kubeconfig documentation for detailed config file information.
kubectl config view # Show Merged kubeconfig settings. # use multiple kubeconfig files at the same time and view merged config KUBECONFIG=~/.kube/config:~/.kube/kubconfig2 kubectl config view # get the password for the e2e user kubectl config view -o jsonpath='{.users[?(@.name == "e2e")].user.password}' kubectl config view -o jsonpath='{.users[].name}' # display the first user kubectl config view -o jsonpath='{.users[*].name}' # get a list of users kubectl config get-contexts # display list of contexts kubectl config current-context # display the current-context kubectl config use-context my-cluster-name # set the default context to my-cluster-name # add a new user to your kubeconf that supports basic auth kubectl config set-credentials kubeuser/foo.kubernetes.com --username=kubeuser --password=kubepassword # permanently save the namespace for all subsequent kubectl commands in that context. kubectl config set-context --current --namespace=ggckad-s2 # set a context utilizing a specific username and namespace. kubectl config set-context gce --user=cluster-admin --namespace=foo && kubectl config use-context gce kubectl config unset users.foo # delete user foo
apply
manages applications through files defining Kubernetes resources. It creates and updates resources in a cluster through running kubectl apply
. This is the recommended way of managing Kubernetes applications on production. See Kubectl Book.
Kubernetes manifests can be defined in YAML or JSON. The file extension .yaml
, .yml
, and .json
can be used.
kubectl apply -f ./my-manifest.yaml # create resource(s) kubectl apply -f ./my1.yaml -f ./my2.yaml # create from multiple files kubectl apply -f ./dir # create resource(s) in all manifest files in dir kubectl apply -f https://git.io/vPieo # create resource(s) from url kubectl create deployment nginx --image=nginx # start a single instance of nginx # create a Job which prints "Hello World" kubectl create job hello --image=busybox -- echo "Hello World" # create a CronJob that prints "Hello World" every minute kubectl create cronjob hello --image=busybox --schedule="*/1 * * * *" -- echo "Hello World" kubectl explain pods # get the documentation for pod manifests # Create multiple YAML objects from stdin cat <<EOF | kubectl apply -f - apiVersion: v1 kind: Pod metadata: name: busybox-sleep spec: containers: - name: busybox image: busybox args: - sleep - "1000000" --- apiVersion: v1 kind: Pod metadata: name: busybox-sleep-less spec: containers: - name: busybox image: busybox args: - sleep - "1000" EOF # Create a secret with several keys cat <<EOF | kubectl apply -f - apiVersion: v1 kind: Secret metadata: name: mysecret type: Opaque data: password: $(echo -n "s33msi4" | base64 -w0) username: $(echo -n "jane" | base64 -w0) EOF
# Get commands with basic output kubectl get services # List all services in the namespace kubectl get pods --all-namespaces # List all pods in all namespaces kubectl get pods -o wide # List all pods in the current namespace, with more details kubectl get deployment my-dep # List a particular deployment kubectl get pods # List all pods in the namespace kubectl get pod my-pod -o yaml # Get a pod's YAML # Describe commands with verbose output kubectl describe nodes my-node kubectl describe pods my-pod # List Services Sorted by Name kubectl get services --sort-by=.metadata.name # List pods Sorted by Restart Count kubectl get pods --sort-by='.status.containerStatuses[0].restartCount' # List PersistentVolumes sorted by capacity kubectl get pv --sort-by=.spec.capacity.storage # Get the version label of all pods with label app=cassandra kubectl get pods --selector=app=cassandra -o jsonpath='{.items[*].metadata.labels.version}' # Retrieve the value of a key with dots, e.g. 'ca.crt' kubectl get configmap myconfig -o jsonpath='{.data.ca.crt}' # Get all worker nodes (use a selector to exclude results that have a label # named 'node-role.kubernetes.io/master') kubectl get node --selector='!node-role.kubernetes.io/master' # Get all running pods in the namespace kubectl get pods --field-selector=status.phase=Running # Get ExternalIPs of all nodes kubectl get nodes -o jsonpath='{.items[*].status.addresses[?(@.type=="ExternalIP")].address}' # List Names of Pods that belong to Particular RC # "jq" command useful for transformations that are too complex for jsonpath, it can be found at https://stedolan.github.io/jq/ sel=${$(kubectl get rc my-rc --output=json | jq -j '.spec.selector | to_entries | .[] | "(.key)=(.value),"' echo $(kubectl get pods --selector=$sel --output=jsonpath={.items..metadata.name}) # Show labels for all pods (or any other Kubernetes object that supports labelling) kubectl get pods --show-labels # Check which nodes are ready JSONPATH='{range .items[*]}{@.metadata.name}:{range @.status.conditions[*]}{@.type}={@.status};{end}{end}' && kubectl get nodes -o jsonpath="$JSONPATH" | grep "Ready=True" # List all Secrets currently in use by a pod kubectl get pods -o json | jq '.items[].spec.containers[].env[]?.valueFrom.secretKeyRef.name' | grep -v null | sort | uniq # List all containerIDs of initContainer of all pods # Helpful when cleaning up stopped containers, while avoiding removal of initContainers. kubectl get pods --all-namespaces -o jsonpath='{range .items[*].status.initContainerStatuses[*]}{.containerID}{"n"}{end}' | cut -d/ -f3 # List Events sorted by timestamp kubectl get events --sort-by=.metadata.creationTimestamp # Compares the current state of the cluster against the state that the cluster would be in if the manifest was applied. kubectl diff -f ./my-manifest.yaml # Produce a period-delimited tree of all keys returned for nodes # Helpful when locating a key within a complex nested JSON structure kubectl get nodes -o json | jq -c 'path(..)|[.[]|tostring]|join(".")' # Produce a period-delimited tree of all keys returned for pods, etc kubectl get pods -o json | jq -c 'path(..)|[.[]|tostring]|join(".")'
kubectl set image deployment/frontend www=image:v2 # Rolling update "www" containers of "frontend" deployment, updating the image kubectl rollout history deployment/frontend # Check the history of deployments including the revision kubectl rollout undo deployment/frontend # Rollback to the previous deployment kubectl rollout undo deployment/frontend --to-revision=2 # Rollback to a specific revision kubectl rollout status -w deployment/frontend # Watch rolling update status of "frontend" deployment until completion kubectl rollout restart deployment/frontend # Rolling restart of the "frontend" deployment cat pod.json | kubectl replace -f - # Replace a pod based on the JSON passed into std # Force replace, delete and then re-create the resource. Will cause a service outage. kubectl replace --force -f ./pod.json # Create a service for a replicated nginx, which serves on port 80 and connects to the containers on port 8000 kubectl expose rc nginx --port=80 --target-port=8000 # Update a single-container pod's image version (tag) to v4 kubectl get pod mypod -o yaml | sed 's/(image: myimage):.*$/1:v4/' | kubectl replace -f - kubectl label pods my-pod new-label=awesome # Add a Label kubectl annotate pods my-pod icon-url=http://goo.gl/XXBTWq # Add an annotation kubectl autoscale deployment foo --min=2 --max=10 # Auto scale a deployment "foo"
# Partially update a node kubectl patch node k8s-node-1 -p '{"spec":{"unschedulable":true}}' # Update a container's image; spec.containers[*].name is required because it's a merge key kubectl patch pod valid-pod -p '{"spec":{"containers":[{"name":"kubernetes-serve-hostname","image":"new image"}]}}' # Update a container's image using a json patch with positional arrays kubectl patch pod valid-pod --type='json' -p='[{"op": "replace", "path": "/spec/containers/0/image", "value":"new image"}]' # Disable a deployment livenessProbe using a json patch with positional arrays kubectl patch deployment valid-deployment --type json -p='[{"op": "remove", "path": "/spec/template/spec/containers/0/livenessProbe"}]' # Add a new element to a positional array kubectl patch sa default --type='json' -p='[{"op": "add", "path": "/secrets/1", "value": {"name": "whatever" } }]'
Edit any API resource in your preferred editor.
kubectl edit svc/docker-registry # Edit the service named docker-registry KUBE_EDITOR="nano" kubectl edit svc/docker-registry # Use an alternative editor
kubectl scale --replicas=3 rs/foo # Scale a replicaset named 'foo' to 3 kubectl scale --replicas=3 -f foo.yaml # Scale a resource specified in "foo.yaml" to 3 kubectl scale --current-replicas=2 --replicas=3 deployment/mysql # If the deployment named mysql's current size is 2, scale mysql to 3 kubectl scale --replicas=5 rc/foo rc/bar rc/baz # Scale multiple replication controllers
kubectl delete -f ./pod.json # Delete a pod using the type and name specified in pod.json kubectl delete pod,service baz foo # Delete pods and services with same names "baz" and "foo" kubectl delete pods,services -l name=myLabel # Delete pods and services with label name=myLabel kubectl -n my-ns delete pod,svc --all # Delete all pods and services in namespace my-ns, # Delete all pods matching the awk pattern1 or pattern2 kubectl get pods -n mynamespace --no-headers=true | awk '/pattern1|pattern2/{print $1}' | xargs kubectl delete -n mynamespace pod
kubectl logs my-pod # dump pod logs (stdout) kubectl logs -l name=myLabel # dump pod logs, with label name=myLabel (stdout) kubectl logs my-pod --previous # dump pod logs (stdout) for a previous instantiation of a container kubectl logs my-pod -c my-container # dump pod container logs (stdout, multi-container case) kubectl logs -l name=myLabel -c my-container # dump pod logs, with label name=myLabel (stdout) kubectl logs my-pod -c my-container --previous # dump pod container logs (stdout, multi-container case) for a previous instantiation of a container kubectl logs -f my-pod # stream pod logs (stdout) kubectl logs -f my-pod -c my-container # stream pod container logs (stdout, multi-container case) kubectl logs -f -l name=myLabel --all-containers # stream all pods logs with label name=myLabel (stdout) kubectl run -i --tty busybox --image=busybox -- sh # Run pod as interactive shell kubectl run nginx --image=nginx -n mynamespace # Run pod nginx in a specific namespace kubectl run nginx --image=nginx # Run pod nginx and write its spec into a file called pod.yaml --dry-run=client -o yaml > pod.yaml kubectl attach my-pod -i # Attach to Running Container kubectl port-forward my-pod 5000:6000 # Listen on port 5000 on the local machine and forward to port 6000 on my-pod kubectl exec my-pod -- ls / # Run command in existing pod (1 container case) kubectl exec --stdin --tty my-pod -- /bin/sh # Interactive shell access to a running pod (1 container case) kubectl exec my-pod -c my-container -- ls / # Run command in existing pod (multi-container case) kubectl top pod POD_NAME --containers # Show metrics for a given pod and its containers
kubectl cordon my-node # Mark my-node as unschedulable kubectl drain my-node # Drain my-node in preparation for maintenance kubectl uncordon my-node # Mark my-node as schedulable kubectl top node my-node # Show metrics for a given node kubectl cluster-info # Display addresses of the master and services kubectl cluster-info dump # Dump current cluster state to stdout kubectl cluster-info dump --output-directory=/path/to/cluster-state # Dump current cluster state to /path/to/cluster-state # If a taint with that key and effect already exists, its value is replaced as specified. kubectl taint nodes foo dedicated=special-user:NoSchedule
List all supported resource types along with their shortnames, API group, whether they are namespaced, and Kind:
kubectl api-resources
Other operations for exploring API resources:
kubectl api-resources --namespaced=true # All namespaced resources kubectl api-resources --namespaced=false # All non-namespaced resources kubectl api-resources -o name # All resources with simple output (just the resource name) kubectl api-resources -o wide # All resources with expanded (aka "wide") output kubectl api-resources --verbs=list,get # All resources that support the "list" and "get" request verbs kubectl api-resources --api-group=extensions # All resources in the "extensions" API group
To output details to your terminal window in a specific format, add the -o
(or --output
) flag to a supported kubectl
command.
Output format | Description |
---|---|
-o=custom-columns=<spec> | Print a table using a comma separated list of custom columns |
-o=custom-columns-file=<filename> | Print a table using the custom columns template in the <filename> file |
-o=json | Output a JSON formatted API object |
-o=jsonpath=<template> | Print the fields defined in a jsonpath expression |
-o=jsonpath-file=<filename> | Print the fields defined by the jsonpath expression in the <filename> file |
-o=name | Print only the resource name and nothing else |
-o=wide | Output in the plain-text format with any additional information, and for pods, the node name is included |
-o=yaml | Output a YAML formatted API object |
Examples using -o=custom-columns
:
# All images running in a cluster kubectl get pods -A -o=custom-columns='DATA:spec.containers[*].image' # All images excluding "k8s.gcr.io/coredns:1.6.2" kubectl get pods -A -o=custom-columns='DATA:spec.containers[?(@.image!="k8s.gcr.io/coredns:1.6.2")].image' # All fields under metadata regardless of name kubectl get pods -A -o=custom-columns='DATA:metadata.*'
More examples in the kubectl reference documentation.
Kubectl verbosity is controlled with the -v
or --v
flags followed by an integer representing the log level. General Kubernetes logging conventions and the associated log levels are described here.
Verbosity | Description |
---|---|
--v=0 | Generally useful for this to always be visible to a cluster operator. |
--v=1 | A reasonable default log level if you don’t want verbosity. |
--v=2 | Useful steady state information about the service and important log messages that may correlate to significant changes in the system. This is the recommended default log level for most systems. |
--v=3 | Extended information about changes. |
--v=4 | Debug level verbosity. |
--v=6 | Display requested resources. |
--v=7 | Display HTTP request headers. |
--v=8 | Display HTTP request contents. |
--v=9 | Display HTTP request contents without truncation of contents. |