![Page 1: Creating a dynamic software deployment solution using free/libre software](https://reader033.vdocuments.site/reader033/viewer/2022052311/5599241e1a28ab2f5e8b46f0/html5/thumbnails/1.jpg)
Creating a dynamic softwaredeployment solution using free/libresoftwareLinuxTag 2014 08.05.2014
Mattias GieseSolutions Architect for Systems Management and Monitoring
B1 Systems [email protected]
B1 Systems GmbH - Linux/Open Source Consulting, Training, Support & Development
![Page 2: Creating a dynamic software deployment solution using free/libre software](https://reader033.vdocuments.site/reader033/viewer/2022052311/5599241e1a28ab2f5e8b46f0/html5/thumbnails/2.jpg)
Agenda
B1 Systems GmbHCreating a dynamic software deployment
solution using free/libre software 2 / 51
![Page 3: Creating a dynamic software deployment solution using free/libre software](https://reader033.vdocuments.site/reader033/viewer/2022052311/5599241e1a28ab2f5e8b46f0/html5/thumbnails/3.jpg)
AgendaWorkflow/Process OverviewSCM HooksJenkinsOpen Build ServiceSpacewalkPuppet/Foreman
B1 Systems GmbHCreating a dynamic software deployment
solution using free/libre software 3 / 51
![Page 4: Creating a dynamic software deployment solution using free/libre software](https://reader033.vdocuments.site/reader033/viewer/2022052311/5599241e1a28ab2f5e8b46f0/html5/thumbnails/4.jpg)
Process Overview
B1 Systems GmbHCreating a dynamic software deployment
solution using free/libre software 4 / 51
![Page 5: Creating a dynamic software deployment solution using free/libre software](https://reader033.vdocuments.site/reader033/viewer/2022052311/5599241e1a28ab2f5e8b46f0/html5/thumbnails/5.jpg)
What are we trying to accomplish?Continuous Integration
New features should be merged as quickly as possibleConfidence that changes don’t break productionBase for test-driven development (TDD)
Continuous DeliveryWe don’t want to deploy every revision of our softwareBut would be cool if we could
B1 Systems GmbHCreating a dynamic software deployment
solution using free/libre software 5 / 51
![Page 6: Creating a dynamic software deployment solution using free/libre software](https://reader033.vdocuments.site/reader033/viewer/2022052311/5599241e1a28ab2f5e8b46f0/html5/thumbnails/6.jpg)
Process Overview
B1 Systems GmbHCreating a dynamic software deployment
solution using free/libre software 6 / 51
![Page 7: Creating a dynamic software deployment solution using free/libre software](https://reader033.vdocuments.site/reader033/viewer/2022052311/5599241e1a28ab2f5e8b46f0/html5/thumbnails/7.jpg)
Code Changes and Commit
B1 Systems GmbHCreating a dynamic software deployment
solution using free/libre software 7 / 51
![Page 8: Creating a dynamic software deployment solution using free/libre software](https://reader033.vdocuments.site/reader033/viewer/2022052311/5599241e1a28ab2f5e8b46f0/html5/thumbnails/8.jpg)
B1 Systems GmbHCreating a dynamic software deployment
solution using free/libre software 8 / 51
![Page 9: Creating a dynamic software deployment solution using free/libre software](https://reader033.vdocuments.site/reader033/viewer/2022052311/5599241e1a28ab2f5e8b46f0/html5/thumbnails/9.jpg)
Using SCM-HooksHooks → do stuffsupported in many SCMsgit-hooks may be run at different phasesUse Cases:
Syntax checkLinterEnforcement of other policyTriggering of other processes
We want to trigger Jenkins!
B1 Systems GmbHCreating a dynamic software deployment
solution using free/libre software 9 / 51
![Page 10: Creating a dynamic software deployment solution using free/libre software](https://reader033.vdocuments.site/reader033/viewer/2022052311/5599241e1a28ab2f5e8b46f0/html5/thumbnails/10.jpg)
Using SCM-Hooks
Simple post-receive hook#!/bin/bashAUTH=’myuser:pass’JOB=myjobTOKEN=mybuildtoken
echo Poking jenkins/usr/bin/curl --user $AUTH -s \"http://jenkins:8080/job/$JOB/build?token=$TOKEN"
B1 Systems GmbHCreating a dynamic software deployment
solution using free/libre software 10 / 51
![Page 11: Creating a dynamic software deployment solution using free/libre software](https://reader033.vdocuments.site/reader033/viewer/2022052311/5599241e1a28ab2f5e8b46f0/html5/thumbnails/11.jpg)
Testing with Jenkins
B1 Systems GmbHCreating a dynamic software deployment
solution using free/libre software 11 / 51
![Page 12: Creating a dynamic software deployment solution using free/libre software](https://reader033.vdocuments.site/reader033/viewer/2022052311/5599241e1a28ab2f5e8b46f0/html5/thumbnails/12.jpg)
Testing with Jenkins
B1 Systems GmbHCreating a dynamic software deployment
solution using free/libre software 12 / 51
![Page 13: Creating a dynamic software deployment solution using free/libre software](https://reader033.vdocuments.site/reader033/viewer/2022052311/5599241e1a28ab2f5e8b46f0/html5/thumbnails/13.jpg)
Jenkins OverviewThe artist formerly known as HudsonThe first address for CIcan be used as Cron, general Job-Scheduler or Monitor600+ plugins (nifty)Alternatives: Travis-CI, CruiseControl, Bamboo
B1 Systems GmbHCreating a dynamic software deployment
solution using free/libre software 13 / 51
![Page 14: Creating a dynamic software deployment solution using free/libre software](https://reader033.vdocuments.site/reader033/viewer/2022052311/5599241e1a28ab2f5e8b46f0/html5/thumbnails/14.jpg)
Jenkins OverviewMust-Have Plugins
WarningsPost-BuildBuild PipelinePromoted BuildsGitChuck Norris
B1 Systems GmbHCreating a dynamic software deployment
solution using free/libre software 14 / 51
![Page 15: Creating a dynamic software deployment solution using free/libre software](https://reader033.vdocuments.site/reader033/viewer/2022052311/5599241e1a28ab2f5e8b46f0/html5/thumbnails/15.jpg)
Usage in this scenarioJenkins
is triggered through git post-receive hookchecks out git-repo (specific branch)runs configured build stepsafter successful build: trigger packaging process
B1 Systems GmbHCreating a dynamic software deployment
solution using free/libre software 15 / 51
![Page 16: Creating a dynamic software deployment solution using free/libre software](https://reader033.vdocuments.site/reader033/viewer/2022052311/5599241e1a28ab2f5e8b46f0/html5/thumbnails/16.jpg)
Jenkins Post-Build
Post-Build Step, complete#!/bin/bashauth=’obsuser:passwd’project=’foobar’main_project=’internal-tools’git_host=’git.example.com’obs_api=’https://api.obs.example.com’branch=’development’service="<services><service name="tar_scm"><param name="scm">git</param><param name="url">git://${git_url}/${project}.git</param><param name="revision">$GIT_COMMIT</param>
</service>[...]</services>"echo $service | curl -u $auth -s -X PUT -T - \
"$obs_api/source/$main_project/$project/_service"
B1 Systems GmbHCreating a dynamic software deployment
solution using free/libre software 16 / 51
![Page 17: Creating a dynamic software deployment solution using free/libre software](https://reader033.vdocuments.site/reader033/viewer/2022052311/5599241e1a28ab2f5e8b46f0/html5/thumbnails/17.jpg)
Post-Build Step, Service File<services><service name="tar_scm"><param name="scm">git</param><param name="url">git://${git_url}/${project}.git</param><param name="revision">$GIT_COMMIT</param>
</service><service name="recompress"><param name="file">*$project*.tar</param><param name="compression">bz2</param>
</service><service name="download_url"><param name="path">/$project/$branch/${project}.spec</param><param name="host">$git_host</param><param name="protocol">https</param>
</service><service name="set_version"></service>
</services>
B1 Systems GmbHCreating a dynamic software deployment
solution using free/libre software 17 / 51
![Page 18: Creating a dynamic software deployment solution using free/libre software](https://reader033.vdocuments.site/reader033/viewer/2022052311/5599241e1a28ab2f5e8b46f0/html5/thumbnails/18.jpg)
Jenkins Post-Build
Post-Build Step, the trigger itselfecho $service | curl -u $auth -s -X PUT -T - \
"$obs_api/source/$main_project/$project/_service"
B1 Systems GmbHCreating a dynamic software deployment
solution using free/libre software 18 / 51
![Page 19: Creating a dynamic software deployment solution using free/libre software](https://reader033.vdocuments.site/reader033/viewer/2022052311/5599241e1a28ab2f5e8b46f0/html5/thumbnails/19.jpg)
Packaging
B1 Systems GmbHCreating a dynamic software deployment
solution using free/libre software 19 / 51
![Page 20: Creating a dynamic software deployment solution using free/libre software](https://reader033.vdocuments.site/reader033/viewer/2022052311/5599241e1a28ab2f5e8b46f0/html5/thumbnails/20.jpg)
Packaging with OBS
B1 Systems GmbHCreating a dynamic software deployment
solution using free/libre software 20 / 51
![Page 21: Creating a dynamic software deployment solution using free/libre software](https://reader033.vdocuments.site/reader033/viewer/2022052311/5599241e1a28ab2f5e8b46f0/html5/thumbnails/21.jpg)
Open Build Service OverviewBuild Platform for packages or live media (kiwi)builds RPM (SUSE/RHEL), DPKG (Debian/Ubuntu) andPacman (Archlinux)public reference install at build.opensuse.orgCentral build platform for openSUSE
B1 Systems GmbHCreating a dynamic software deployment
solution using free/libre software 21 / 51
![Page 22: Creating a dynamic software deployment solution using free/libre software](https://reader033.vdocuments.site/reader033/viewer/2022052311/5599241e1a28ab2f5e8b46f0/html5/thumbnails/22.jpg)
Open Build Service OverviewExtensive API (CLI is an API client)can run hooks after successful publishing of a package/projectAlternatives: None, koji if all you want is RHEL
B1 Systems GmbHCreating a dynamic software deployment
solution using free/libre software 22 / 51
![Page 23: Creating a dynamic software deployment solution using free/libre software](https://reader033.vdocuments.site/reader033/viewer/2022052311/5599241e1a28ab2f5e8b46f0/html5/thumbnails/23.jpg)
Open Build Service Overview
B1 Systems GmbHCreating a dynamic software deployment
solution using free/libre software 23 / 51
![Page 24: Creating a dynamic software deployment solution using free/libre software](https://reader033.vdocuments.site/reader033/viewer/2022052311/5599241e1a28ab2f5e8b46f0/html5/thumbnails/24.jpg)
Usage in this scenarioOpen Build Service is used
to build packages for different distributions/architecturesto trigger Spacewalk to sync packages
B1 Systems GmbHCreating a dynamic software deployment
solution using free/libre software 24 / 51
![Page 25: Creating a dynamic software deployment solution using free/libre software](https://reader033.vdocuments.site/reader033/viewer/2022052311/5599241e1a28ab2f5e8b46f0/html5/thumbnails/25.jpg)
Open Build Service Overview
B1 Systems GmbHCreating a dynamic software deployment
solution using free/libre software 25 / 51
![Page 26: Creating a dynamic software deployment solution using free/libre software](https://reader033.vdocuments.site/reader033/viewer/2022052311/5599241e1a28ab2f5e8b46f0/html5/thumbnails/26.jpg)
OBS should trigger Spacewalk!
OBS published-hook#!/usr/bin/env python2import xmlrpclibimport sysSPACEWALK_URL = "http://spacewalk.example.com/rpc/api"SPACEWALK_LOGIN = "apiuser"SPACEWALK_PASSWORD = "testing"try:
channel = sys.argv[1]client = xmlrpclib.Server(SPACEWALK_URL, verbose=0)key = client.auth.login(SPACEWALK_LOGIN, SPACEWALK_PASSWORD)client.channel.software.syncRepo(key,channel)client.auth.logout(key)
except Exception, e: # Gotta catch em allprint ’Failed to sync channel: ’, esys.exit(1)
B1 Systems GmbHCreating a dynamic software deployment
solution using free/libre software 26 / 51
![Page 27: Creating a dynamic software deployment solution using free/libre software](https://reader033.vdocuments.site/reader033/viewer/2022052311/5599241e1a28ab2f5e8b46f0/html5/thumbnails/27.jpg)
Publishing
B1 Systems GmbHCreating a dynamic software deployment
solution using free/libre software 27 / 51
![Page 28: Creating a dynamic software deployment solution using free/libre software](https://reader033.vdocuments.site/reader033/viewer/2022052311/5599241e1a28ab2f5e8b46f0/html5/thumbnails/28.jpg)
Package Publishing with Spacewalk
B1 Systems GmbHCreating a dynamic software deployment
solution using free/libre software 28 / 51
![Page 29: Creating a dynamic software deployment solution using free/libre software](https://reader033.vdocuments.site/reader033/viewer/2022052311/5599241e1a28ab2f5e8b46f0/html5/thumbnails/29.jpg)
Spacewalk OverviewSystem Lifecycle ManagementExtensive APIruns on RHEL/Fedora and Derivativessupports SUSE/RHEL and Derivatives, Debian somewhat.Base for SUSE Manager and Satellite (changing with 6.x)Alternatives: Pulp, if all you want is RHEL
B1 Systems GmbHCreating a dynamic software deployment
solution using free/libre software 29 / 51
![Page 30: Creating a dynamic software deployment solution using free/libre software](https://reader033.vdocuments.site/reader033/viewer/2022052311/5599241e1a28ab2f5e8b46f0/html5/thumbnails/30.jpg)
Usage in this scenarioProvisioning of packagesStaging of packagesAutomatic synchronization of packages in “Development”channelOn-Demand/automatic promotion of channel contents tointegration/production stages
B1 Systems GmbHCreating a dynamic software deployment
solution using free/libre software 30 / 51
![Page 31: Creating a dynamic software deployment solution using free/libre software](https://reader033.vdocuments.site/reader033/viewer/2022052311/5599241e1a28ab2f5e8b46f0/html5/thumbnails/31.jpg)
Delivery
B1 Systems GmbHCreating a dynamic software deployment
solution using free/libre software 31 / 51
![Page 32: Creating a dynamic software deployment solution using free/libre software](https://reader033.vdocuments.site/reader033/viewer/2022052311/5599241e1a28ab2f5e8b46f0/html5/thumbnails/32.jpg)
Package Delivery with Puppet/Foreman
B1 Systems GmbHCreating a dynamic software deployment
solution using free/libre software 32 / 51
![Page 33: Creating a dynamic software deployment solution using free/libre software](https://reader033.vdocuments.site/reader033/viewer/2022052311/5599241e1a28ab2f5e8b46f0/html5/thumbnails/33.jpg)
PuppetConfiguration Management Toolbased on Ruby, easy to learn DSLruns on many platforms (Linux, *nix, Windows)abstracts differences between those platformsis idempotentfeatures Inventory and Reporting on Infrastructure changesAlternatives: CFEngine, Chef, maybe Ansible or SaltStack
B1 Systems GmbHCreating a dynamic software deployment
solution using free/libre software 33 / 51
![Page 34: Creating a dynamic software deployment solution using free/libre software](https://reader033.vdocuments.site/reader033/viewer/2022052311/5599241e1a28ab2f5e8b46f0/html5/thumbnails/34.jpg)
Simple Puppet manifestpackage{’myapp’:
ensure => latest,}file{’/etc/myapp/config’:
ensure => file,owner => ’serviceuser’,group => ’servicegroup’,mode => ’0640’,content => template(’myapp-config.erb’),require => Package[’myapp’],notify => Service[’myapp’],
}service{’myapp’:
ensure => running,enable => true,require => Package[’myapp’],
}
B1 Systems GmbHCreating a dynamic software deployment
solution using free/libre software 34 / 51
![Page 35: Creating a dynamic software deployment solution using free/libre software](https://reader033.vdocuments.site/reader033/viewer/2022052311/5599241e1a28ab2f5e8b46f0/html5/thumbnails/35.jpg)
The ForemanWebApp and API to automate infrastructureintegrates well with Puppetcan manage DHCP, DNS, TFTP, Puppet, “Clouds"features nice reporting and auditingAlternatives:Provisioning: Cobbler, RazorManagement: Puppet Dashboard/Puppet Enterprise Console,
Rudder (CFEngine)
B1 Systems GmbHCreating a dynamic software deployment
solution using free/libre software 35 / 51
![Page 36: Creating a dynamic software deployment solution using free/libre software](https://reader033.vdocuments.site/reader033/viewer/2022052311/5599241e1a28ab2f5e8b46f0/html5/thumbnails/36.jpg)
Architecture Overview
B1 Systems GmbHCreating a dynamic software deployment
solution using free/libre software 36 / 51
![Page 37: Creating a dynamic software deployment solution using free/libre software](https://reader033.vdocuments.site/reader033/viewer/2022052311/5599241e1a28ab2f5e8b46f0/html5/thumbnails/37.jpg)
Usage of Foreman in this setupProvisioning of new bare-metal or virtual machinesSingle source of truth for PuppetReporting and Auditing of InfrastructureIdea: Use Foreman-API to trigger VM provisioning foracceptance tests
B1 Systems GmbHCreating a dynamic software deployment
solution using free/libre software 37 / 51
![Page 38: Creating a dynamic software deployment solution using free/libre software](https://reader033.vdocuments.site/reader033/viewer/2022052311/5599241e1a28ab2f5e8b46f0/html5/thumbnails/38.jpg)
System/Acceptance Tests
B1 Systems GmbHCreating a dynamic software deployment
solution using free/libre software 38 / 51
![Page 39: Creating a dynamic software deployment solution using free/libre software](https://reader033.vdocuments.site/reader033/viewer/2022052311/5599241e1a28ab2f5e8b46f0/html5/thumbnails/39.jpg)
System/Acceptance Tests
B1 Systems GmbHCreating a dynamic software deployment
solution using free/libre software 39 / 51
![Page 40: Creating a dynamic software deployment solution using free/libre software](https://reader033.vdocuments.site/reader033/viewer/2022052311/5599241e1a28ab2f5e8b46f0/html5/thumbnails/40.jpg)
OverviewVagrantDockerSmoketestsServerspec
B1 Systems GmbHCreating a dynamic software deployment
solution using free/libre software 40 / 51
![Page 41: Creating a dynamic software deployment solution using free/libre software](https://reader033.vdocuments.site/reader033/viewer/2022052311/5599241e1a28ab2f5e8b46f0/html5/thumbnails/41.jpg)
VagrantWrapper around different Hypervisors and Provisionerssupports VirtualBox (First Class), VMware (commercial),libvirtd (somewhat) and Dockerruns on Linux, Mac OS X, WindowsProvisioners may be Shell, Puppet, Chef and so onEasy to use:
1 mkdir myvm; cd myvm2 vagrant init precise64
http://files.vagrantup.com/precise64.box3 vagrant up4 vagrant ssh5 vagrant halt/destroy
B1 Systems GmbHCreating a dynamic software deployment
solution using free/libre software 41 / 51
![Page 42: Creating a dynamic software deployment solution using free/libre software](https://reader033.vdocuments.site/reader033/viewer/2022052311/5599241e1a28ab2f5e8b46f0/html5/thumbnails/42.jpg)
Dockerchroot on steroidsdesigned to execute and contain one processuses LXC, cgroups, UnionFS(AUFS)does not need a custom kernel (anymore)runs on many current Linux distributionsyep, it also runs on current RHEL6(.5) and SLES12 oncereleasednot useful in every scenario (no mounts, modules, init and so on)
B1 Systems GmbHCreating a dynamic software deployment
solution using free/libre software 42 / 51
![Page 43: Creating a dynamic software deployment solution using free/libre software](https://reader033.vdocuments.site/reader033/viewer/2022052311/5599241e1a28ab2f5e8b46f0/html5/thumbnails/43.jpg)
VM with no VM overhead
Example: Initialization, Execution, Destruction$ time docker run -t -i smoketest-suse hostnamed20cdb21deb3
real 0m0.230suser 0m0.007ssys 0m0.003s$ time docker run -t -i --rm \
smoketest-suse hostnamee1e1b445465d
real 0m4.250suser 0m0.000ssys 0m0.010s
B1 Systems GmbHCreating a dynamic software deployment
solution using free/libre software 43 / 51
![Page 44: Creating a dynamic software deployment solution using free/libre software](https://reader033.vdocuments.site/reader033/viewer/2022052311/5599241e1a28ab2f5e8b46f0/html5/thumbnails/44.jpg)
Smoketest with Docker
Application of Puppet Manifest: Does it blow up?$ docker run -t -i smoketest-suse \
bash -c "r10k deploy -p; puppet apply \--detailed-exitcodes --modulepath=/test/modules \-e ’include memcached’"
B1 Systems GmbHCreating a dynamic software deployment
solution using free/libre software 44 / 51
![Page 45: Creating a dynamic software deployment solution using free/libre software](https://reader033.vdocuments.site/reader033/viewer/2022052311/5599241e1a28ab2f5e8b46f0/html5/thumbnails/45.jpg)
Serverspecbased on RSpecexecutes tests locally or remotely (ssh)integrates with Vagrant somewhatSupported resources: cgroup, command, cron,default_gateway, file, group, host, iis_app_pool,iis_website, interface, ipfilter, iptables,kernel_module and more
B1 Systems GmbHCreating a dynamic software deployment
solution using free/libre software 45 / 51
![Page 46: Creating a dynamic software deployment solution using free/libre software](https://reader033.vdocuments.site/reader033/viewer/2022052311/5599241e1a28ab2f5e8b46f0/html5/thumbnails/46.jpg)
Serverspec - Example Spec
Simple System/Acceptance Test for memcached (excerpt)describe package(’memcached’) do
it { should be_installed }enddescribe service(’memcached’) do
it { should be_enabled }it { should be_running }
enddescribe port(11211) do
it { should be_listening.with(’tcp’) }it { should be_listening.with(’udp’) }
end
B1 Systems GmbHCreating a dynamic software deployment
solution using free/libre software 46 / 51
![Page 47: Creating a dynamic software deployment solution using free/libre software](https://reader033.vdocuments.site/reader033/viewer/2022052311/5599241e1a28ab2f5e8b46f0/html5/thumbnails/47.jpg)
Serverspec – Example Spec
Simple System/Acceptance Test for memcached (excerpt)describe file(’/etc/sysconfig/memcached’) do
it { should be_readable }its(:content) { should match /PORT="11211"/ }
enddescribe command(’echo -e \
"add Test 0 60 11\r\nHello World\r" | nc localhost 11211’) doit { should return_stdout /^STORED$/ }
enddescribe command(’echo -e "get Test\r" | nc localhost 11211’) do
it { should return_stdout /^Hello World$/ }end
B1 Systems GmbHCreating a dynamic software deployment
solution using free/libre software 47 / 51
![Page 48: Creating a dynamic software deployment solution using free/libre software](https://reader033.vdocuments.site/reader033/viewer/2022052311/5599241e1a28ab2f5e8b46f0/html5/thumbnails/48.jpg)
Serverspec – Example Run
Test Run for memcached, Part 1$ rake spec SPEC_OPTS="-fd"(in /home/b1user/serverspec)/usr/bin/ruby -S rspec spec/default/memcached_spec.rb
Package "memcached"should be installed
Service "memcached"should be enabled (FAILED - 1)should be running
Port "11211"should be listeningshould be listening
B1 Systems GmbHCreating a dynamic software deployment
solution using free/libre software 48 / 51
![Page 49: Creating a dynamic software deployment solution using free/libre software](https://reader033.vdocuments.site/reader033/viewer/2022052311/5599241e1a28ab2f5e8b46f0/html5/thumbnails/49.jpg)
Test Run for memcached, Part 2File "/etc/sysconfig/memcached"
should be readablecontent
should match /PORT="11211"/
Command "echo -e "add Test 0 60 11\r\nHello World\r" | nc localhost 11211"should return stdout /^STORED$/
Command "echo -e "get Test\r" | nc localhost 11211"should return stdout /^Hello World$/
[...]Failures:
1) Service "memcached" should be enabledFailure/Error: it { should be_enabled }
sudo chkconfig --list memcached | grep 3:onexpected Service "memcached" to be enabled
# ./spec/default/memcached_spec.rb:8Finished in 11.36 seconds12 examples, 1 failure[...]
B1 Systems GmbHCreating a dynamic software deployment
solution using free/libre software 49 / 51
![Page 50: Creating a dynamic software deployment solution using free/libre software](https://reader033.vdocuments.site/reader033/viewer/2022052311/5599241e1a28ab2f5e8b46f0/html5/thumbnails/50.jpg)
What’s Next?After successful acceptance test
1 Promotion of packages from Dev to Test/Integration softwarechannel (Spacewalk)
2 Integration Test of packages3 Promotion of packages from Test to Prod4 Canary Testing → does it blow up in Prod?5 Profit
B1 Systems GmbHCreating a dynamic software deployment
solution using free/libre software 50 / 51
![Page 51: Creating a dynamic software deployment solution using free/libre software](https://reader033.vdocuments.site/reader033/viewer/2022052311/5599241e1a28ab2f5e8b46f0/html5/thumbnails/51.jpg)
Thank you for your attention!If you have further questions please contact [email protected] or
call +49 (0)8457 - 931096
B1 Systems GmbH - Linux/Open Source Consulting, Training, Support & Development