Func%onal Programming at LumiGuide



Similar documents
CORBA Programming with TAOX11. The C++11 CORBA Implementation

IOS110. Virtualization 5/27/2014 1

Reading and Writing PCD Files The PCD File Format The Grabber Interface Writing a Custom Grabber PCL :: I/O. Suat Gedikli, Nico Blodow

Server Virtualization with Windows Server Hyper-V and System Center

Installing Java (Windows) and Writing your First Program

Functional Programming in C++11

Arduino Internet Connectivity: Maintenance Manual Julian Ryan Draft No. 7 April 24, 2015

Keil C51 Cross Compiler

Last not not Last Last Next! Next! Line Line Forms Forms Here Here Last In, First Out Last In, First Out not Last Next! Call stack: Worst line ever!

Retour vers le futur des bibliothèques de squelettes algorithmiques et DSL

JAVA Program For Processing SMS Messages

IBM Watson Ecosystem. Getting Started Guide

Help on the Embedded Software Block

First Java Programs. V. Paúl Pauca. CSC 111D Fall, Department of Computer Science Wake Forest University. Introduction to Computer Science

Object Oriented Software Design II

System Requirements for Microsoft Dynamics SL 2015

Software documentation systems

Datacenter Operating Systems

Mobile Labs Plugin for IBM Urban Code Deploy

Customize Mobile Apps with MicroStrategy SDK: Custom Security, Plugins, and Extensions

Android and OpenCV Tutorial

Overview of Web Services API

1 Abstract Data Types Information Hiding

Version control with Subversion

The full setup includes the server itself, the server control panel, Firebird Database Server, and three sample applications with source code.

Sample CSE8A midterm Multiple Choice (circle one)

TCP/IP Networking, Part 2: Web-Based Control

Government Girls Polytechnic, Bilaspur

Linux Kernel Rootkit : Virtual Terminal Key Logger

NETFORT LANGUARDIAN INSTALLING LANGUARDIAN ON MICROSOFT HYPER V

Working With Virtual Hosts on Pramati Server

Channel Access Client Programming. Andrew Johnson Computer Scientist, AES-SSG

Drupal CMS for marketing sites

Using NixOS for declarative deployment and testing

Server Virtualization with Windows Server Hyper-V and System Center

PetaLinux SDK User Guide. Application Development Guide

Iotivity Programmer s Guide Soft Sensor Manager for Android

Computer Systems II. Unix system calls. fork( ) wait( ) exit( ) How To Create New Processes? Creating and Executing Processes

The C Programming Language course syllabus associate level

Virtualization Technologies

Last Class: OS and Computer Architecture. Last Class: OS and Computer Architecture

Hardware and Software Requirements for Installing California.pro

I/O Virtualization The Next Virtualization Frontier

APS PACKAGE LISTEQ CLOUD DESKTOP Specification

DHCP Server Port-Based Address Allocation

Data Management Applications with Drupal as Your Framework

For the next three questions, consider the class declaration: Member function implementations put inline to save space.

3F6 - Software Engineering and Design. Handout 10 Distributed Systems I With Markup. Steve Young

Platform as a Service and Container Clouds

Functional Programming. Functional Programming Languages. Chapter 14. Introduction

Continuous Integration Part 2

CSI33 Data Structures

Server Virtualization with Windows Server Hyper-V and System Center

Webapps Vulnerability Report

How To Write A Distributed Deployment System On Nix (Programming)

Telit AppZone Programming Tips

Application-Level Debugging and Profiling: Gaps in the Tool Ecosystem. Dr Rosemary Francis, Ellexus

Operating Systems Virtualization mechanisms

Resco CRM Server Guide. How to integrate Resco CRM with other back-end systems using web services

Deploying Dedicated Virtual Desktops in Hosted Environments

Deploying Dedicated Virtual Desktops in Hosted Environments

The Nix project. Sander van der Burg. June 24, Delft University of Technology, EEMCS, Department of Software Technology

3.5. cmsg Developer s Guide. Data Acquisition Group JEFFERSON LAB. Version

Virtualization Support - Real Backups of Virtual Environments

Anh Quach, Matthew Rajman, Bienvenido Rodriguez, Brian Rodriguez, Michael Roefs, Ahmed Shaikh

Virtuozzo Virtualization SDK

C++ INTERVIEW QUESTIONS

Specific Simple Network Management Tools

Deep Freeze and Microsoft System Center Configuration Manager 2012 Integration

WCF and Windows Activation Service(WAS)

Deploying Windows Streaming Media Servers NLB Cluster and metasan

Installing & Using KVM with Virtual Machine Manager COSC 495

Implementing a WCF Service in the Real World

CSCE 665: Lab Basics. Virtual Machine. Guofei Gu

deploying meteor with meteor up

Development Techniques for Native/Hybrid Tizen Apps. Presented by Kirill Kruchinkin

Services Provider License Agreement Cloud Platform Suite & Guest

CONFIGURING MNLB FOR LOAD BALANCING EXCHANGE 2013 CU2 CAS SERVERS FOR HIGH AVAILABILITY

Module 5 Introduction to Processes and Controls

Configuring Data Masking

Eylean server deployment guide

9/26/2011. What is Virtualization? What are the different types of virtualization.

Chapter 15 Functional Programming Languages

Web Development using PHP (WD_PHP) Duration 1.5 months

Creating Mobile Applications on Top of SAP, Part 1

Compiler Construction

Informatica e Sistemi in Tempo Reale

Transcription:

Func%onal Programming at LumiGuide

Bas van Dijk? Sensor Sense (Nijmegen) Be?er (Zürich, Switzerland) ZuriHac! CTO @ LumiGuide (Nijmegen)

I some%mes wear a suit ;)

LumiGuide

P-route Bicycle

Rack-independent sensors

1 sensor is able to simultaneously detect 40-60 cycle rack spaces a minute

Detec%on of rack-free parking spaces

Detec%on of rack-free parking spaces

Outdoor signage Signage Indoor signage

Management SoZware

GHCJS & blaze-react (Simon Meier)

GHCJS & blaze-react (Simon Meier) data App state action = App { appinitialstate :: state, appinitialrequests :: [IO action], appapplyaction :: action -> Transition state action, apprender :: state -> Html action } type Transition state action = state -> (state, [IO action]) runapp :: App state action -> IO () data Html action = p :: Html action -> Html action input :: Html action (!) :: ( Attributable h action) => h -> Attribute action -> h onvaluechange :: (Text -> action) -> Attribute action

thea: Haskell binding to OpenCV-3.1 exposed-modules: OpenCV, OpenCV.Core, OpenCV.Core.Types, OpenCV.Core.Types.Mat, OpenCV.Core.Types.Mat.HMat, OpenCV.Core.Types.Mat.Repa, OpenCV.Core.ArrayOps, OpenCV.Unsafe, OpenCV.ImgProc.ImgFiltering, OpenCV.ImgProc.GeometricImgTransform, OpenCV.ImgProc.MiscImgTransform, OpenCV.ImgProc.Drawing, OpenCV.ImgProc.StructuralAnalysis, OpenCV.ImgProc.ObjectDetection, OpenCV.ImgProc.Types, OpenCV.ImgCodecs, OpenCV.HighGui, OpenCV.Video, OpenCV.JSON

imencode :: OutputFormat -> Mat -> Either CvException ByteString imencode format mat = unsafeperformio $ withmatptr mat $ \matptr -> withcstring ext $ \extptr -> alloca $ \(bufptrptr :: Ptr (Ptr CUChar)) -> alloca $ \(vecptrptr :: Ptr (Ptr ())) -> alloca $ \(c'bufsizeptr :: Ptr CInt) -> mask_ $ do ptrexception <- [cvexcept const int * const paramsptr = $vec-ptr:(int * params); std::vector<uchar> * vec = new std::vector<uchar>(); *$(void * * vecptrptr) = reinterpret_cast<void *>(vec); std::vector<int> params(paramsptr, paramsptr + $vec-len:params); cv::imencode( $(char * extptr), *$(Mat * matptr), *vec, params ); *$(int * c'bufsizeptr) = vec->size(); *$(unsigned char * * bufptrptr) = &((*vec)[0]); ] vecptr <- peek vecptrptr if ptrexception /= nullptr then do freevec vecptr Left <$> cvexceptionfromptr (pure ptrexception) else do bufsize <- peek c'bufsizeptr bufptr <- peek bufptrptr bs <- BU.unsafePackCStringFinalizer (castptr bufptr) (fromintegral bufsize) (freevec vecptr) pure $ Right bs where (ext :: String, params :: Vector CInt) = marshalloutputformat format freevec :: Ptr () -> IO () freevec vecptr = [C.exp void { delete reinterpret_cast< std::vector<uchar> * >($(void * vecptr)) } ]

imencode :: OutputFormat -> Mat -> Either CvException ByteString imencode format mat = unsafeperformio $ withmatptr mat $ \matptr -> withcstring ext $ \extptr -> alloca $ \(bufptrptr :: Ptr (Ptr CUChar)) -> alloca $ \(vecptrptr :: Ptr (Ptr ())) -> alloca $ \(c'bufsizeptr :: Ptr CInt) -> mask_ $ do ptrexception <- [cvexcept const int * const paramsptr = $vec-ptr:(int * params); std::vector<uchar> * vec = new std::vector<uchar>(); *$(void * * vecptrptr) = reinterpret_cast<void *>(vec); std::vector<int> params(paramsptr, paramsptr + $vec-len:params); cv::imencode( $(char * extptr), *$(Mat * matptr), *vec, params ); *$(int * c'bufsizeptr) = vec->size(); *$(unsigned char * * bufptrptr) = &((*vec)[0]); ] vecptr <- peek vecptrptr if ptrexception /= nullptr then do freevec vecptr Left <$> cvexceptionfromptr (pure ptrexception) else do bufsize <- peek c'bufsizeptr bufptr <- peek bufptrptr bs <- BU.unsafePackCStringFinalizer (castptr bufptr) (fromintegral bufsize) (freevec vecptr) pure $ Right bs where (ext :: String, params :: Vector CInt) = marshalloutputformat format data OutputFormat = OutputBmp OutputExr OutputHdr Bool OutputJpeg JpegParams OutputJpeg2000 OutputPng PngParams OutputPxm Bool OutputSunras OutputTiff OutputWebP Int freevec :: Ptr () -> IO () freevec vecptr = [C.exp void { delete reinterpret_cast< std::vector<uchar> * >($(void * vecptr)) } ]

imencode :: OutputFormat -> Mat -> Either CvException ByteString imencode format mat = unsafeperformio $ withmatptr mat $ \matptr -> withcstring ext $ \extptr -> alloca $ \(bufptrptr :: Ptr (Ptr CUChar)) -> alloca $ \(vecptrptr :: Ptr (Ptr ())) -> alloca $ \(c'bufsizeptr :: Ptr CInt) -> mask_ $ do ptrexception <- [cvexcept const int * const paramsptr = $vec-ptr:(int * params); std::vector<uchar> * vec = new std::vector<uchar>(); *$(void * * vecptrptr) = reinterpret_cast<void *>(vec); std::vector<int> params(paramsptr, paramsptr + $vec-len:params); cv::imencode( $(char * extptr), *$(Mat * matptr), *vec, params ); *$(int * c'bufsizeptr) = vec->size(); *$(unsigned char * * bufptrptr) = &((*vec)[0]); ] vecptr <- peek vecptrptr if ptrexception /= nullptr then do freevec vecptr Left <$> cvexceptionfromptr (pure ptrexception) else do bufsize <- peek c'bufsizeptr bufptr <- peek bufptrptr bs <- BU.unsafePackCStringFinalizer (castptr bufptr) (fromintegral bufsize) (freevec vecptr) pure $ Right bs where (ext :: String, params :: Vector CInt) = marshalloutputformat format freevec :: Ptr () -> IO () freevec vecptr = [C.exp void { delete reinterpret_cast< std::vector<uchar> * >($(void * vecptr)) } ]

imencode :: OutputFormat -> Mat -> Either CvException ByteString imencode format mat = unsafeperformio $ withmatptr mat $ \matptr -> withcstring ext $ \extptr -> alloca $ \(bufptrptr :: Ptr (Ptr CUChar)) -> alloca $ \(vecptrptr :: Ptr (Ptr ())) -> alloca $ \(c'bufsizeptr :: Ptr CInt) -> mask_ $ do ptrexception <- [cvexcept const int * const paramsptr = $vec-ptr:(int * params); std::vector<uchar> * vec = new std::vector<uchar>(); *$(void * * vecptrptr) = reinterpret_cast<void *>(vec); std::vector<int> params(paramsptr, paramsptr + $vec-len:params); cv::imencode( $(char * extptr), *$(Mat * matptr), *vec, params ); *$(int * c'bufsizeptr) = vec->size(); *$(unsigned char * * bufptrptr) = &((*vec)[0]); ] vecptr <- peek vecptrptr if ptrexception /= nullptr then do freevec vecptr Left <$> cvexceptionfromptr (pure ptrexception) else do bufsize <- peek c'bufsizeptr bufptr <- peek bufptrptr bs <- BU.unsafePackCStringFinalizer (castptr bufptr) (fromintegral bufsize) (freevec vecptr) pure $ Right bs where (ext :: String, params :: Vector CInt) = marshalloutputformat format freevec :: Ptr () -> IO () freevec vecptr = [C.exp void { delete reinterpret_cast< std::vector<uchar> * >($(void * vecptr)) } ]

imencode :: OutputFormat -> Mat -> Either CvException ByteString imencode format mat = unsafeperformio $ withmatptr mat $ \matptr -> withcstring ext $ \extptr -> alloca $ \(bufptrptr :: Ptr (Ptr CUChar)) -> alloca $ \(vecptrptr :: Ptr (Ptr ())) -> alloca $ \(c'bufsizeptr :: Ptr CInt) -> mask_ $ do ptrexception <- [cvexcept const int * const paramsptr = $vec-ptr:(int * params); std::vector<uchar> * vec = new std::vector<uchar>(); *$(void * * vecptrptr) = reinterpret_cast<void *>(vec); std::vector<int> params(paramsptr, paramsptr + $vec-len:params); cv::imencode( $(char * extptr), *$(Mat * matptr), *vec, params ); *$(int * c'bufsizeptr) = vec->size(); *$(unsigned char * * bufptrptr) = &((*vec)[0]); ] vecptr <- peek vecptrptr if ptrexception /= nullptr then do freevec vecptr Left <$> cvexceptionfromptr (pure ptrexception) else do bufsize <- peek c'bufsizeptr bufptr <- peek bufptrptr bs <- BU.unsafePackCStringFinalizer (castptr bufptr) (fromintegral bufsize) (freevec vecptr) pure $ Right bs where (ext :: String, params :: Vector CInt) = marshalloutputformat format freevec :: Ptr () -> IO () freevec vecptr = [C.exp void { delete reinterpret_cast< std::vector<uchar> * >($(void * vecptr)) } ]

imencode :: OutputFormat -> Mat -> Either CvException ByteString imencode format mat = unsafeperformio $ withmatptr mat $ \matptr -> withcstring ext $ \extptr -> inline-c (Francesco Mazzoli, Mathieu Boespflug FP Complete) alloca $ \(bufptrptr :: Ptr (Ptr CUChar)) -> alloca $ \(vecptrptr :: Ptr (Ptr ())) -> alloca $ \(c'bufsizeptr :: Ptr CInt) -> mask_ $ do ptrexception <- [cvexcept const int * const paramsptr = $vec-ptr:(int * params); std::vector<uchar> * vec = new std::vector<uchar>(); *$(void * * vecptrptr) = reinterpret_cast<void *>(vec); std::vector<int> params(paramsptr, paramsptr + $vec-len:params); cv::imencode( $(char * extptr), *$(Mat * matptr), *vec, params ); *$(int * c'bufsizeptr) = vec->size(); *$(unsigned char * * bufptrptr) = &((*vec)[0]); ] vecptr <- peek vecptrptr if ptrexception /= nullptr then do freevec vecptr Left <$> cvexceptionfromptr (pure ptrexception) else do bufsize <- peek c'bufsizeptr bufptr <- peek bufptrptr bs <- BU.unsafePackCStringFinalizer (castptr bufptr) (fromintegral bufsize) (freevec vecptr) pure $ Right bs where (ext :: String, params :: Vector CInt) = marshalloutputformat format freevec :: Ptr () -> IO () freevec vecptr = [C.exp void { delete reinterpret_cast< std::vector<uchar> * >($(void * vecptr)) } ]

imencode :: OutputFormat -> Mat -> Either CvException ByteString imencode format mat = unsafeperformio $ withmatptr mat $ \matptr -> withcstring ext $ \extptr -> alloca $ \(bufptrptr :: Ptr (Ptr CUChar)) -> alloca $ \(vecptrptr :: Ptr (Ptr ())) -> alloca $ \(c'bufsizeptr :: Ptr CInt) -> mask_ $ do ptrexception <- [cvexcept const int * const paramsptr = $vec-ptr:(int * params); std::vector<uchar> * vec = new std::vector<uchar>(); *$(void * * vecptrptr) = reinterpret_cast<void *>(vec); std::vector<int> params(paramsptr, paramsptr + $vec-len:params); cv::imencode( $(char * extptr), *$(Mat * matptr), *vec, params ); *$(int * c'bufsizeptr) = vec->size(); *$(unsigned char * * bufptrptr) = &((*vec)[0]); ] vecptr <- peek vecptrptr if ptrexception /= nullptr then do freevec vecptr Left <$> cvexceptionfromptr (pure ptrexception) else do bufsize <- peek c'bufsizeptr bufptr <- peek bufptrptr bs <- BU.unsafePackCStringFinalizer (castptr bufptr) (fromintegral bufsize) (freevec vecptr) pure $ Right bs where (ext :: String, params :: Vector CInt) = marshalloutputformat format cvexcept :: QuasiQuoter cvexcept = C.block { quoteexp = \s -> quoteexp C.block (cvexceptwrap s) } cvexceptwrap :: String -> String cvexceptwrap s = "Exception * {\n\ \ try\n\ \ {\n " <> s <> "\n\ \ return NULL;\n\ \ }\n\ \ catch (const cv::exception & e)\n\ \ {\n\ \ return new cv::exception(e);\n\ \ }\n\ \}" freevec :: Ptr () -> IO () freevec vecptr = [C.exp void { delete reinterpret_cast< std::vector<uchar> * >($(void * vecptr)) } ]

imencode :: OutputFormat -> Mat -> Either CvException ByteString imencode format mat = unsafeperformio $ withmatptr mat $ \matptr -> withcstring ext $ \extptr -> alloca $ \(bufptrptr :: Ptr (Ptr CUChar)) -> alloca $ \(vecptrptr :: Ptr (Ptr ())) -> alloca $ \(c'bufsizeptr :: Ptr CInt) -> mask_ $ do ptrexception <- [cvexcept const int * const paramsptr = $vec-ptr:(int * params); std::vector<uchar> * vec = new std::vector<uchar>(); *$(void * * vecptrptr) = reinterpret_cast<void *>(vec); std::vector<int> params(paramsptr, paramsptr + $vec-len:params); cv::imencode( $(char * extptr), *$(Mat * matptr), *vec, params ); *$(int * c'bufsizeptr) = vec->size(); *$(unsigned char * * bufptrptr) = &((*vec)[0]); ] vecptr <- peek vecptrptr if ptrexception /= nullptr then do freevec vecptr Left <$> cvexceptionfromptr (pure ptrexception) else do bufsize <- peek c'bufsizeptr bufptr <- peek bufptrptr bs <- BU.unsafePackCStringFinalizer (castptr bufptr) (fromintegral bufsize) (freevec vecptr) pure $ Right bs where (ext :: String, params :: Vector CInt) = marshalloutputformat format freevec :: Ptr () -> IO () freevec vecptr = [C.exp void { delete reinterpret_cast< std::vector<uchar> * >($(void * vecptr)) } ]

extern "C" { Exception * inline_c_opencv_imgcodecs_2_25828b73bb33f9d4698167b33554fcb1f7f72415 ( int * params_inline_c_0, void ** vecptrptr_inline_c_1, long params_inline_c_2, char * extptr_inline_c_3, Mat * matptr_inline_c_4, int * cbufsizeptr_27_inline_c_5, unsigned char ** bufptrptr_inline_c_6 ) { try { const int * const paramsptr = params_inline_c_0; std::vector<uchar> * vec = new std::vector<uchar>(); *vecptrptr_inline_c_1 = reinterpret_cast<void *>(vec); std::vector<int> params(paramsptr, paramsptr + params_inline_c_2); cv::imencode( extptr_inline_c_3, *matptr_inline_c_4, *vec, params ); *cbufsizeptr_27_inline_c_5 = vec->size(); *bufptrptr_inline_c_6 = &((*vec)[0]); return NULL; } catch (const cv::exception & e) { return new cv::exception(e); } }

Nix Nix: a purely, func%onal, lazy and dynamically typed programming language nixpkgs: a git repository of Nix expressions for Linux & Mac OS X packages NixOS: Nix-based Linux distribu%on Hydra: Nix-based con%nuous build system nixops: deploy sets of NixOS machines

$ ls /nix/store 0006h2k02xc3hjy7ddr0xk3b4mxzv2vx-gsl-1.16.tar.gz.drv 006cjanl30r789cis6qww6hh3ja2ri2w-engineers.nix 008gllqbf452a044bwnwgylaf7a9dlyf-perl-Text-Glob-0.09 008s4z7vx9zs78bk6zjfc2jw30mlj6vg-python2.7-setuptools-18.2 009fqvhziw9zj7b3a4qi624y93sklk4b-namespace-clean-0.25.tar.gz.drv 00b8q75g8lw8flvsnmcsjanxpc1afl80-nodejs-isarray-0.0.1.drv 00bnnx5ypgkk5g38wk37y9s1vjbgmagr-python-memcached-1.51.tar.gz.drv 00g8fmql256da1d2ks587d33k1qlndnk-String-ToIdentifier-EN-0.11.tar.gz 00gm250lj5wwqlq7q8gyfskcgccvmp79-topgit-0.9.tar.gz.drv

LumiOS NixOS extended with our own modules Configures everything: All facility servers All central servers All support servers All the worksta%ons of our engineers (virtualbox, hyperv and real hardware)

Development $ nix-build A lumi.facility.client /nix/store/z2mfz8h4dpcbrlmknpkqfmrjg9ni48l7-lumi-facility-client-0.0.1 $ nix-shell A lumi.facility.client

Hydra Con%nuous build system let pkgs = import./default.nix; workstation = hardware : (import (import <lumi/nixpkgs.nix> + /nixos) { configuration = import <lumi/os/workstation/hydra> hardware; }).system; in { central = pkgs.lumi.central; facility.client = pkgs.lumi.facility.client; facility.server = pkgs.lumi.facility.localserver; facility.install-cd-hydra = pkgs.lumi.facility.install-cd-hydra; pris-gateway = pkgs.lumi.pris-gateway; sensors-logger = pkgs.lumi.sensors-logger; py-vision-playground = pkgs.lumi.py-vision-playground; hs-vision-playground = pkgs.lumi.hs-vision-playground; command-poller = pkgs.lumi.command-poller; tender-slurper = pkgs.lumi.tender-slurper; thea thea-profiled = pkgs.haskellpackages.thea; = pkgs.profiledhaskellpackages.thea; workstation.virtualbox workstation.hyperv workstation.real = workstation <lumi/os/workstation/hardware/virtualbox.nix>; = workstation <lumi/os/workstation/hardware/hyperv.nix>; = workstation <lumi/os/workstation/hardware/real.nix>; }

nixops: deploying NixOS machines nixops create \ -state state.nixops \ --deployment stalling-net \ <stalling-net.nix>' \ <stalling-net-hardware.nix>'

stalling-net.nix let facility = namespace: in { network.description = "Stalling network"; zeus = import <lumi/os/central>; hera = { imports = [ <lumi/os/support> ]; support.pgmaster = "zeus"; }; nijmegen-verloren-toren = facility 1; utrecht-lange-koestraat = facility 2; utrecht-zadelstraat = facility 3; utrecht-vredenburg = facility 4; utrecht-westplein = facility 5; utrecht-stadhuis = facility 10; Logical configura%on utrecht-jaarbeursplein = { config,... }: { imports = [ <lumi/os/pris-gateway> ]; services.lumi.pris-gateway-poster.facilityservice = facilityservice config.networking.hostname; }; denhaag-stadhuis = facility 13; amsterdam-sportpark-ijburg = facility 14; }

stalling-net-hardware.nix let hetzner = mainip: ; facility = nic: ipaddress: defaultgateway: ; in { zeus = {imports = [ (hetzner 123.321.123.321") <lumi/os/central/hardware.nix> ];}; hera = {imports = [ (hetzner 321.123.321.123") <lumi/os/support/hardware.nix> ];}; } # nic ipaddress defaultgateway nijmegen-verloren-toren = facility "eno1" "10.0.1.2" "10.0.1.1"; utrecht-lange-koestraat = facility "eno1" "10.0.2.2" "10.0.2.1"; utrecht-zadelstraat = facility "eno1" "10.0.3.2" "10.0.3.1"; utrecht-vredenburg = facility "eno1" "10.0.4.2" "10.0.4.1"; utrecht-westplein = {imports=[(facility "eno1" "10.0.5.2" "10.0.5.1") (router-rebooter "10.0.5.1")];}; utrecht-jaarbeursplein = facility "enp3s0" "10.0.6.2" "10.0.6.1"; utrecht-stadhuis = facility "eno1" "10.0.7.2" "10.0.7.1"; amsterdam-sportpark-ijburg = facility "enp0s25" "10.0.8.2" "10.0.8.1"; denhaag-stadhuis = facility "enp3s0" "10.0.9.2" "10.0.9.1"; Physical configura%on

Deploy the network configura%on nixops deploy \ -state state.nixops \ --deployment stalling-net Provisions machines and other resources Copies Nix closures Ac%vates new configura%on

Have fun parking your bike!

Please ask me something?