├── .dockerignore
├── .gitignore
├── .travis.yml
├── .whitesource
├── Dockerfile
├── LICENSE
├── Makefile
├── README.md
├── docker-compose.yml
├── docs
├── index.md
├── k3s.md
├── kube.md
└── microk8s.md
├── example
├── simplest-webthing-go
│ └── simplest-thing.go
└── single-webthing-go
│ └── single-thing.go
├── extra
└── tools
│ ├── docker
│ └── debian
│ │ └── Dockerfile
│ └── kube
│ ├── Makefile
│ ├── deployment.yml
│ ├── service.yml
│ └── webthing-go.yml
├── go.mod
├── go.sum
└── webthing.go
/.dockerignore:
--------------------------------------------------------------------------------
1 | #.dockerignore
2 | Dockerfile
3 | .git/
4 | # .gitignore
5 | *.tmp
6 | *~
7 | a.out
8 | master
9 |
10 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # .gitignore
2 | *.tmp
3 | *~
4 | a.out
5 | master
6 | simplest-thing
7 | *-webthing-go
8 |
--------------------------------------------------------------------------------
/.travis.yml:
--------------------------------------------------------------------------------
1 | language: go
2 |
--------------------------------------------------------------------------------
/.whitesource:
--------------------------------------------------------------------------------
1 | {
2 | "scanSettings": {
3 | "configMode": "AUTO",
4 | "configExternalURL": ""
5 | },
6 | "checkRunSettings": {
7 | "vulnerableCheckRunConclusionLevel": "failure"
8 | },
9 | "issueSettings": {
10 | "minSeverityLevel": "LOW"
11 | }
12 | }
--------------------------------------------------------------------------------
/Dockerfile:
--------------------------------------------------------------------------------
1 | #!/bin/echo docker build . -f
2 | # -*- coding: utf-8 -*-
3 | # SPDX-License-Identifier: MIT
4 | #{
5 | # Copyright 2019-present Samsung Electronics France SAS, and other contributors
6 | #
7 | # This Source Code Form is subject to the terms of the MIT Licence
8 | # If a copy of the MIT was not distributed with this file
9 | # You can obtain one at:
10 | # https://spdx.org/licenses/MIT.html
11 | #}
12 |
13 | FROM golang:1.12.9-alpine3.10 AS webthing-go-builder
14 | LABEL maintainer "Philippe Coval (p.coval@samsung.com)"
15 |
16 | ENV project webthing-go
17 | ENV project_dir /usr/local/src/github.com/rzr/${project}/
18 |
19 | RUN echo "#log: Setup system" \
20 | && apk update \
21 | && apk add make sudo \
22 | && rm -rf /var/cache/apk/* \
23 | && sync
24 |
25 | COPY Makefile ${project_dir}
26 | WORKDIR ${project_dir}
27 | RUN echo "#log: ${project}: Preparing sources" \
28 | && set -x \
29 | && make rule/setup/alpine \
30 | && sync
31 |
32 | COPY . ${project_dir}
33 | RUN echo "#log: ${project}: Buidling sources" \
34 | && set -x \
35 | && make all \
36 | && sync
37 |
38 | FROM alpine:3.10
39 | ENV project webthing-go
40 | ENV project_dir /usr/local/src/github.com/rzr/${project}/
41 | COPY --from=webthing-go-builder ${project_dir}/simplest-webthing-go /usr/local/bin/
42 | EXPOSE 8888
43 | ENTRYPOINT [ "/usr/local/bin/simplest-webthing-go" ]
44 | CMD []
45 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | Mozilla Public License Version 2.0
2 | ==================================
3 |
4 | 1. Definitions
5 | --------------
6 |
7 | 1.1. "Contributor"
8 | means each individual or legal entity that creates, contributes to
9 | the creation of, or owns Covered Software.
10 |
11 | 1.2. "Contributor Version"
12 | means the combination of the Contributions of others (if any) used
13 | by a Contributor and that particular Contributor's Contribution.
14 |
15 | 1.3. "Contribution"
16 | means Covered Software of a particular Contributor.
17 |
18 | 1.4. "Covered Software"
19 | means Source Code Form to which the initial Contributor has attached
20 | the notice in Exhibit A, the Executable Form of such Source Code
21 | Form, and Modifications of such Source Code Form, in each case
22 | including portions thereof.
23 |
24 | 1.5. "Incompatible With Secondary Licenses"
25 | means
26 |
27 | (a) that the initial Contributor has attached the notice described
28 | in Exhibit B to the Covered Software; or
29 |
30 | (b) that the Covered Software was made available under the terms of
31 | version 1.1 or earlier of the License, but not also under the
32 | terms of a Secondary License.
33 |
34 | 1.6. "Executable Form"
35 | means any form of the work other than Source Code Form.
36 |
37 | 1.7. "Larger Work"
38 | means a work that combines Covered Software with other material, in
39 | a separate file or files, that is not Covered Software.
40 |
41 | 1.8. "License"
42 | means this document.
43 |
44 | 1.9. "Licensable"
45 | means having the right to grant, to the maximum extent possible,
46 | whether at the time of the initial grant or subsequently, any and
47 | all of the rights conveyed by this License.
48 |
49 | 1.10. "Modifications"
50 | means any of the following:
51 |
52 | (a) any file in Source Code Form that results from an addition to,
53 | deletion from, or modification of the contents of Covered
54 | Software; or
55 |
56 | (b) any new file in Source Code Form that contains any Covered
57 | Software.
58 |
59 | 1.11. "Patent Claims" of a Contributor
60 | means any patent claim(s), including without limitation, method,
61 | process, and apparatus claims, in any patent Licensable by such
62 | Contributor that would be infringed, but for the grant of the
63 | License, by the making, using, selling, offering for sale, having
64 | made, import, or transfer of either its Contributions or its
65 | Contributor Version.
66 |
67 | 1.12. "Secondary License"
68 | means either the GNU General Public License, Version 2.0, the GNU
69 | Lesser General Public License, Version 2.1, the GNU Affero General
70 | Public License, Version 3.0, or any later versions of those
71 | licenses.
72 |
73 | 1.13. "Source Code Form"
74 | means the form of the work preferred for making modifications.
75 |
76 | 1.14. "You" (or "Your")
77 | means an individual or a legal entity exercising rights under this
78 | License. For legal entities, "You" includes any entity that
79 | controls, is controlled by, or is under common control with You. For
80 | purposes of this definition, "control" means (a) the power, direct
81 | or indirect, to cause the direction or management of such entity,
82 | whether by contract or otherwise, or (b) ownership of more than
83 | fifty percent (50%) of the outstanding shares or beneficial
84 | ownership of such entity.
85 |
86 | 2. License Grants and Conditions
87 | --------------------------------
88 |
89 | 2.1. Grants
90 |
91 | Each Contributor hereby grants You a world-wide, royalty-free,
92 | non-exclusive license:
93 |
94 | (a) under intellectual property rights (other than patent or trademark)
95 | Licensable by such Contributor to use, reproduce, make available,
96 | modify, display, perform, distribute, and otherwise exploit its
97 | Contributions, either on an unmodified basis, with Modifications, or
98 | as part of a Larger Work; and
99 |
100 | (b) under Patent Claims of such Contributor to make, use, sell, offer
101 | for sale, have made, import, and otherwise transfer either its
102 | Contributions or its Contributor Version.
103 |
104 | 2.2. Effective Date
105 |
106 | The licenses granted in Section 2.1 with respect to any Contribution
107 | become effective for each Contribution on the date the Contributor first
108 | distributes such Contribution.
109 |
110 | 2.3. Limitations on Grant Scope
111 |
112 | The licenses granted in this Section 2 are the only rights granted under
113 | this License. No additional rights or licenses will be implied from the
114 | distribution or licensing of Covered Software under this License.
115 | Notwithstanding Section 2.1(b) above, no patent license is granted by a
116 | Contributor:
117 |
118 | (a) for any code that a Contributor has removed from Covered Software;
119 | or
120 |
121 | (b) for infringements caused by: (i) Your and any other third party's
122 | modifications of Covered Software, or (ii) the combination of its
123 | Contributions with other software (except as part of its Contributor
124 | Version); or
125 |
126 | (c) under Patent Claims infringed by Covered Software in the absence of
127 | its Contributions.
128 |
129 | This License does not grant any rights in the trademarks, service marks,
130 | or logos of any Contributor (except as may be necessary to comply with
131 | the notice requirements in Section 3.4).
132 |
133 | 2.4. Subsequent Licenses
134 |
135 | No Contributor makes additional grants as a result of Your choice to
136 | distribute the Covered Software under a subsequent version of this
137 | License (see Section 10.2) or under the terms of a Secondary License (if
138 | permitted under the terms of Section 3.3).
139 |
140 | 2.5. Representation
141 |
142 | Each Contributor represents that the Contributor believes its
143 | Contributions are its original creation(s) or it has sufficient rights
144 | to grant the rights to its Contributions conveyed by this License.
145 |
146 | 2.6. Fair Use
147 |
148 | This License is not intended to limit any rights You have under
149 | applicable copyright doctrines of fair use, fair dealing, or other
150 | equivalents.
151 |
152 | 2.7. Conditions
153 |
154 | Sections 3.1, 3.2, 3.3, and 3.4 are conditions of the licenses granted
155 | in Section 2.1.
156 |
157 | 3. Responsibilities
158 | -------------------
159 |
160 | 3.1. Distribution of Source Form
161 |
162 | All distribution of Covered Software in Source Code Form, including any
163 | Modifications that You create or to which You contribute, must be under
164 | the terms of this License. You must inform recipients that the Source
165 | Code Form of the Covered Software is governed by the terms of this
166 | License, and how they can obtain a copy of this License. You may not
167 | attempt to alter or restrict the recipients' rights in the Source Code
168 | Form.
169 |
170 | 3.2. Distribution of Executable Form
171 |
172 | If You distribute Covered Software in Executable Form then:
173 |
174 | (a) such Covered Software must also be made available in Source Code
175 | Form, as described in Section 3.1, and You must inform recipients of
176 | the Executable Form how they can obtain a copy of such Source Code
177 | Form by reasonable means in a timely manner, at a charge no more
178 | than the cost of distribution to the recipient; and
179 |
180 | (b) You may distribute such Executable Form under the terms of this
181 | License, or sublicense it under different terms, provided that the
182 | license for the Executable Form does not attempt to limit or alter
183 | the recipients' rights in the Source Code Form under this License.
184 |
185 | 3.3. Distribution of a Larger Work
186 |
187 | You may create and distribute a Larger Work under terms of Your choice,
188 | provided that You also comply with the requirements of this License for
189 | the Covered Software. If the Larger Work is a combination of Covered
190 | Software with a work governed by one or more Secondary Licenses, and the
191 | Covered Software is not Incompatible With Secondary Licenses, this
192 | License permits You to additionally distribute such Covered Software
193 | under the terms of such Secondary License(s), so that the recipient of
194 | the Larger Work may, at their option, further distribute the Covered
195 | Software under the terms of either this License or such Secondary
196 | License(s).
197 |
198 | 3.4. Notices
199 |
200 | You may not remove or alter the substance of any license notices
201 | (including copyright notices, patent notices, disclaimers of warranty,
202 | or limitations of liability) contained within the Source Code Form of
203 | the Covered Software, except that You may alter any license notices to
204 | the extent required to remedy known factual inaccuracies.
205 |
206 | 3.5. Application of Additional Terms
207 |
208 | You may choose to offer, and to charge a fee for, warranty, support,
209 | indemnity or liability obligations to one or more recipients of Covered
210 | Software. However, You may do so only on Your own behalf, and not on
211 | behalf of any Contributor. You must make it absolutely clear that any
212 | such warranty, support, indemnity, or liability obligation is offered by
213 | You alone, and You hereby agree to indemnify every Contributor for any
214 | liability incurred by such Contributor as a result of warranty, support,
215 | indemnity or liability terms You offer. You may include additional
216 | disclaimers of warranty and limitations of liability specific to any
217 | jurisdiction.
218 |
219 | 4. Inability to Comply Due to Statute or Regulation
220 | ---------------------------------------------------
221 |
222 | If it is impossible for You to comply with any of the terms of this
223 | License with respect to some or all of the Covered Software due to
224 | statute, judicial order, or regulation then You must: (a) comply with
225 | the terms of this License to the maximum extent possible; and (b)
226 | describe the limitations and the code they affect. Such description must
227 | be placed in a text file included with all distributions of the Covered
228 | Software under this License. Except to the extent prohibited by statute
229 | or regulation, such description must be sufficiently detailed for a
230 | recipient of ordinary skill to be able to understand it.
231 |
232 | 5. Termination
233 | --------------
234 |
235 | 5.1. The rights granted under this License will terminate automatically
236 | if You fail to comply with any of its terms. However, if You become
237 | compliant, then the rights granted under this License from a particular
238 | Contributor are reinstated (a) provisionally, unless and until such
239 | Contributor explicitly and finally terminates Your grants, and (b) on an
240 | ongoing basis, if such Contributor fails to notify You of the
241 | non-compliance by some reasonable means prior to 60 days after You have
242 | come back into compliance. Moreover, Your grants from a particular
243 | Contributor are reinstated on an ongoing basis if such Contributor
244 | notifies You of the non-compliance by some reasonable means, this is the
245 | first time You have received notice of non-compliance with this License
246 | from such Contributor, and You become compliant prior to 30 days after
247 | Your receipt of the notice.
248 |
249 | 5.2. If You initiate litigation against any entity by asserting a patent
250 | infringement claim (excluding declaratory judgment actions,
251 | counter-claims, and cross-claims) alleging that a Contributor Version
252 | directly or indirectly infringes any patent, then the rights granted to
253 | You by any and all Contributors for the Covered Software under Section
254 | 2.1 of this License shall terminate.
255 |
256 | 5.3. In the event of termination under Sections 5.1 or 5.2 above, all
257 | end user license agreements (excluding distributors and resellers) which
258 | have been validly granted by You or Your distributors under this License
259 | prior to termination shall survive termination.
260 |
261 | ************************************************************************
262 | * *
263 | * 6. Disclaimer of Warranty *
264 | * ------------------------- *
265 | * *
266 | * Covered Software is provided under this License on an "as is" *
267 | * basis, without warranty of any kind, either expressed, implied, or *
268 | * statutory, including, without limitation, warranties that the *
269 | * Covered Software is free of defects, merchantable, fit for a *
270 | * particular purpose or non-infringing. The entire risk as to the *
271 | * quality and performance of the Covered Software is with You. *
272 | * Should any Covered Software prove defective in any respect, You *
273 | * (not any Contributor) assume the cost of any necessary servicing, *
274 | * repair, or correction. This disclaimer of warranty constitutes an *
275 | * essential part of this License. No use of any Covered Software is *
276 | * authorized under this License except under this disclaimer. *
277 | * *
278 | ************************************************************************
279 |
280 | ************************************************************************
281 | * *
282 | * 7. Limitation of Liability *
283 | * -------------------------- *
284 | * *
285 | * Under no circumstances and under no legal theory, whether tort *
286 | * (including negligence), contract, or otherwise, shall any *
287 | * Contributor, or anyone who distributes Covered Software as *
288 | * permitted above, be liable to You for any direct, indirect, *
289 | * special, incidental, or consequential damages of any character *
290 | * including, without limitation, damages for lost profits, loss of *
291 | * goodwill, work stoppage, computer failure or malfunction, or any *
292 | * and all other commercial damages or losses, even if such party *
293 | * shall have been informed of the possibility of such damages. This *
294 | * limitation of liability shall not apply to liability for death or *
295 | * personal injury resulting from such party's negligence to the *
296 | * extent applicable law prohibits such limitation. Some *
297 | * jurisdictions do not allow the exclusion or limitation of *
298 | * incidental or consequential damages, so this exclusion and *
299 | * limitation may not apply to You. *
300 | * *
301 | ************************************************************************
302 |
303 | 8. Litigation
304 | -------------
305 |
306 | Any litigation relating to this License may be brought only in the
307 | courts of a jurisdiction where the defendant maintains its principal
308 | place of business and such litigation shall be governed by laws of that
309 | jurisdiction, without reference to its conflict-of-law provisions.
310 | Nothing in this Section shall prevent a party's ability to bring
311 | cross-claims or counter-claims.
312 |
313 | 9. Miscellaneous
314 | ----------------
315 |
316 | This License represents the complete agreement concerning the subject
317 | matter hereof. If any provision of this License is held to be
318 | unenforceable, such provision shall be reformed only to the extent
319 | necessary to make it enforceable. Any law or regulation which provides
320 | that the language of a contract shall be construed against the drafter
321 | shall not be used to construe this License against a Contributor.
322 |
323 | 10. Versions of the License
324 | ---------------------------
325 |
326 | 10.1. New Versions
327 |
328 | Mozilla Foundation is the license steward. Except as provided in Section
329 | 10.3, no one other than the license steward has the right to modify or
330 | publish new versions of this License. Each version will be given a
331 | distinguishing version number.
332 |
333 | 10.2. Effect of New Versions
334 |
335 | You may distribute the Covered Software under the terms of the version
336 | of the License under which You originally received the Covered Software,
337 | or under the terms of any subsequent version published by the license
338 | steward.
339 |
340 | 10.3. Modified Versions
341 |
342 | If you create software not governed by this License, and you want to
343 | create a new license for such software, you may create and use a
344 | modified version of this License if you rename the license and remove
345 | any references to the name of the license steward (except to note that
346 | such modified license differs from this License).
347 |
348 | 10.4. Distributing Source Code Form that is Incompatible With Secondary
349 | Licenses
350 |
351 | If You choose to distribute Source Code Form that is Incompatible With
352 | Secondary Licenses under the terms of this version of the License, the
353 | notice described in Exhibit B of this License must be attached.
354 |
355 | Exhibit A - Source Code Form License Notice
356 | -------------------------------------------
357 |
358 | This Source Code Form is subject to the terms of the Mozilla Public
359 | License, v. 2.0. If a copy of the MPL was not distributed with this
360 | file, You can obtain one at http://mozilla.org/MPL/2.0/.
361 |
362 | If it is not possible or desirable to put the notice in a particular
363 | file, then You may include the notice in a location (such as a LICENSE
364 | file in a relevant directory) where a recipient would be likely to look
365 | for such a notice.
366 |
367 | You may add additional accurate notices of copyright ownership.
368 |
369 | Exhibit B - "Incompatible With Secondary Licenses" Notice
370 | ---------------------------------------------------------
371 |
372 | This Source Code Form is "Incompatible With Secondary Licenses", as
373 | defined by the Mozilla Public License, v. 2.0.
374 |
--------------------------------------------------------------------------------
/Makefile:
--------------------------------------------------------------------------------
1 | #! /usr/bin/make -f
2 | # -*- makefile -*-
3 | # ex: set tabstop=4 noexpandtab:
4 | # Copyright: 2019-present Samsung Electronics Co., Ltd. and other contributors
5 | # SPDX-License-Identifier: MPL-2.0
6 |
7 | default: all
8 | @echo "# log: $@: $^"
9 |
10 | package_name?=webthing-go
11 | port?=8888
12 | url?=http://localhost:${port}
13 | main_name?=simplest-webthing-go
14 | main_src?=example/${main_name}/simplest-thing.go
15 | main_srcs?=$(wildcard ./example/*/*.go | sort)
16 | main_dirs?=$(dir ${main_srcs})
17 | sudo?=sudo
18 | go?=go
19 |
20 |
21 | all: get version build
22 | @echo "# log: $@: $^"
23 |
24 | get:
25 | ${go} $@
26 |
27 | build: ${main_srcs} get
28 | ${go} $@
29 | for app in ${main_dirs}; do ${go} $@ $${app} ; done
30 |
31 | devel/run: ${main_src}
32 | -${make} get
33 | ${go} run $<
34 |
35 | ${main_name}: build
36 | ldd $@
37 |
38 | run: ${main_src}
39 | ${go} run $<
40 |
41 | start: ${main_name}
42 | ${
94 | *
95 | *
96 | *
97 |
--------------------------------------------------------------------------------
/docker-compose.yml:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 | # SPDX-License-Identifier: MIT
3 | #{
4 | # Copyright 2019-present Samsung Electronics France SAS, and other contributors
5 | #
6 | # This Source Code Form is subject to the terms of the MIT Licence
7 | # If a copy of the MIT was not distributed with this file
8 | # You can obtain one at:
9 | # https://spdx.org/licenses/MIT.html
10 | #}
11 |
12 | version: "2"
13 |
14 | services:
15 | default:
16 | build: .
17 | ports:
18 | - "8888:8888"
19 | network_mode: "host"
20 |
--------------------------------------------------------------------------------
/docs/index.md:
--------------------------------------------------------------------------------
1 | # WEBTHING-GO DOCS #
2 |
3 | ## INDEX: ##
4 |
5 | * [kube](kube)
6 | * [K3S](k3s)
7 |
8 |
9 | ## RESOURCES: ##
10 |
11 | *
12 | *
13 |
--------------------------------------------------------------------------------
/docs/k3s.md:
--------------------------------------------------------------------------------
1 | # WEBTHING-GO WITH K3S #
2 |
3 | As an extra, here is a recipe to run a service using K3S:
4 |
5 | ```sh
6 | name="webthing-go"
7 | image="rzrfreefr/${name}:latest"
8 | kubectl="sudo kubectl"
9 |
10 | sudo sync
11 | curl -sfL "https://get.k3s.io" | sh - # v0.8.0
12 | sudo systemctl status k3s.service
13 |
14 | $kubectl get nodes # Wait "Ready state"
15 | #| {host} Ready master 51s v1.14.4-k3s.1
16 |
17 | $kubectl run --generator="run-pod/v1" "${name}" --image="${image}"
18 |
19 | $kubectl get all --all-namespaces | grep "$name"
20 | #| default pod/webthing-go 1/1 Running 0 19s
21 | #| default pod/webthing-go-688f84fc55-df8n4 1/1 Running 0 40s
22 |
23 | pod=$($kubectl get all --all-namespaces \
24 | | grep -o "pod/${name}-.*" | cut -d/ -f2 | awk '{ print $1}' \
25 | || echo failure) && echo pod="$pod"
26 | $kubectl describe pod "$pod" | grep 'Status: Running'
27 | ip=$($kubectl describe pod "$pod" | grep 'IP:' | awk '{ print $2 }') && echo "ip=${ip}"
28 |
29 | curl -I "http://${ip}:8888" | grep 'HTTP/1.1'
30 |
31 | sudo cat "/proc/$(pidof simplest-webthing-go | cut -d' ' -f1)/smaps"
32 | #| 00fc2000-00fe3000 rw-p 00000000 00:00 0 [heap]
33 | #| Size: 132 kB
34 | #| (...)
35 | #| 7fff1e838000-7fff1e859000 rw-p 00000000 00:00 0 [stack]
36 | #| Size: 132 kB
37 | #| (...)
38 |
39 | # Remove if needed
40 | /usr/local/bin/k3s-uninstall.sh
41 | ```
42 |
43 |
44 | ## RESOURCES: ##
45 |
46 | *
47 | *
48 | *
49 |
--------------------------------------------------------------------------------
/docs/kube.md:
--------------------------------------------------------------------------------
1 | # WEBTHING-GO WITH KUBERNETES: #
2 |
3 | ## SERVICE USING MINIKUBE: ###
4 |
5 | As an extra, here is a recipe to run a service using K8s's minikube:
6 |
7 | ```sh
8 | name="webthing-go"
9 | url="https://raw.githubusercontent.com/rzr/webthing-go/master/extra/tools/kube/$name.yml"
10 | kubectl=kubectl
11 | kubectl version || kubectl="sudo kubectl" # Maybe you'd better check your env
12 |
13 | minikube version
14 | #| minikube version: v1.3.0
15 |
16 | minikube start || minikube logs --alsologtostderr
17 |
18 | $kubectl version
19 | #| Client Version: version.Info{Major:"1", Minor:"15", GitVersion:"v1.15.1", ...
20 | #| Server Version: version.Info{Major:"1", Minor:"15", GitVersion:"v1.15.2", ...
21 |
22 | $kubectl apply -f "${url}"
23 | #| deployment.extensions/webthing-go created
24 | #| service/webthing-go created
25 | $kubectl get services
26 | #| webthing-go NodePort 10.100.249.206 8888:30080/TCP 4s
27 |
28 | minikube service ${name} --url
29 | #| http://192.168.99.102:30080
30 | time minikube service ${name}
31 | #| 🎉 Opening kubernetes service default/webthing-go in default browser...
32 | ```
33 |
34 |
35 | ### CLUSTER USING KUBEADM: ###
36 |
37 | The process can be automatically move between cluster's nodes:
38 |
39 | ```sh
40 | project="webthing-go"
41 | kubectl=kubectl
42 | command="go run example/simplest-thing.go"
43 |
44 | kubectl get nodes
45 | #| NAME STATUS ROLES AGE VERSION
46 | #| slave01 Ready 94m v1.15.2
47 | #| master Ready master 99m v1.15.2
48 |
49 | kubectl describe nodes
50 |
51 | kubectl get services $project
52 | #| webthing-go NodePort 10.104.44.241 8888:30080/TCP 32s
53 |
54 | pod=$($kubectl get all --all-namespaces \
55 | | grep -o "pod/${project}.*" | cut -d/ -f2 | awk '{ print $1}' \
56 | || echo failure) && echo pod="$pod"
57 |
58 | kubectl describe pods "$pod"
59 |
60 | ip=$($kubectl describe pod "$pod" | grep 'IP:' | awk '{ print $2 }') && echo "ip=${ip}"
61 |
62 | curl -i http://$ip:8888/ | grep "HTTP/1.1 200 OK"
63 |
64 | #| webthing-go-58d7cc6657 1 1 1 34m
65 |
66 | # Move process to slave host
67 | kubectl drain $HOSTNAME --ignore-daemonsets --delete-local-data
68 | kubectl cordon $HOSTNAME
69 | kubectl uncordon $hostname
70 | $kubectl get all --all-namespaces | grep $project
71 | ps auxf | grep -5 "$command" | grep -v grep # on slave
72 | #| go run ...
73 |
74 | # Moving back to master host
75 | kubectl drain $hostname --ignore-daemonsets --delete-local-data
76 | kubectl cordon $hostname
77 | kubectl uncordon $HOSTNAME
78 | $kubectl get all --all-namespaces | grep $project
79 | ps auxf | grep -- "$command" | grep -v grep # on master
80 | #| root 1561 0.2 0.2 3474520 48392 ? Ssl 16:08 0:26 /usr/bin/containerd
81 | #| root 11758 0.0 0.0 107344 5428 ? Sl 19:33 0:00 \_ containerd-shim -namespace moby ...
82 | #| root 11779 0.0 0.0 5620 2320 ? Ss 19:33 0:00 | \_ /usr/bin/make start
83 | #| root 11798 0.1 0.1 1295752 19404 ? Sl 19:33 0:00 | \_ go run example/simplest-thing.go
84 | #| root 11924 0.0 0.0 477272 5696 ? Sl 19:33 0:00 | \_ /tmp/go-build000000403/b001/exe/simplest-thing
85 | ```
86 |
87 | ## RESOURCES: ##
88 |
89 | *
90 |
--------------------------------------------------------------------------------
/docs/microk8s.md:
--------------------------------------------------------------------------------
1 | # WEBTHING-GO WITH MICROK8S #
2 |
3 | As an extra, here is a recipe to run a service using Microk8s:
4 |
5 | ### SERVICE: ###
6 |
7 | ```sh
8 | name="webthing-go"
9 | url="https://raw.githubusercontent.com/rzr/${name}/master/extra/tools/kube/$name.yml"
10 | export PATH="/snap/microk8s/current/:/snap/bin/:$PATH"
11 | kubectl="microk8s.kubectl"
12 | port=8888
13 | #
14 | sudo sync
15 | sudo snap install microk8s --classic # v1.15.2
16 |
17 | microk8s.enable dns
18 | $kubectl apply -f "${url}"
19 | $kubectl describe services/$name
20 | $kubectl get all --all-namespaces | grep "$name" | grep 'Running'
21 | # Through kube-proxy
22 | port=$($kubectl get svc ${name} -o=jsonpath="{.spec.ports[?(@.port==$port)].nodePort}")
23 | curl -i http://127.0.0.1:${port}/ | grep 'HTTP/1.1'
24 | #| HTTP/1.1 200 OK
25 |
26 | # Remove if needed
27 | microk8s.reset
28 | $kubectl delete --all pod
29 | $kubectl delete --all node
30 | $kubectl delete --all services
31 | sudo snap remove microk8s
32 | ```
33 |
34 |
35 | ### DEPLOYMENT: ###
36 |
37 | ```sh
38 | name="webthing-go"
39 | image="rzrfreefr/${name}:latest"
40 | export PATH=/snap/microk8s/current/:$PATH
41 | kubectl="kubectl"
42 | port=8888
43 |
44 | sudo sync
45 | sudo snap install microk8s --classic # v1.15.2
46 |
47 | sudo systemctl status | grep kube
48 | #| (...)
49 | #| /snap/microk8s/743/kube-apiserver
50 | #| (...)
51 |
52 | $kubectl cluster-info
53 | #| Kubernetes master is running at http://localhost:8080
54 |
55 | $kubectl get services
56 | #| NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
57 | #| kubernetes ClusterIP 10.152.183.1 443/TCP 15m
58 |
59 | $kubectl get nodes # Wait "Ready state"
60 | #| {host} Ready master 51s {version}
61 |
62 | microk8s.enable dns
63 |
64 | $kubectl run --generator=run-pod/v1 "${name}" --image="${image}"
65 |
66 | $kubectl get all --all-namespaces | grep "$name" # ContainerCreating, Running
67 | #| default pod/webthing-go 1/1 Running 0 19s
68 |
69 | pod=$($kubectl get all --all-namespaces \
70 | | grep -o "pod/${name}-.*" | cut -d/ -f2 | awk '{ print $1}' \
71 | || echo failure) && echo pod="$pod"
72 | $kubectl describe pod "$pod" | grep 'Status: * Running'
73 | ip=$($kubectl describe pod "$pod" | grep 'IP:' | awk '{ print $2 }') && echo "ip=${ip}"
74 |
75 | curl -qi "http://${ip}:${port}" | grep 'HTTP/1.1'
76 | #| HTTP/1.1 200 OK
77 |
78 | sudo cat "/proc/$(pidof simplest-webthing-go | cut -d' ' -f1)/smaps" | grep -2 ']'
79 | #| 00fc2000-00fe3000 rw-p 00000000 00:00 0 [heap]
80 | #| Size: 132 kB
81 | #| (...)
82 | #| 7fff1e838000-7fff1e859000 rw-p 00000000 00:00 0 [stack]
83 | #| Size: 132 kB
84 | #| (...)
85 | ```
86 |
87 | ## RESOURCES: ##
88 |
89 | *
90 | *
91 | *
92 |
--------------------------------------------------------------------------------
/example/simplest-webthing-go/simplest-thing.go:
--------------------------------------------------------------------------------
1 | // -*- Mode: Go; indent-tabs-mode: t -*-
2 | // Copyright: 2019-present Samsung Electronics Co., Ltd. and other contributors
3 | // SPDX-License-Identifier: MPL-2.0
4 |
5 | package main
6 |
7 | import (
8 | webthing "github.com/rzr/webthing-go"
9 | "fmt"
10 | )
11 |
12 | func valueHandler(update interface{}) {
13 | fmt.Println("change:", (update).(bool))
14 | }
15 |
16 | func main() {
17 | thing := webthing.NewThing(
18 | "urn:dev:ops:my-actuator-1234",
19 | "ActuatorExample",
20 | []string{"OnOffSwitch"},
21 | "An actuator example")
22 |
23 | onProperty := webthing.NewProperty("on", "boolean", false, valueHandler)
24 | thing.AddProperty(onProperty)
25 |
26 | server := webthing.NewServer(thing, 8888)
27 | server.Start()
28 | }
29 |
--------------------------------------------------------------------------------
/example/single-webthing-go/single-thing.go:
--------------------------------------------------------------------------------
1 | // -*- Mode: Go; indent-tabs-mode: t -*-
2 | // Copyright: 2019-present Samsung Electronics Co., Ltd. and other contributors
3 | // SPDX-License-Identifier: MPL-2.0
4 |
5 | package main
6 |
7 | import (
8 | webthing "github.com/rzr/webthing-go"
9 | )
10 |
11 | func main() {
12 | thing := webthing.NewThing(
13 | "urn:dev:ops:my-lamp-1234",
14 | "My Lamp",
15 | []string{"OnOffSwitch", "Light"},
16 | "A web connected lamp")
17 |
18 | onProperty := webthing.NewProperty("on", "boolean", false, nil)
19 | thing.AddProperty(onProperty)
20 |
21 | brightnessProperty := webthing.NewProperty("brightness", "integer", 0, nil)
22 | thing.AddProperty(brightnessProperty)
23 |
24 | server := webthing.NewServer(thing, 8888)
25 | server.Start()
26 | }
27 |
--------------------------------------------------------------------------------
/extra/tools/docker/debian/Dockerfile:
--------------------------------------------------------------------------------
1 | #!/bin/echo docker build . -f
2 | # -*- coding: utf-8 -*-
3 | # SPDX-License-Identifier: MIT
4 | #{
5 | # Copyright 2019-present Samsung Electronics France SAS, and other contributors
6 | #
7 | # This Source Code Form is subject to the terms of the MIT Licence
8 | # If a copy of the MIT was not distributed with this file
9 | # You can obtain one at:
10 | # https://spdx.org/licenses/MIT.html
11 | #}
12 |
13 | FROM golang:1.12.9 as webthing-go-builder
14 | MAINTAINER Philippe Coval (p.coval@samsung.com)
15 |
16 | ENV DEBIAN_FRONTEND noninteractive
17 | ENV LC_ALL en_US.UTF-8
18 | ENV LANG ${LC_ALL}
19 |
20 | RUN echo "#log: Configuring locales" \
21 | && set -x \
22 | && apt-get update -y \
23 | && apt-get install -y locales \
24 | && echo "${LC_ALL} UTF-8" | tee /etc/locale.gen \
25 | && locale-gen ${LC_ALL} \
26 | && dpkg-reconfigure locales \
27 | && sync
28 |
29 | ENV project webthing-go
30 | ENV project_dir /go/src/github.com/rzr/${project}/
31 | ADD Makefile ${project_dir}
32 | WORKDIR ${project_dir}
33 | RUN echo "#log: Setup system" \
34 | && apt-get update -y \
35 | && apt-get install -y make sudo \
36 | && apt-get clean \
37 | && sync
38 |
39 | ADD . ${project_dir}
40 | WORKDIR ${project_dir}
41 | RUN echo "#log: ${project}: Preparing sources" \
42 | && set -x \
43 | && make all \
44 | && sync
45 |
46 | FROM debian:10
47 | ENV project webthing-go
48 | ENV project_dir /go/src/github.com/rzr/${project}/
49 | COPY --from=webthing-go-builder ${project_dir}/simplest-webthing-go /usr/local/bin/
50 | EXPOSE 8888
51 | ENTRYPOINT [ "/usr/local/bin/simplest-webthing-go" ]
52 | CMD []
53 |
--------------------------------------------------------------------------------
/extra/tools/kube/Makefile:
--------------------------------------------------------------------------------
1 | #! /usr/bin/make -f
2 | # -*- makefile -*-
3 | # ex: set tabstop=4 noexpandtab:
4 | # Copyright: 2019-present Samsung Electronics Co., Ltd. and other contributors
5 | # SPDX-License-Identifier: MPL-2.0
6 |
7 | name?=webthing-go
8 |
9 | ${name}.yml: deployment.yml service.yml Makefile
10 | @echo '#YAML' > $@
11 | @echo '---' >> $@
12 | cat deployment.yml >> $@
13 | @echo '---' >> $@
14 | cat service.yml >> $@
15 | @echo '---' >> $@
16 |
--------------------------------------------------------------------------------
/extra/tools/kube/deployment.yml:
--------------------------------------------------------------------------------
1 | apiVersion: extensions/v1beta1
2 | kind: Deployment
3 | metadata:
4 | name: webthing-go
5 | spec:
6 | replicas: 1
7 | template:
8 | metadata:
9 | labels:
10 | run: webthing-go
11 | spec:
12 | containers:
13 | - image: rzrfreefr/webthing-go:latest
14 | name: webthing-go
15 | ports:
16 | - containerPort: 8888
17 |
--------------------------------------------------------------------------------
/extra/tools/kube/service.yml:
--------------------------------------------------------------------------------
1 | apiVersion: v1
2 | kind: Service
3 | metadata:
4 | name: webthing-go
5 | spec:
6 | ports:
7 | - nodePort: 30080
8 | port: 8888
9 | protocol: TCP
10 | targetPort: 8888
11 | selector:
12 | run: webthing-go
13 | sessionAffinity: None
14 | type: NodePort
15 | status:
16 | loadBalancer: {}
17 |
--------------------------------------------------------------------------------
/extra/tools/kube/webthing-go.yml:
--------------------------------------------------------------------------------
1 | #YAML
2 | ---
3 | apiVersion: extensions/v1beta1
4 | kind: Deployment
5 | metadata:
6 | name: webthing-go
7 | spec:
8 | replicas: 1
9 | template:
10 | metadata:
11 | labels:
12 | run: webthing-go
13 | spec:
14 | containers:
15 | - image: rzrfreefr/webthing-go:latest
16 | name: webthing-go
17 | ports:
18 | - containerPort: 8888
19 | ---
20 | apiVersion: v1
21 | kind: Service
22 | metadata:
23 | name: webthing-go
24 | spec:
25 | ports:
26 | - nodePort: 30080
27 | port: 8888
28 | protocol: TCP
29 | targetPort: 8888
30 | selector:
31 | run: webthing-go
32 | sessionAffinity: None
33 | type: NodePort
34 | status:
35 | loadBalancer: {}
36 | ---
37 |
--------------------------------------------------------------------------------
/go.mod:
--------------------------------------------------------------------------------
1 | module github.com/rzr/webthing-go
2 |
3 | go 1.12
4 |
5 | require github.com/julienschmidt/httprouter v1.2.0
6 |
--------------------------------------------------------------------------------
/go.sum:
--------------------------------------------------------------------------------
1 | github.com/julienschmidt/httprouter v1.2.0 h1:TDTW5Yz1mjftljbcKqRcrYhd4XeOoI98t+9HbQbYf7g=
2 | github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w=
3 |
--------------------------------------------------------------------------------
/webthing.go:
--------------------------------------------------------------------------------
1 | // -*- Mode: Go; indent-tabs-mode: t -*-
2 | // Copyright: 2019-present Samsung Electronics Co., Ltd. and other contributors
3 | // SPDX-License-Identifier: MPL-2.0
4 |
5 | package webthing
6 |
7 | import (
8 | "encoding/json"
9 | "fmt"
10 | "github.com/julienschmidt/httprouter"
11 | "io"
12 | "net/http"
13 | )
14 |
15 | // Value is a multitypes placeholder, only one is used
16 | type Value struct {
17 | boolean bool
18 | integer int
19 | number float64
20 | string string
21 | }
22 |
23 | // Property is made of value(s)
24 | type Property struct {
25 | name string
26 | valuetype string
27 | value *Value
28 | handler func(interface{})
29 | }
30 |
31 | func (property Property) setValue(value interface{}) {
32 | switch property.valuetype {
33 | case "boolean":
34 | property.value.boolean = (value).(bool)
35 | case "integer":
36 | property.value.integer = (value).(int)
37 | case "number":
38 | property.value.number = (value).(float64)
39 | case "string":
40 | property.value.string = (value).(string)
41 | }
42 | if property.handler != nil {
43 | property.handler(value)
44 | }
45 | }
46 |
47 | func (property Property) getValue() interface{} {
48 | switch property.valuetype {
49 | case "boolean":
50 | return property.value.boolean
51 | case "integer":
52 | return property.value.integer
53 | case "number":
54 | return property.value.number
55 | case "string":
56 | return property.value.string
57 | }
58 | return nil
59 | }
60 |
61 | // NewProperty contructs and assign value
62 | func NewProperty(name string, valuetype string, value interface{}, handler func(interface{})) *Property {
63 | var property = Property{name: name, valuetype: valuetype, handler: handler}
64 | property.value = &Value{}
65 | property.setValue(value)
66 | return &property
67 | }
68 |
69 | // Thing is made of Property(ies)
70 | type Thing struct {
71 | id string
72 | title string
73 | context string
74 | types []string
75 | description string
76 | properties map[string]Property
77 | href string
78 | }
79 |
80 | // AddProperty adds property (along values) to thing
81 | func (thing Thing) AddProperty(property *Property) {
82 | thing.properties[property.name] = *property
83 | }
84 |
85 | func (thing Thing) getPropertiesDescriptions() map[string]interface{} {
86 | result := make(map[string]interface{})
87 |
88 | for name, property := range thing.properties {
89 | description := make(map[string]interface{})
90 | description["type"] = property.valuetype
91 | description["href"] = thing.href + "properties/" + name
92 | result[name] = description
93 | }
94 | return result
95 | }
96 |
97 | // NewThing construct without properties
98 | func NewThing(id string, title string, types []string, description string) *Thing {
99 | thing := Thing{
100 | id: id,
101 | title: title,
102 | href: "/",
103 | properties: make(map[string]Property),
104 | types: types,
105 | description: description,
106 | context: "https://iot.mozilla.org/schemas"}
107 | if thing.types == nil {
108 | thing.types = make([]string, 0)
109 | }
110 | return &thing
111 | }
112 |
113 | // Server is an HTTP server made for webthings model
114 | type Server struct {
115 | thing *Thing
116 | port int
117 | }
118 |
119 | func (server Server) thingHandler(w http.ResponseWriter, req *http.Request, _ httprouter.Params) {
120 | description := make(map[string]interface{})
121 | description["id"] = server.thing.id
122 | description["title"] = server.thing.title
123 | description["@context"] = server.thing.context
124 | description["@type"] = server.thing.types
125 | description["properties"] = server.thing.getPropertiesDescriptions()
126 | description["events"] = make(map[string]interface{})
127 | description["links"] = [...]map[string]interface{}{
128 | {"rel": "properties", "href": "/properties"}}
129 | description["description"] = server.thing.description
130 | description["actions"] = make(map[string]interface{})
131 |
132 | description["href"] = server.thing.href
133 |
134 | // https://github.com/golang/go/issues/28940
135 | scheme := "http"
136 | if req.TLS != nil {
137 | scheme = "https"
138 | }
139 | description["base"] = scheme + "://" + req.Host + req.URL.RequestURI()
140 |
141 | description["security"] = "nosec_sc"
142 | description["securityDefinitions"] = make(map[string]interface{})
143 | description["securityDefinitions"].(map[string]interface{})["nosec_sc"] =
144 | map[string]interface{}{"scheme": "nosec"}
145 |
146 | var body, _ = json.Marshal(description)
147 | io.WriteString(w, string(body))
148 | }
149 |
150 | func (server Server) propertiesHandler(w http.ResponseWriter, req *http.Request, _ httprouter.Params) {
151 | description := make(map[string]interface{})
152 | for name, property := range server.thing.properties {
153 | description[name] = property.getValue()
154 | }
155 | var body, _ = json.Marshal(description)
156 | io.WriteString(w, string(body))
157 |
158 | }
159 |
160 | func (server Server) propertyPutHandler(w http.ResponseWriter, req *http.Request, params httprouter.Params) {
161 | decoder := json.NewDecoder(req.Body)
162 | object := make(map[string]interface{})
163 | err := decoder.Decode(&object)
164 | if err != nil {
165 | fmt.Println(err)
166 | }
167 | name := params.ByName("propertyName")
168 | property := server.thing.properties[name]
169 | property.setValue(object[name])
170 | var body, _ = json.Marshal(object)
171 | io.WriteString(w, string(body))
172 | }
173 |
174 | func (server Server) propertyGetHandler(w http.ResponseWriter, req *http.Request, params httprouter.Params) {
175 | name := params.ByName("propertyName")
176 | property := server.thing.properties[name]
177 | object := make(map[string]interface{})
178 | object[name] = property.getValue()
179 | var body, _ = json.Marshal(object)
180 | io.WriteString(w, string(body))
181 | }
182 |
183 | // NewServer constructs an http server to be started
184 | func NewServer(thing *Thing, port int) *Server {
185 | return &Server{thing: thing, port: port}
186 | }
187 |
188 | // Start listening for incoming requests and process using handlers
189 | func (server Server) Start() {
190 | router := httprouter.New()
191 | router.GET("/", server.thingHandler)
192 | router.GET("/properties", server.propertiesHandler)
193 | router.GET("/properties/:propertyName", server.propertyGetHandler)
194 | router.PUT("/properties/:propertyName", server.propertyPutHandler)
195 |
196 | address := fmt.Sprintf(":%d", server.port)
197 | fmt.Print("Listening: ")
198 | fmt.Println(address)
199 |
200 | err := http.ListenAndServe(address, router)
201 | fmt.Println(err)
202 | }
203 |
--------------------------------------------------------------------------------