https://wiki.alpinelinux.org/w/api.php?action=feedcontributions&user=Macbrody&feedformat=atomAlpine Linux - User contributions [en]2024-03-29T12:01:56ZUser contributionsMediaWiki 1.40.0https://wiki.alpinelinux.org/w/index.php?title=Setting_up_the_build_environment_1.7&diff=1890Setting up the build environment 1.72007-11-18T20:26:36Z<p>Macbrody: /* Step-by-step */ - added 'sudo' for starting ./create-alpine-sdk.sh</p>
<hr />
<div>Quick note on how to set up a build environment.<br />
<br />
In this document the build environment will be created in /opt/alpine/1.7. You can ofcourse place it anywhere you have space.<br />
You will need a few Gigabytes to have enough space for kernel cmpiling and storing all the binary packages and iso image.<br />
<br />
If you already done this part and only want to 'update your build env.' then see bottom of this page.<br />
<br />
== Requirements ==<br />
You need a 2.6 kernel to use the chroot build environment.<br />
<br />
* '''Note:''' Make sure your running kernel supports 16bit UIDs for backward compatibility. uCLibc needs them. Check it with:<br />
<br />
zcat /proc/config.gz | grep CONFIG_UID16<br />
<br />
or if you dont have /proc/config.gz:<br />
<br />
grep CONFIG_UID16 /boot/config-`uname -r`<br />
<br />
You should se something like:<br />
<br />
CONFIG_UID16=y<br />
<br />
== Step-by-step ==<br />
'''Before you go on please read this!'''<br />
1) There is the hard way - do it yourself - if you want that go on with step-by-step<br />
2) The quick/easy way: download a script that will do it for you: [http://dev.alpinelinux.org/~abrodman/create-alpine-sdk.sh]<br />
1) download the script<br />
2) chmod +x create-alpine-sdk.sh<br />
3) sudo ./create-alpine-sdk.sh<br />
-> it will download, unpack and compile everything for you<br />
-> location: /opt/alpine/alpine-sdk<br />
<br />
<br />
All packages are downloaded from http://dev.alpinelinux.org/alpine/v1.7<br />
<br />
* Download latest buildroot package from [http://dev.alpinelinux.org/alpine/v1.7/sdk/] and unpack it in /opt/alpine, using the --preserve-permissions option and create a symblink named 1.7 for the development branch.<br />
<br />
sudo mkdir -p /opt/alpine/alpine-sdk<br />
cd /opt/alpine/alpine-sdk<br />
wget -q -O - http://dev.alpinelinux.org/alpine/v1.7/sdk/alpine-sdk-latest.tar.bz2\<br />
| sudo tar -vjxp<br />
cd ..<br />
sudo ln -s alpine-sdk 1.7<br />
<br />
* Copy your DNS configuration to the build environment and mount proc.<br />
<br />
sudo cp /etc/resolv.conf /opt/alpine/1.7/etc/<br />
sudo mount -t proc proc /opt/alpine/1.7/proc<br />
<br />
* Enter the chroot and change the prompt to reflect your chroot environment<br />
<br />
sudo chroot /opt/alpine/1.7 /bin/bash --login<br />
echo 'PS1="(chroot)$PS1"' >> /etc/profile<br />
<br />
Now we are in the build environment chroot.<br />
<br />
* Download latest portage snapshot [http://mirror.gentoo.se/snapshots/portage-latest.tar.bz2 portage-latest.tar.bz2] from Gentoo and unpack it to /usr<br />
<br />
cd /usr<br />
wget -q -O - http://mirror.gentoo.se/snapshots/portage-latest.tar.bz2 portage-latest.tar.bz2 | tar -vjx<br />
<br />
* Check out the alpine-portage overlay from svn.<br />
<br />
svn co svn://svn.alpinelinux.org/alpine-portage/trunk /usr/alpine-portage<br />
<br />
* Download all the [http://dl.alpinelinux.org/alpine/v1.7/tbz2 tbz2] packages into the var/cache/packages directory. This is probably easiest with rsync.<br />
<br />
rsync -rauv rsync://rsync.alpinelinux.org/alpine/v1.7/tbz2/* /var/cache/packages/<br />
<br />
* Check out the alpine-builder scripts in usr/src/<br />
<br />
svn co svn://svn.alpinelinux.org/alpine-builder/trunk /usr/src/alpine<br />
'''NOTE:''' The trunk is constantly changing. You might want to use a tagged release like ''svn://svn.alpinelinux.org/alpine-builder/tags/release-1.7.7''<br />
<br />
* Configure portage to use the config from alpine-builder.<br />
<br />
rm -r /etc/make.conf /etc/portage<br />
ln -s /usr/src/alpine/sdk/etc/make.conf /etc<br />
ln -s /usr/src/alpine/sdk/etc/portage /etc<br />
<br />
* Update the portage tree (this takes some time first time you do it)<br />
<br />
emerge --sync<br />
<br />
* Build the alpine images (iso, usb, flash, etc.)<br />
<br />
cd /usr/src/alpine<br />
make<br />
<br />
'''Failure compiling ipp2p:''' just manually 'emerge iptables' and issue 'make' again.<br />
<br />
<br />
If you get failures while building kernel drivers then you can workaround that by commenting out the specific in ''/usr/src/alpine/kernel/generic/drivers''.<br />
<br />
<br />
'''NOTE when leaving chroot:''' When leaving your chroot, you should unmount the /proc<br />
exit<br />
sudo umount /opt/alpine/1.7/proc<br />
<br />
== Updating the build env. ==<br />
If you already setup the build env earlier and only want to enter it, update it and maybe create a iso, then this part of the documentation is what you are looking for.<br />
* Mount proc.<br />
<br />
sudo mount -t proc proc /opt/alpine/1.7/proc<br />
<br />
* Enter the chroot and change the prompt to reflect your chroot environment<br />
<br />
sudo chroot /opt/alpine/1.7 /bin/bash --login<br />
<br />
Now we are in the build environment chroot.<br />
<br />
* Update the portage snapshot from Gentoo<br />
emerge --sync<br />
When emerge has done syncing, you could be advised to update the portage. In such case, you just follow instructions.<br />
<br />
One instruction could be "* To update portage, run 'emerge portage'".<br />
emerge portage<br />
<br />
Another case could be that you see "* IMPORTANT: x config files in '/etc' need updating.". In that case run the dispatch-conf tool.<br />
dispatch-conf<br />
In most cases (when using the 'dispatch-conf') you should use the new config (by pressing 'u' in the console).<br />
<br />
* Check out the alpine-portage overlay from svn.<br />
<br />
cd /usr/alpine-portage && svn up<br />
<br />
* Download all the [http://dl.alpinelinux.org/alpine/v1.7/tbz2 tbz2] packages into the var/cache/packages directory. This is probably easiest with rsync.<br />
<br />
rsync -rauv rsync://rsync.alpinelinux.org/alpine/v1.7/tbz2/* /var/cache/packages/<br />
<br />
* Check out the alpine-builder scripts in usr/src/<br />
<br />
cd /usr/src/alpine && svn up<br />
<br />
* Build the alpine images (iso, usb, flash, etc.)<br />
<br />
cd /usr/src/alpine/iso<br />
make iso<br />
<br />
<br />
'''NOTE when leaving chroot:''' When leaving your chroot, you should unmount the /proc<br />
exit<br />
sudo umount /opt/alpine/1.7/proc</div>Macbrodyhttps://wiki.alpinelinux.org/w/index.php?title=ACF_how_to_write&diff=1886ACF how to write2007-11-17T10:18:07Z<p>Macbrody: /* =Step 7 - How To Get It Going? */</p>
<hr />
<div>=How to Write an ACF <span style="color:red"> Under Construction</span> =<br />
<br />
For some examples please see svn<br />
<br />
svn co svn://svn.alpinelinux.org/acf<br />
<br />
*shorewall<br />
*dhcp<br />
<br />
<br />
==From <nil> to a running ACF example application==<br />
<br />
===Step 1 - The Programming Language===<br />
* ACF uses lua as programming language. Have a look at lua.org [http://www.lua.org/] before starting.<br />
<br />
===Step 2 - The Development Environment===<br />
* Setup an ACF Development Environment: [[Getting_started_with_ACF_development]]<br />
<br />
===Step 3 - Create A Development Directory===<br />
Once you entered the ACF Development Environment as described in step 2:<br />
* in your user home create a directory for your application (e.g. mkdir ~/myapp)<br />
* and cd into it (e.g. cd ~/myapp)<br />
<br />
===Step 4 - MVC, How Does It Affect My Coding?===<br />
ACF is an MVC based framework. What does this mean to you? Your application is separated into three layers: Model, View, Controller - each of which has one or more files.<br />
* Model: In Model the 'real work' is done (e.g. modifying config files, starting/stopping services etc.)<br />
* View: This is where you define what your application will look like. You can have one or more files, each presenting a dynamic html page which only as much code as neccessary to format the data you retrieve from Model.<br />
* Controller: The event dispatcher. In controller you place one function per event. If the user calls the respective 'event page' (web), acf will fire an action - the same-named function in controller will be called. This function then retrieves neccessary data from Model and passes it to View to be displayed to the user.<br />
<br />
===Step 5 - The Example Files To Start With===<br />
Now let us have a look at the files we need to place into our application directory:<br />
<br />
* Makefile<br />
* config.mk<br />
* myapp-model.lua<br />
* myapp-myview-html.lsp<br />
* myapp-controller.lua<br />
* myapp.menu<br />
<br />
<br />
'''Makefile:'''<br />
<br />
The Makefile once called does install our acf application so that we can look at it working.<br />
APP_NAME=myapp<br />
PACKAGE=acf-$(APP_NAME)<br />
VERSION=1.0_alpha1<br />
<br />
APP_DIST=myapp-model.lua \<br />
myapp-myview-html.lsp \<br />
myapp-controller.lua \<br />
myapp.menu<br />
<br />
EXTRA_DIST=README Makefile config.mk<br />
<br />
DISTFILES=$(APP_DIST) $(EXTRA_DIST)<br />
<br />
TAR=tar<br />
<br />
P=$(PACKAGE)-$(VERSION)<br />
tarball=$(P).tar.bz2<br />
install_dir=$(DESTDIR)/$(appdir)/$(APP_NAME)<br />
<br />
all:<br />
clean:<br />
rm -rf $(tarball) $(P)<br />
<br />
dist: $(tarball)<br />
<br />
install:<br />
mkdir -p "$(install_dir)"<br />
cp -a $(APP_DIST) "$(install_dir)"<br />
<br />
$(tarball): $(DISTFILES)<br />
rm -rf $(P)<br />
mkdir -p $(P)<br />
cp $(DISTFILES) $(P)<br />
$(TAR) -jcf $@ $(P)<br />
rm -rf $(P)<br />
<br />
# target that creates a tar package, unpacks is and install from package<br />
dist-install: $(tarball)<br />
$(TAR) -jxf $(tarball)<br />
$(MAKE) -C $(P) install DESTDIR=$(DESTDIR)<br />
rm -rf $(P)<br />
<br />
include config.mk<br />
<br />
.PHONY: all clean dist install dist-install<br />
<br />
Remark: Should you create additional view files for example, don't forget to place their names in Makefile under APP_DIST otherwise they will not be installed later on and your application will fail with an error message.<br />
<br />
<br />
'''config.mk:'''<br />
For use with the Makefile. Just copy/paste it. We will look at it later.<br />
prefix=/usr<br />
datadir=${prefix}/share<br />
sysconfdir=${prefix}/etc<br />
localstatedir=${prefix}/var<br />
acfdir=${datadir}/acf<br />
wwwdir=${acfdir}/www<br />
cgibindir=${acfdir}/cgi-bin<br />
appdir=${acfdir}/app<br />
acflibdir=${acfdir}/lib<br />
sessionsdir=${localstatedir}/lib/acf/sessions<br />
<br />
<br />
'''myapp-model.lsp:'''<br />
-- acf model for myapp<br />
-- Copyright(c) 2007 <Your name here> - Licensed under terms of GPL2<br />
module (..., package.seeall)<br />
<br />
cfgfile = "/tmp/myfile"<br />
<br />
-- This function returns a cfe (table of values) containing the files'<br />
-- value as string and an error code. If the file does not exist, we'll<br />
-- simply return "" (an empty string, but NOT nil)<br />
readfile = function()<br />
retval = ""<br />
error = 0<br />
fileptr = io.open( cfgfile, "r" )<br />
if fileptr ~= nil then<br />
retval = fileptr:read( "*a" )<br />
if retval == nil then<br />
retval = ""<br />
end<br />
fileptr:close()<br />
end<br />
return error, cfe({ msg = retval })<br />
end<br />
<br />
-- This function will write new contents into our file<br />
writefile = function( newcontents )<br />
fileptr = io.open( cfgfile, "w+" )<br />
if fileptr ~= nil then<br />
fileptr:write( newcontents )<br />
fileptr:close()<br />
end<br />
return<br />
end<br />
<br />
<br />
'''myapp-myview-html.lsp:'''<br />
<?<br />
form = ...<br />
option = form.option<br />
?><br />
&lt;h1>MyApp - MyView&lt;/h1><br />
<form action="" method="POST"><br />
<textarea name="textdata"><? io.write( form.value.msg ); ?></textarea><br />
<input type="submit" name="cmd" value="update"><br />
</form><br />
<br />
<br />
'''myapp-controller.lua:'''<br />
-- the myapp controller<br />
module (..., package.seeall) <br />
<br />
--- default code up here<br />
--- do not change anything except: self.conf.action for redirect<br />
local list_redir = function( self )<br />
self.conf.action = "myview"<br />
self.conf.type = "redir"<br />
error (self.conf)<br />
end<br />
<br />
local pvt = {}<br />
mvc= {}<br />
mvc.on_load = function( self, parent )<br />
if ( rawget(self.worker, self.conf.action) == nil ) then<br />
list_redir(self)<br />
end<br />
pvt.parent_on_exec = parent.worker.mvc.post_exec<br />
end<br />
<br />
-- This is where 'our' code starts<br />
<br />
myview = function( self )<br />
-- self.clientdata contains the data from the html form<br />
-- in your myapp-myview-html.lsp<br />
local clidat = self.clientdata <br />
<br />
-- user did submit the form (not just call the page)<br />
if clidat.cmd then<br />
if clidat.cmd == "update" then -- user pressed update button<br />
self.model.writefile( clidat.textdata )<br />
end<br />
end<br />
error, value = self.model.readfile()<br />
return cfe({ value = value })<br />
end<br />
<br />
<br />
'''myapp.menu:'''<br />
# Cat Group Tab Action<br />
Test MyApp MyView MyView<br />
<br />
===Step 6 - What Does It Do?===<br />
This program only just displays a &lt;textarea> box and a submit "update" button. The user can enter text which is saved into a file once he presses "update".<br />
<br />
====In Depth====<br />
Now let us have a closer look at the different files' contents:<br />
<br />
=====myapp.menu=====<br />
In this file you define:<br />
* '''The Category''' in which a menu entry for your program will appear<br />
* '''The Group''', resp. the subheading's name under Category<br />
* '''The Action''' with-in your controller that will be called once the user klicks on the menu entry defined by Category and Group.<br />
<br />
=====myapp-controller.lua=====<br />
The controller is an event dispatcher. So in here you define all the actions that the user can call or that are defined in the menu. Each action is a separate function that will receive ''self'' as the only parameter.<br />
<br />
In our case the action is ''myview''.<br />
<br />
For every action you define here, so can define a separate view file using the nameage: myapp-''action''-html.lsp<br />
<br />
This function can call the ''model's'' functions to update and/or retrieve<br />
data (e.g. self.model.readfile()).<br />
<br />
Anything that this function returns will be passed on to the ''view''<br />
<br />
=====myapp-model.lua=====<br />
The functions defined in here can be accessed by the controller<br />
to update/set/retrieve data, start/stop services, basically do<br />
any 'real work'.<br />
<br />
=====myapp-myview-html.lsp=====<br />
This is our ''view''. It receives the data to be displayed via ''controller''. What ever is returned by a controller action (function) can be accessed by the view ''(see the first three lines .. &lt;? .. ?&gt;)''.<br />
<br />
====How to exchange data between model-view-controller?====<br />
To exchange data between model, view and controller ACF uses the so called<br />
''Configuration Framework Entities (CFE)''.<br />
<br />
Please see [[ACF_core_principles]] for further details on CFEs.<br />
<br />
===Step 7 - How To Get It Going?===<br />
Once you have completed all the above mentioned steps, go on with:<br />
* sudo make install (this will install your app with the http server)<br />
* point your browser to http://ip-of-your-dev-host/</div>Macbrodyhttps://wiki.alpinelinux.org/w/index.php?title=ACF_how_to_write&diff=1885ACF how to write2007-11-17T10:16:40Z<p>Macbrody: /* From <nil> to a running ACF example application */</p>
<hr />
<div>=How to Write an ACF <span style="color:red"> Under Construction</span> =<br />
<br />
For some examples please see svn<br />
<br />
svn co svn://svn.alpinelinux.org/acf<br />
<br />
*shorewall<br />
*dhcp<br />
<br />
<br />
==From <nil> to a running ACF example application==<br />
<br />
===Step 1 - The Programming Language===<br />
* ACF uses lua as programming language. Have a look at lua.org [http://www.lua.org/] before starting.<br />
<br />
===Step 2 - The Development Environment===<br />
* Setup an ACF Development Environment: [[Getting_started_with_ACF_development]]<br />
<br />
===Step 3 - Create A Development Directory===<br />
Once you entered the ACF Development Environment as described in step 2:<br />
* in your user home create a directory for your application (e.g. mkdir ~/myapp)<br />
* and cd into it (e.g. cd ~/myapp)<br />
<br />
===Step 4 - MVC, How Does It Affect My Coding?===<br />
ACF is an MVC based framework. What does this mean to you? Your application is separated into three layers: Model, View, Controller - each of which has one or more files.<br />
* Model: In Model the 'real work' is done (e.g. modifying config files, starting/stopping services etc.)<br />
* View: This is where you define what your application will look like. You can have one or more files, each presenting a dynamic html page which only as much code as neccessary to format the data you retrieve from Model.<br />
* Controller: The event dispatcher. In controller you place one function per event. If the user calls the respective 'event page' (web), acf will fire an action - the same-named function in controller will be called. This function then retrieves neccessary data from Model and passes it to View to be displayed to the user.<br />
<br />
===Step 5 - The Example Files To Start With===<br />
Now let us have a look at the files we need to place into our application directory:<br />
<br />
* Makefile<br />
* config.mk<br />
* myapp-model.lua<br />
* myapp-myview-html.lsp<br />
* myapp-controller.lua<br />
* myapp.menu<br />
<br />
<br />
'''Makefile:'''<br />
<br />
The Makefile once called does install our acf application so that we can look at it working.<br />
APP_NAME=myapp<br />
PACKAGE=acf-$(APP_NAME)<br />
VERSION=1.0_alpha1<br />
<br />
APP_DIST=myapp-model.lua \<br />
myapp-myview-html.lsp \<br />
myapp-controller.lua \<br />
myapp.menu<br />
<br />
EXTRA_DIST=README Makefile config.mk<br />
<br />
DISTFILES=$(APP_DIST) $(EXTRA_DIST)<br />
<br />
TAR=tar<br />
<br />
P=$(PACKAGE)-$(VERSION)<br />
tarball=$(P).tar.bz2<br />
install_dir=$(DESTDIR)/$(appdir)/$(APP_NAME)<br />
<br />
all:<br />
clean:<br />
rm -rf $(tarball) $(P)<br />
<br />
dist: $(tarball)<br />
<br />
install:<br />
mkdir -p "$(install_dir)"<br />
cp -a $(APP_DIST) "$(install_dir)"<br />
<br />
$(tarball): $(DISTFILES)<br />
rm -rf $(P)<br />
mkdir -p $(P)<br />
cp $(DISTFILES) $(P)<br />
$(TAR) -jcf $@ $(P)<br />
rm -rf $(P)<br />
<br />
# target that creates a tar package, unpacks is and install from package<br />
dist-install: $(tarball)<br />
$(TAR) -jxf $(tarball)<br />
$(MAKE) -C $(P) install DESTDIR=$(DESTDIR)<br />
rm -rf $(P)<br />
<br />
include config.mk<br />
<br />
.PHONY: all clean dist install dist-install<br />
<br />
Remark: Should you create additional view files for example, don't forget to place their names in Makefile under APP_DIST otherwise they will not be installed later on and your application will fail with an error message.<br />
<br />
<br />
'''config.mk:'''<br />
For use with the Makefile. Just copy/paste it. We will look at it later.<br />
prefix=/usr<br />
datadir=${prefix}/share<br />
sysconfdir=${prefix}/etc<br />
localstatedir=${prefix}/var<br />
acfdir=${datadir}/acf<br />
wwwdir=${acfdir}/www<br />
cgibindir=${acfdir}/cgi-bin<br />
appdir=${acfdir}/app<br />
acflibdir=${acfdir}/lib<br />
sessionsdir=${localstatedir}/lib/acf/sessions<br />
<br />
<br />
'''myapp-model.lsp:'''<br />
-- acf model for myapp<br />
-- Copyright(c) 2007 <Your name here> - Licensed under terms of GPL2<br />
module (..., package.seeall)<br />
<br />
cfgfile = "/tmp/myfile"<br />
<br />
-- This function returns a cfe (table of values) containing the files'<br />
-- value as string and an error code. If the file does not exist, we'll<br />
-- simply return "" (an empty string, but NOT nil)<br />
readfile = function()<br />
retval = ""<br />
error = 0<br />
fileptr = io.open( cfgfile, "r" )<br />
if fileptr ~= nil then<br />
retval = fileptr:read( "*a" )<br />
if retval == nil then<br />
retval = ""<br />
end<br />
fileptr:close()<br />
end<br />
return error, cfe({ msg = retval })<br />
end<br />
<br />
-- This function will write new contents into our file<br />
writefile = function( newcontents )<br />
fileptr = io.open( cfgfile, "w+" )<br />
if fileptr ~= nil then<br />
fileptr:write( newcontents )<br />
fileptr:close()<br />
end<br />
return<br />
end<br />
<br />
<br />
'''myapp-myview-html.lsp:'''<br />
<?<br />
form = ...<br />
option = form.option<br />
?><br />
&lt;h1>MyApp - MyView&lt;/h1><br />
<form action="" method="POST"><br />
<textarea name="textdata"><? io.write( form.value.msg ); ?></textarea><br />
<input type="submit" name="cmd" value="update"><br />
</form><br />
<br />
<br />
'''myapp-controller.lua:'''<br />
-- the myapp controller<br />
module (..., package.seeall) <br />
<br />
--- default code up here<br />
--- do not change anything except: self.conf.action for redirect<br />
local list_redir = function( self )<br />
self.conf.action = "myview"<br />
self.conf.type = "redir"<br />
error (self.conf)<br />
end<br />
<br />
local pvt = {}<br />
mvc= {}<br />
mvc.on_load = function( self, parent )<br />
if ( rawget(self.worker, self.conf.action) == nil ) then<br />
list_redir(self)<br />
end<br />
pvt.parent_on_exec = parent.worker.mvc.post_exec<br />
end<br />
<br />
-- This is where 'our' code starts<br />
<br />
myview = function( self )<br />
-- self.clientdata contains the data from the html form<br />
-- in your myapp-myview-html.lsp<br />
local clidat = self.clientdata <br />
<br />
-- user did submit the form (not just call the page)<br />
if clidat.cmd then<br />
if clidat.cmd == "update" then -- user pressed update button<br />
self.model.writefile( clidat.textdata )<br />
end<br />
end<br />
error, value = self.model.readfile()<br />
return cfe({ value = value })<br />
end<br />
<br />
<br />
'''myapp.menu:'''<br />
# Cat Group Tab Action<br />
Test MyApp MyView MyView<br />
<br />
===Step 6 - What Does It Do?===<br />
This program only just displays a &lt;textarea> box and a submit "update" button. The user can enter text which is saved into a file once he presses "update".<br />
<br />
====In Depth====<br />
Now let us have a closer look at the different files' contents:<br />
<br />
=====myapp.menu=====<br />
In this file you define:<br />
* '''The Category''' in which a menu entry for your program will appear<br />
* '''The Group''', resp. the subheading's name under Category<br />
* '''The Action''' with-in your controller that will be called once the user klicks on the menu entry defined by Category and Group.<br />
<br />
=====myapp-controller.lua=====<br />
The controller is an event dispatcher. So in here you define all the actions that the user can call or that are defined in the menu. Each action is a separate function that will receive ''self'' as the only parameter.<br />
<br />
In our case the action is ''myview''.<br />
<br />
For every action you define here, so can define a separate view file using the nameage: myapp-''action''-html.lsp<br />
<br />
This function can call the ''model's'' functions to update and/or retrieve<br />
data (e.g. self.model.readfile()).<br />
<br />
Anything that this function returns will be passed on to the ''view''<br />
<br />
=====myapp-model.lua=====<br />
The functions defined in here can be accessed by the controller<br />
to update/set/retrieve data, start/stop services, basically do<br />
any 'real work'.<br />
<br />
=====myapp-myview-html.lsp=====<br />
This is our ''view''. It receives the data to be displayed via ''controller''. What ever is returned by a controller action (function) can be accessed by the view ''(see the first three lines .. &lt;? .. ?&gt;)''.<br />
<br />
====How to exchange data between model-view-controller?====<br />
To exchange data between model, view and controller ACF uses the so called<br />
''Configuration Framework Entities (CFE)''.<br />
<br />
Please see [[ACF_core_principles]] for further details on CFEs.<br />
<br />
===Step 7 - How To Get It Going?==<br />
Once you have completed all the above mentioned steps, go on with:<br />
* sudo make install (this will install your app with the http server)<br />
* point your browser to http://ip-of-your-dev-host/</div>Macbrodyhttps://wiki.alpinelinux.org/w/index.php?title=ACF_how_to_write&diff=1884ACF how to write2007-11-17T09:54:25Z<p>Macbrody: /* From <nil> to a running ACF example application <span style="color:red">Under Construction</span> */</p>
<hr />
<div>=How to Write an ACF <span style="color:red"> Under Construction</span> =<br />
<br />
For some examples please see svn<br />
<br />
svn co svn://svn.alpinelinux.org/acf<br />
<br />
*shorewall<br />
*dhcp<br />
<br />
<br />
==From <nil> to a running ACF example application==<br />
<br />
===Step 1 - The Programming Language===<br />
* ACF uses lua as programming language. Have a look at lua.org [http://www.lua.org/] before starting.<br />
<br />
===Step 2 - The Development Environment===<br />
* Setup an ACF Development Environment: [[Getting_started_with_ACF_development]]<br />
<br />
===Step 3 - Create A Development Directory===<br />
Once you entered the ACF Development Environment as described in step 2:<br />
* in your user home create a directory for your application (e.g. mkdir ~/myapp)<br />
* and cd into it (e.g. cd ~/myapp)<br />
<br />
===Step 4 - MVC, How Does It Affect My Coding?===<br />
ACF is an MVC based framework. What does this mean to you? Your application is separated into three layers: Model, View, Controller - each of which has one or more files.<br />
* Model: In Model the 'real work' is done (e.g. modifying config files, starting/stopping services etc.)<br />
* View: This is where you define what your application will look like. You can have one or more files, each presenting a dynamic html page which only as much code as neccessary to format the data you retrieve from Model.<br />
* Controller: The event dispatcher. In controller you place one function per event. If the user calls the respective 'event page' (web), acf will fire an action - the same-named function in controller will be called. This function then retrieves neccessary data from Model and passes it to View to be displayed to the user.<br />
<br />
===Step 5 - The Example Files To Start With===<br />
Now let us have a look at the files we need to place into our application directory:<br />
<br />
* Makefile<br />
* config.mk<br />
* myapp-model.lua<br />
* myapp-myview-html.lsp<br />
* myapp-controller.lua<br />
* myapp.menu<br />
<br />
<br />
'''Makefile:'''<br />
<br />
The Makefile once called does install our acf application so that we can look at it working.<br />
APP_NAME=myapp<br />
PACKAGE=acf-$(APP_NAME)<br />
VERSION=1.0_alpha1<br />
<br />
APP_DIST=myapp-model.lua \<br />
myapp-myview-html.lsp \<br />
myapp-controller.lua \<br />
myapp.menu<br />
<br />
EXTRA_DIST=README Makefile config.mk<br />
<br />
DISTFILES=$(APP_DIST) $(EXTRA_DIST)<br />
<br />
TAR=tar<br />
<br />
P=$(PACKAGE)-$(VERSION)<br />
tarball=$(P).tar.bz2<br />
install_dir=$(DESTDIR)/$(appdir)/$(APP_NAME)<br />
<br />
all:<br />
clean:<br />
rm -rf $(tarball) $(P)<br />
<br />
dist: $(tarball)<br />
<br />
install:<br />
mkdir -p "$(install_dir)"<br />
cp -a $(APP_DIST) "$(install_dir)"<br />
<br />
$(tarball): $(DISTFILES)<br />
rm -rf $(P)<br />
mkdir -p $(P)<br />
cp $(DISTFILES) $(P)<br />
$(TAR) -jcf $@ $(P)<br />
rm -rf $(P)<br />
<br />
# target that creates a tar package, unpacks is and install from package<br />
dist-install: $(tarball)<br />
$(TAR) -jxf $(tarball)<br />
$(MAKE) -C $(P) install DESTDIR=$(DESTDIR)<br />
rm -rf $(P)<br />
<br />
include config.mk<br />
<br />
.PHONY: all clean dist install dist-install<br />
<br />
Remark: Should you create additional view files for example, don't forget to place their names in Makefile under APP_DIST otherwise they will not be installed later on and your application will fail with an error message.<br />
<br />
<br />
'''config.mk:'''<br />
For use with the Makefile. Just copy/paste it. We will look at it later.<br />
prefix=/usr<br />
datadir=${prefix}/share<br />
sysconfdir=${prefix}/etc<br />
localstatedir=${prefix}/var<br />
acfdir=${datadir}/acf<br />
wwwdir=${acfdir}/www<br />
cgibindir=${acfdir}/cgi-bin<br />
appdir=${acfdir}/app<br />
acflibdir=${acfdir}/lib<br />
sessionsdir=${localstatedir}/lib/acf/sessions<br />
<br />
<br />
'''myapp-model.lsp:'''<br />
-- acf model for myapp<br />
-- Copyright(c) 2007 <Your name here> - Licensed under terms of GPL2<br />
module (..., package.seeall)<br />
<br />
cfgfile = "/tmp/myfile"<br />
<br />
-- This function returns a cfe (table of values) containing the files'<br />
-- value as string and an error code. If the file does not exist, we'll<br />
-- simply return "" (an empty string, but NOT nil)<br />
readfile = function()<br />
retval = ""<br />
error = 0<br />
fileptr = io.open( cfgfile, "r" )<br />
if fileptr ~= nil then<br />
retval = fileptr:read( "*a" )<br />
if retval == nil then<br />
retval = ""<br />
end<br />
fileptr:close()<br />
end<br />
return error, cfe({ msg = retval })<br />
end<br />
<br />
-- This function will write new contents into our file<br />
writefile = function( newcontents )<br />
fileptr = io.open( cfgfile, "w+" )<br />
if fileptr ~= nil then<br />
fileptr:write( newcontents )<br />
fileptr:close()<br />
end<br />
return<br />
end<br />
<br />
<br />
'''myapp-myview-html.lsp:'''<br />
<?<br />
form = ...<br />
option = form.option<br />
?><br />
&lt;h1>MyApp - MyView&lt;/h1><br />
<form action="" method="POST"><br />
<textarea name="textdata"><? io.write( form.value.msg ); ?></textarea><br />
<input type="submit" name="cmd" value="update"><br />
</form><br />
<br />
<br />
'''myapp-controller.lua:'''<br />
-- the myapp controller<br />
module (..., package.seeall) <br />
<br />
--- default code up here<br />
--- do not change anything except: self.conf.action for redirect<br />
local list_redir = function( self )<br />
self.conf.action = "myview"<br />
self.conf.type = "redir"<br />
error (self.conf)<br />
end<br />
<br />
local pvt = {}<br />
mvc= {}<br />
mvc.on_load = function( self, parent )<br />
if ( rawget(self.worker, self.conf.action) == nil ) then<br />
list_redir(self)<br />
end<br />
pvt.parent_on_exec = parent.worker.mvc.post_exec<br />
end<br />
<br />
-- This is where 'our' code starts<br />
<br />
myview = function( self )<br />
-- self.clientdata contains the data from the html form<br />
-- in your myapp-myview-html.lsp<br />
local clidat = self.clientdata <br />
<br />
-- user did submit the form (not just call the page)<br />
if clidat.cmd then<br />
if clidat.cmd == "update" then -- user pressed update button<br />
self.model.writefile( clidat.textdata )<br />
end<br />
end<br />
error, value = self.model.readfile()<br />
return cfe({ value = value })<br />
end<br />
<br />
<br />
'''myapp.menu:'''<br />
# Cat Group Tab Action<br />
Test MyApp MyView MyView<br />
<br />
===Step 6 - What Does It Do?===<br />
This program only just displays a &lt;textarea> box and a submit "update" button. The user can enter text which is saved into a file once he presses "update".<br />
<br />
====In Depth====<br />
Now let us have a closer look at the different files' contents:<br />
<br />
=====myapp.menu=====<br />
In this file you define:<br />
* '''The Category''' in which a menu entry for your program will appear<br />
* '''The Group''', resp. the subheading's name under Category<br />
* '''The Action''' with-in your controller that will be called once the user klicks on the menu entry defined by Category and Group.<br />
<br />
=====myapp-controller.lua=====<br />
The controller is an event dispatcher. So in here you define all the actions that the user can call or that are defined in the menu. Each action is a separate function that will receive ''self'' as the only parameter.<br />
<br />
In our case the action is ''myview''.<br />
<br />
For every action you define here, so can define a separate view file using the nameage: myapp-''action''-html.lsp<br />
<br />
This function can call the ''model's'' functions to update and/or retrieve<br />
data (e.g. self.model.readfile()).<br />
<br />
Anything that this function returns will be passed on to the ''view''<br />
<br />
=====myapp-model.lua=====<br />
The functions defined in here can be accessed by the controller<br />
to update/set/retrieve data, start/stop services, basically do<br />
any 'real work'.<br />
<br />
=====myapp-myview-html.lsp=====<br />
This is our ''view''. It receives the data to be displayed via ''controller''. What ever is returned by a controller action (function) can be accessed by the view ''(see the first three lines .. &lt;? .. ?&gt;)''.<br />
<br />
====How to exchange data between model-view-controller?====<br />
To exchange data between model, view and controller ACF uses the so called<br />
''Configuration Framework Entities (CFE)''.<br />
<br />
Please see [[ACF_core_principles]] for further details on CFEs.</div>Macbrodyhttps://wiki.alpinelinux.org/w/index.php?title=ACF_how_to_write&diff=1883ACF how to write2007-11-17T09:53:21Z<p>Macbrody: /* myapp-controller.lua */</p>
<hr />
<div>=How to Write an ACF <span style="color:red"> Under Construction</span> =<br />
<br />
For some examples please see svn<br />
<br />
svn co svn://svn.alpinelinux.org/acf<br />
<br />
*shorewall<br />
*dhcp<br />
<br />
<br />
==From <nil> to a running ACF example application <span style="color:red">Under Construction</span>==<br />
<br />
===Step 1 - The Programming Language===<br />
* ACF uses lua as programming language. Have a look at lua.org [http://www.lua.org/] before starting.<br />
<br />
===Step 2 - The Development Environment===<br />
* Setup an ACF Development Environment: [[Getting_started_with_ACF_development]]<br />
<br />
===Step 3 - Create A Development Directory===<br />
Once you entered the ACF Development Environment as described in step 2:<br />
* in your user home create a directory for your application (e.g. mkdir ~/myapp)<br />
* and cd into it (e.g. cd ~/myapp)<br />
<br />
===Step 4 - MVC, How Does It Affect My Coding?===<br />
ACF is an MVC based framework. What does this mean to you? Your application is separated into three layers: Model, View, Controller - each of which has one or more files.<br />
* Model: In Model the 'real work' is done (e.g. modifying config files, starting/stopping services etc.)<br />
* View: This is where you define what your application will look like. You can have one or more files, each presenting a dynamic html page which only as much code as neccessary to format the data you retrieve from Model.<br />
* Controller: The event dispatcher. In controller you place one function per event. If the user calls the respective 'event page' (web), acf will fire an action - the same-named function in controller will be called. This function then retrieves neccessary data from Model and passes it to View to be displayed to the user.<br />
<br />
===Step 5 - The Example Files To Start With===<br />
Now let us have a look at the files we need to place into our application directory:<br />
<br />
* Makefile<br />
* config.mk<br />
* myapp-model.lua<br />
* myapp-myview-html.lsp<br />
* myapp-controller.lua<br />
* myapp.menu<br />
<br />
<br />
'''Makefile:'''<br />
<br />
The Makefile once called does install our acf application so that we can look at it working.<br />
APP_NAME=myapp<br />
PACKAGE=acf-$(APP_NAME)<br />
VERSION=1.0_alpha1<br />
<br />
APP_DIST=myapp-model.lua \<br />
myapp-myview-html.lsp \<br />
myapp-controller.lua \<br />
myapp.menu<br />
<br />
EXTRA_DIST=README Makefile config.mk<br />
<br />
DISTFILES=$(APP_DIST) $(EXTRA_DIST)<br />
<br />
TAR=tar<br />
<br />
P=$(PACKAGE)-$(VERSION)<br />
tarball=$(P).tar.bz2<br />
install_dir=$(DESTDIR)/$(appdir)/$(APP_NAME)<br />
<br />
all:<br />
clean:<br />
rm -rf $(tarball) $(P)<br />
<br />
dist: $(tarball)<br />
<br />
install:<br />
mkdir -p "$(install_dir)"<br />
cp -a $(APP_DIST) "$(install_dir)"<br />
<br />
$(tarball): $(DISTFILES)<br />
rm -rf $(P)<br />
mkdir -p $(P)<br />
cp $(DISTFILES) $(P)<br />
$(TAR) -jcf $@ $(P)<br />
rm -rf $(P)<br />
<br />
# target that creates a tar package, unpacks is and install from package<br />
dist-install: $(tarball)<br />
$(TAR) -jxf $(tarball)<br />
$(MAKE) -C $(P) install DESTDIR=$(DESTDIR)<br />
rm -rf $(P)<br />
<br />
include config.mk<br />
<br />
.PHONY: all clean dist install dist-install<br />
<br />
Remark: Should you create additional view files for example, don't forget to place their names in Makefile under APP_DIST otherwise they will not be installed later on and your application will fail with an error message.<br />
<br />
<br />
'''config.mk:'''<br />
For use with the Makefile. Just copy/paste it. We will look at it later.<br />
prefix=/usr<br />
datadir=${prefix}/share<br />
sysconfdir=${prefix}/etc<br />
localstatedir=${prefix}/var<br />
acfdir=${datadir}/acf<br />
wwwdir=${acfdir}/www<br />
cgibindir=${acfdir}/cgi-bin<br />
appdir=${acfdir}/app<br />
acflibdir=${acfdir}/lib<br />
sessionsdir=${localstatedir}/lib/acf/sessions<br />
<br />
<br />
'''myapp-model.lsp:'''<br />
-- acf model for myapp<br />
-- Copyright(c) 2007 <Your name here> - Licensed under terms of GPL2<br />
module (..., package.seeall)<br />
<br />
cfgfile = "/tmp/myfile"<br />
<br />
-- This function returns a cfe (table of values) containing the files'<br />
-- value as string and an error code. If the file does not exist, we'll<br />
-- simply return "" (an empty string, but NOT nil)<br />
readfile = function()<br />
retval = ""<br />
error = 0<br />
fileptr = io.open( cfgfile, "r" )<br />
if fileptr ~= nil then<br />
retval = fileptr:read( "*a" )<br />
if retval == nil then<br />
retval = ""<br />
end<br />
fileptr:close()<br />
end<br />
return error, cfe({ msg = retval })<br />
end<br />
<br />
-- This function will write new contents into our file<br />
writefile = function( newcontents )<br />
fileptr = io.open( cfgfile, "w+" )<br />
if fileptr ~= nil then<br />
fileptr:write( newcontents )<br />
fileptr:close()<br />
end<br />
return<br />
end<br />
<br />
<br />
'''myapp-myview-html.lsp:'''<br />
<?<br />
form = ...<br />
option = form.option<br />
?><br />
&lt;h1>MyApp - MyView&lt;/h1><br />
<form action="" method="POST"><br />
<textarea name="textdata"><? io.write( form.value.msg ); ?></textarea><br />
<input type="submit" name="cmd" value="update"><br />
</form><br />
<br />
<br />
'''myapp-controller.lua:'''<br />
-- the myapp controller<br />
module (..., package.seeall) <br />
<br />
--- default code up here<br />
--- do not change anything except: self.conf.action for redirect<br />
local list_redir = function( self )<br />
self.conf.action = "myview"<br />
self.conf.type = "redir"<br />
error (self.conf)<br />
end<br />
<br />
local pvt = {}<br />
mvc= {}<br />
mvc.on_load = function( self, parent )<br />
if ( rawget(self.worker, self.conf.action) == nil ) then<br />
list_redir(self)<br />
end<br />
pvt.parent_on_exec = parent.worker.mvc.post_exec<br />
end<br />
<br />
-- This is where 'our' code starts<br />
<br />
myview = function( self )<br />
-- self.clientdata contains the data from the html form<br />
-- in your myapp-myview-html.lsp<br />
local clidat = self.clientdata <br />
<br />
-- user did submit the form (not just call the page)<br />
if clidat.cmd then<br />
if clidat.cmd == "update" then -- user pressed update button<br />
self.model.writefile( clidat.textdata )<br />
end<br />
end<br />
error, value = self.model.readfile()<br />
return cfe({ value = value })<br />
end<br />
<br />
<br />
'''myapp.menu:'''<br />
# Cat Group Tab Action<br />
Test MyApp MyView MyView<br />
<br />
===Step 6 - What Does It Do?===<br />
This program only just displays a &lt;textarea> box and a submit "update" button. The user can enter text which is saved into a file once he presses "update".<br />
<br />
====In Depth====<br />
Now let us have a closer look at the different files' contents:<br />
<br />
=====myapp.menu=====<br />
In this file you define:<br />
* '''The Category''' in which a menu entry for your program will appear<br />
* '''The Group''', resp. the subheading's name under Category<br />
* '''The Action''' with-in your controller that will be called once the user klicks on the menu entry defined by Category and Group.<br />
<br />
=====myapp-controller.lua=====<br />
The controller is an event dispatcher. So in here you define all the actions that the user can call or that are defined in the menu. Each action is a separate function that will receive ''self'' as the only parameter.<br />
<br />
In our case the action is ''myview''.<br />
<br />
For every action you define here, so can define a separate view file using the nameage: myapp-''action''-html.lsp<br />
<br />
This function can call the ''model's'' functions to update and/or retrieve<br />
data (e.g. self.model.readfile()).<br />
<br />
Anything that this function returns will be passed on to the ''view''<br />
<br />
=====myapp-model.lua=====<br />
The functions defined in here can be accessed by the controller<br />
to update/set/retrieve data, start/stop services, basically do<br />
any 'real work'.<br />
<br />
=====myapp-myview-html.lsp=====<br />
This is our ''view''. It receives the data to be displayed via ''controller''. What ever is returned by a controller action (function) can be accessed by the view ''(see the first three lines .. &lt;? .. ?&gt;)''.<br />
<br />
====How to exchange data between model-view-controller?====<br />
To exchange data between model, view and controller ACF uses the so called<br />
''Configuration Framework Entities (CFE)''.<br />
<br />
Please see [[ACF_core_principles]] for further details on CFEs.</div>Macbrodyhttps://wiki.alpinelinux.org/w/index.php?title=ACF_how_to_write&diff=1882ACF how to write2007-11-17T09:51:29Z<p>Macbrody: /* In Depth */</p>
<hr />
<div>=How to Write an ACF <span style="color:red"> Under Construction</span> =<br />
<br />
For some examples please see svn<br />
<br />
svn co svn://svn.alpinelinux.org/acf<br />
<br />
*shorewall<br />
*dhcp<br />
<br />
<br />
==From <nil> to a running ACF example application <span style="color:red">Under Construction</span>==<br />
<br />
===Step 1 - The Programming Language===<br />
* ACF uses lua as programming language. Have a look at lua.org [http://www.lua.org/] before starting.<br />
<br />
===Step 2 - The Development Environment===<br />
* Setup an ACF Development Environment: [[Getting_started_with_ACF_development]]<br />
<br />
===Step 3 - Create A Development Directory===<br />
Once you entered the ACF Development Environment as described in step 2:<br />
* in your user home create a directory for your application (e.g. mkdir ~/myapp)<br />
* and cd into it (e.g. cd ~/myapp)<br />
<br />
===Step 4 - MVC, How Does It Affect My Coding?===<br />
ACF is an MVC based framework. What does this mean to you? Your application is separated into three layers: Model, View, Controller - each of which has one or more files.<br />
* Model: In Model the 'real work' is done (e.g. modifying config files, starting/stopping services etc.)<br />
* View: This is where you define what your application will look like. You can have one or more files, each presenting a dynamic html page which only as much code as neccessary to format the data you retrieve from Model.<br />
* Controller: The event dispatcher. In controller you place one function per event. If the user calls the respective 'event page' (web), acf will fire an action - the same-named function in controller will be called. This function then retrieves neccessary data from Model and passes it to View to be displayed to the user.<br />
<br />
===Step 5 - The Example Files To Start With===<br />
Now let us have a look at the files we need to place into our application directory:<br />
<br />
* Makefile<br />
* config.mk<br />
* myapp-model.lua<br />
* myapp-myview-html.lsp<br />
* myapp-controller.lua<br />
* myapp.menu<br />
<br />
<br />
'''Makefile:'''<br />
<br />
The Makefile once called does install our acf application so that we can look at it working.<br />
APP_NAME=myapp<br />
PACKAGE=acf-$(APP_NAME)<br />
VERSION=1.0_alpha1<br />
<br />
APP_DIST=myapp-model.lua \<br />
myapp-myview-html.lsp \<br />
myapp-controller.lua \<br />
myapp.menu<br />
<br />
EXTRA_DIST=README Makefile config.mk<br />
<br />
DISTFILES=$(APP_DIST) $(EXTRA_DIST)<br />
<br />
TAR=tar<br />
<br />
P=$(PACKAGE)-$(VERSION)<br />
tarball=$(P).tar.bz2<br />
install_dir=$(DESTDIR)/$(appdir)/$(APP_NAME)<br />
<br />
all:<br />
clean:<br />
rm -rf $(tarball) $(P)<br />
<br />
dist: $(tarball)<br />
<br />
install:<br />
mkdir -p "$(install_dir)"<br />
cp -a $(APP_DIST) "$(install_dir)"<br />
<br />
$(tarball): $(DISTFILES)<br />
rm -rf $(P)<br />
mkdir -p $(P)<br />
cp $(DISTFILES) $(P)<br />
$(TAR) -jcf $@ $(P)<br />
rm -rf $(P)<br />
<br />
# target that creates a tar package, unpacks is and install from package<br />
dist-install: $(tarball)<br />
$(TAR) -jxf $(tarball)<br />
$(MAKE) -C $(P) install DESTDIR=$(DESTDIR)<br />
rm -rf $(P)<br />
<br />
include config.mk<br />
<br />
.PHONY: all clean dist install dist-install<br />
<br />
Remark: Should you create additional view files for example, don't forget to place their names in Makefile under APP_DIST otherwise they will not be installed later on and your application will fail with an error message.<br />
<br />
<br />
'''config.mk:'''<br />
For use with the Makefile. Just copy/paste it. We will look at it later.<br />
prefix=/usr<br />
datadir=${prefix}/share<br />
sysconfdir=${prefix}/etc<br />
localstatedir=${prefix}/var<br />
acfdir=${datadir}/acf<br />
wwwdir=${acfdir}/www<br />
cgibindir=${acfdir}/cgi-bin<br />
appdir=${acfdir}/app<br />
acflibdir=${acfdir}/lib<br />
sessionsdir=${localstatedir}/lib/acf/sessions<br />
<br />
<br />
'''myapp-model.lsp:'''<br />
-- acf model for myapp<br />
-- Copyright(c) 2007 <Your name here> - Licensed under terms of GPL2<br />
module (..., package.seeall)<br />
<br />
cfgfile = "/tmp/myfile"<br />
<br />
-- This function returns a cfe (table of values) containing the files'<br />
-- value as string and an error code. If the file does not exist, we'll<br />
-- simply return "" (an empty string, but NOT nil)<br />
readfile = function()<br />
retval = ""<br />
error = 0<br />
fileptr = io.open( cfgfile, "r" )<br />
if fileptr ~= nil then<br />
retval = fileptr:read( "*a" )<br />
if retval == nil then<br />
retval = ""<br />
end<br />
fileptr:close()<br />
end<br />
return error, cfe({ msg = retval })<br />
end<br />
<br />
-- This function will write new contents into our file<br />
writefile = function( newcontents )<br />
fileptr = io.open( cfgfile, "w+" )<br />
if fileptr ~= nil then<br />
fileptr:write( newcontents )<br />
fileptr:close()<br />
end<br />
return<br />
end<br />
<br />
<br />
'''myapp-myview-html.lsp:'''<br />
<?<br />
form = ...<br />
option = form.option<br />
?><br />
&lt;h1>MyApp - MyView&lt;/h1><br />
<form action="" method="POST"><br />
<textarea name="textdata"><? io.write( form.value.msg ); ?></textarea><br />
<input type="submit" name="cmd" value="update"><br />
</form><br />
<br />
<br />
'''myapp-controller.lua:'''<br />
-- the myapp controller<br />
module (..., package.seeall) <br />
<br />
--- default code up here<br />
--- do not change anything except: self.conf.action for redirect<br />
local list_redir = function( self )<br />
self.conf.action = "myview"<br />
self.conf.type = "redir"<br />
error (self.conf)<br />
end<br />
<br />
local pvt = {}<br />
mvc= {}<br />
mvc.on_load = function( self, parent )<br />
if ( rawget(self.worker, self.conf.action) == nil ) then<br />
list_redir(self)<br />
end<br />
pvt.parent_on_exec = parent.worker.mvc.post_exec<br />
end<br />
<br />
-- This is where 'our' code starts<br />
<br />
myview = function( self )<br />
-- self.clientdata contains the data from the html form<br />
-- in your myapp-myview-html.lsp<br />
local clidat = self.clientdata <br />
<br />
-- user did submit the form (not just call the page)<br />
if clidat.cmd then<br />
if clidat.cmd == "update" then -- user pressed update button<br />
self.model.writefile( clidat.textdata )<br />
end<br />
end<br />
error, value = self.model.readfile()<br />
return cfe({ value = value })<br />
end<br />
<br />
<br />
'''myapp.menu:'''<br />
# Cat Group Tab Action<br />
Test MyApp MyView MyView<br />
<br />
===Step 6 - What Does It Do?===<br />
This program only just displays a &lt;textarea> box and a submit "update" button. The user can enter text which is saved into a file once he presses "update".<br />
<br />
====In Depth====<br />
Now let us have a closer look at the different files' contents:<br />
<br />
=====myapp.menu=====<br />
In this file you define:<br />
* '''The Category''' in which a menu entry for your program will appear<br />
* '''The Group''', resp. the subheading's name under Category<br />
* '''The Action''' with-in your controller that will be called once the user klicks on the menu entry defined by Category and Group.<br />
<br />
=====myapp-controller.lua=====<br />
The controller is an event dispatcher. So in here you define all the actions that the user can call or that are defined in the menu. Each action is a separate function that will receive ''self'' as the only parameter.<br />
<br />
In our case the action is ''myview''.<br />
<br />
This function can call the ''model's'' functions to update and/or retrieve<br />
data (e.g. self.model.readfile()).<br />
<br />
Anything that this function returns will be passed on to the ''view''<br />
<br />
=====myapp-model.lua=====<br />
The functions defined in here can be accessed by the controller<br />
to update/set/retrieve data, start/stop services, basically do<br />
any 'real work'.<br />
<br />
=====myapp-myview-html.lsp=====<br />
This is our ''view''. It receives the data to be displayed via ''controller''. What ever is returned by a controller action (function) can be accessed by the view ''(see the first three lines .. &lt;? .. ?&gt;)''.<br />
<br />
====How to exchange data between model-view-controller?====<br />
To exchange data between model, view and controller ACF uses the so called<br />
''Configuration Framework Entities (CFE)''.<br />
<br />
Please see [[ACF_core_principles]] for further details on CFEs.</div>Macbrodyhttps://wiki.alpinelinux.org/w/index.php?title=ACF_how_to_write&diff=1881ACF how to write2007-11-17T09:49:09Z<p>Macbrody: /* How to exchange data between model-view-controller? */</p>
<hr />
<div>=How to Write an ACF <span style="color:red"> Under Construction</span> =<br />
<br />
For some examples please see svn<br />
<br />
svn co svn://svn.alpinelinux.org/acf<br />
<br />
*shorewall<br />
*dhcp<br />
<br />
<br />
==From <nil> to a running ACF example application <span style="color:red">Under Construction</span>==<br />
<br />
===Step 1 - The Programming Language===<br />
* ACF uses lua as programming language. Have a look at lua.org [http://www.lua.org/] before starting.<br />
<br />
===Step 2 - The Development Environment===<br />
* Setup an ACF Development Environment: [[Getting_started_with_ACF_development]]<br />
<br />
===Step 3 - Create A Development Directory===<br />
Once you entered the ACF Development Environment as described in step 2:<br />
* in your user home create a directory for your application (e.g. mkdir ~/myapp)<br />
* and cd into it (e.g. cd ~/myapp)<br />
<br />
===Step 4 - MVC, How Does It Affect My Coding?===<br />
ACF is an MVC based framework. What does this mean to you? Your application is separated into three layers: Model, View, Controller - each of which has one or more files.<br />
* Model: In Model the 'real work' is done (e.g. modifying config files, starting/stopping services etc.)<br />
* View: This is where you define what your application will look like. You can have one or more files, each presenting a dynamic html page which only as much code as neccessary to format the data you retrieve from Model.<br />
* Controller: The event dispatcher. In controller you place one function per event. If the user calls the respective 'event page' (web), acf will fire an action - the same-named function in controller will be called. This function then retrieves neccessary data from Model and passes it to View to be displayed to the user.<br />
<br />
===Step 5 - The Example Files To Start With===<br />
Now let us have a look at the files we need to place into our application directory:<br />
<br />
* Makefile<br />
* config.mk<br />
* myapp-model.lua<br />
* myapp-myview-html.lsp<br />
* myapp-controller.lua<br />
* myapp.menu<br />
<br />
<br />
'''Makefile:'''<br />
<br />
The Makefile once called does install our acf application so that we can look at it working.<br />
APP_NAME=myapp<br />
PACKAGE=acf-$(APP_NAME)<br />
VERSION=1.0_alpha1<br />
<br />
APP_DIST=myapp-model.lua \<br />
myapp-myview-html.lsp \<br />
myapp-controller.lua \<br />
myapp.menu<br />
<br />
EXTRA_DIST=README Makefile config.mk<br />
<br />
DISTFILES=$(APP_DIST) $(EXTRA_DIST)<br />
<br />
TAR=tar<br />
<br />
P=$(PACKAGE)-$(VERSION)<br />
tarball=$(P).tar.bz2<br />
install_dir=$(DESTDIR)/$(appdir)/$(APP_NAME)<br />
<br />
all:<br />
clean:<br />
rm -rf $(tarball) $(P)<br />
<br />
dist: $(tarball)<br />
<br />
install:<br />
mkdir -p "$(install_dir)"<br />
cp -a $(APP_DIST) "$(install_dir)"<br />
<br />
$(tarball): $(DISTFILES)<br />
rm -rf $(P)<br />
mkdir -p $(P)<br />
cp $(DISTFILES) $(P)<br />
$(TAR) -jcf $@ $(P)<br />
rm -rf $(P)<br />
<br />
# target that creates a tar package, unpacks is and install from package<br />
dist-install: $(tarball)<br />
$(TAR) -jxf $(tarball)<br />
$(MAKE) -C $(P) install DESTDIR=$(DESTDIR)<br />
rm -rf $(P)<br />
<br />
include config.mk<br />
<br />
.PHONY: all clean dist install dist-install<br />
<br />
Remark: Should you create additional view files for example, don't forget to place their names in Makefile under APP_DIST otherwise they will not be installed later on and your application will fail with an error message.<br />
<br />
<br />
'''config.mk:'''<br />
For use with the Makefile. Just copy/paste it. We will look at it later.<br />
prefix=/usr<br />
datadir=${prefix}/share<br />
sysconfdir=${prefix}/etc<br />
localstatedir=${prefix}/var<br />
acfdir=${datadir}/acf<br />
wwwdir=${acfdir}/www<br />
cgibindir=${acfdir}/cgi-bin<br />
appdir=${acfdir}/app<br />
acflibdir=${acfdir}/lib<br />
sessionsdir=${localstatedir}/lib/acf/sessions<br />
<br />
<br />
'''myapp-model.lsp:'''<br />
-- acf model for myapp<br />
-- Copyright(c) 2007 <Your name here> - Licensed under terms of GPL2<br />
module (..., package.seeall)<br />
<br />
cfgfile = "/tmp/myfile"<br />
<br />
-- This function returns a cfe (table of values) containing the files'<br />
-- value as string and an error code. If the file does not exist, we'll<br />
-- simply return "" (an empty string, but NOT nil)<br />
readfile = function()<br />
retval = ""<br />
error = 0<br />
fileptr = io.open( cfgfile, "r" )<br />
if fileptr ~= nil then<br />
retval = fileptr:read( "*a" )<br />
if retval == nil then<br />
retval = ""<br />
end<br />
fileptr:close()<br />
end<br />
return error, cfe({ msg = retval })<br />
end<br />
<br />
-- This function will write new contents into our file<br />
writefile = function( newcontents )<br />
fileptr = io.open( cfgfile, "w+" )<br />
if fileptr ~= nil then<br />
fileptr:write( newcontents )<br />
fileptr:close()<br />
end<br />
return<br />
end<br />
<br />
<br />
'''myapp-myview-html.lsp:'''<br />
<?<br />
form = ...<br />
option = form.option<br />
?><br />
&lt;h1>MyApp - MyView&lt;/h1><br />
<form action="" method="POST"><br />
<textarea name="textdata"><? io.write( form.value.msg ); ?></textarea><br />
<input type="submit" name="cmd" value="update"><br />
</form><br />
<br />
<br />
'''myapp-controller.lua:'''<br />
-- the myapp controller<br />
module (..., package.seeall) <br />
<br />
--- default code up here<br />
--- do not change anything except: self.conf.action for redirect<br />
local list_redir = function( self )<br />
self.conf.action = "myview"<br />
self.conf.type = "redir"<br />
error (self.conf)<br />
end<br />
<br />
local pvt = {}<br />
mvc= {}<br />
mvc.on_load = function( self, parent )<br />
if ( rawget(self.worker, self.conf.action) == nil ) then<br />
list_redir(self)<br />
end<br />
pvt.parent_on_exec = parent.worker.mvc.post_exec<br />
end<br />
<br />
-- This is where 'our' code starts<br />
<br />
myview = function( self )<br />
-- self.clientdata contains the data from the html form<br />
-- in your myapp-myview-html.lsp<br />
local clidat = self.clientdata <br />
<br />
-- user did submit the form (not just call the page)<br />
if clidat.cmd then<br />
if clidat.cmd == "update" then -- user pressed update button<br />
self.model.writefile( clidat.textdata )<br />
end<br />
end<br />
error, value = self.model.readfile()<br />
return cfe({ value = value })<br />
end<br />
<br />
<br />
'''myapp.menu:'''<br />
# Cat Group Tab Action<br />
Test MyApp MyView MyView<br />
<br />
===Step 6 - What Does It Do?===<br />
This program only just displays a &lt;textarea> box and a submit "update" button. The user can enter text which is saved into a file once he presses "update".<br />
<br />
====In Depth====<br />
Now let us have a closer look at what the different files' contents:<br />
<br />
=====myapp.menu=====<br />
In this file you define:<br />
* '''The Category''' in which a menu entry for your program will appear<br />
* '''The Group''', resp. the subheading's name under Category<br />
* '''The Action''' with-in your controller that will be called once the user klicks on the menu entry defined by Category and Group.<br />
<br />
=====myapp-controller.lua=====<br />
The controller is an event dispatcher. So in here you define all the actions that the user can call or that are defined in the menu. Each action is a separate function that will receive ''self'' as the only parameter.<br />
<br />
In our case the action is ''myview''.<br />
<br />
This function can call the ''model's'' functions to update and/or retrieve<br />
data (e.g. self.model.readfile()).<br />
<br />
Anything that this function returns will be passed on to the ''view''<br />
<br />
=====myapp-model.lua=====<br />
The functions defined in here can be accessed by the controller<br />
to update/set/retrieve data, start/stop services, basically do<br />
any 'real work'.<br />
<br />
=====myapp-myview-html.lsp=====<br />
This is our ''view''. It receives the data to be displayed via ''controller''. What ever is returned by a controller action (function) can be accessed by the view ''(see the first three lines .. &lt;? .. ?&gt;)''.<br />
<br />
====How to exchange data between model-view-controller?====<br />
To exchange data between model, view and controller ACF uses the so called<br />
''Configuration Framework Entities (CFE)''.<br />
<br />
Please see [[ACF_core_principles]] for further details on CFEs.</div>Macbrodyhttps://wiki.alpinelinux.org/w/index.php?title=ACF_how_to_write&diff=1880ACF how to write2007-11-17T09:47:54Z<p>Macbrody: /* How to exchange data between model-view-controller? */</p>
<hr />
<div>=How to Write an ACF <span style="color:red"> Under Construction</span> =<br />
<br />
For some examples please see svn<br />
<br />
svn co svn://svn.alpinelinux.org/acf<br />
<br />
*shorewall<br />
*dhcp<br />
<br />
<br />
==From <nil> to a running ACF example application <span style="color:red">Under Construction</span>==<br />
<br />
===Step 1 - The Programming Language===<br />
* ACF uses lua as programming language. Have a look at lua.org [http://www.lua.org/] before starting.<br />
<br />
===Step 2 - The Development Environment===<br />
* Setup an ACF Development Environment: [[Getting_started_with_ACF_development]]<br />
<br />
===Step 3 - Create A Development Directory===<br />
Once you entered the ACF Development Environment as described in step 2:<br />
* in your user home create a directory for your application (e.g. mkdir ~/myapp)<br />
* and cd into it (e.g. cd ~/myapp)<br />
<br />
===Step 4 - MVC, How Does It Affect My Coding?===<br />
ACF is an MVC based framework. What does this mean to you? Your application is separated into three layers: Model, View, Controller - each of which has one or more files.<br />
* Model: In Model the 'real work' is done (e.g. modifying config files, starting/stopping services etc.)<br />
* View: This is where you define what your application will look like. You can have one or more files, each presenting a dynamic html page which only as much code as neccessary to format the data you retrieve from Model.<br />
* Controller: The event dispatcher. In controller you place one function per event. If the user calls the respective 'event page' (web), acf will fire an action - the same-named function in controller will be called. This function then retrieves neccessary data from Model and passes it to View to be displayed to the user.<br />
<br />
===Step 5 - The Example Files To Start With===<br />
Now let us have a look at the files we need to place into our application directory:<br />
<br />
* Makefile<br />
* config.mk<br />
* myapp-model.lua<br />
* myapp-myview-html.lsp<br />
* myapp-controller.lua<br />
* myapp.menu<br />
<br />
<br />
'''Makefile:'''<br />
<br />
The Makefile once called does install our acf application so that we can look at it working.<br />
APP_NAME=myapp<br />
PACKAGE=acf-$(APP_NAME)<br />
VERSION=1.0_alpha1<br />
<br />
APP_DIST=myapp-model.lua \<br />
myapp-myview-html.lsp \<br />
myapp-controller.lua \<br />
myapp.menu<br />
<br />
EXTRA_DIST=README Makefile config.mk<br />
<br />
DISTFILES=$(APP_DIST) $(EXTRA_DIST)<br />
<br />
TAR=tar<br />
<br />
P=$(PACKAGE)-$(VERSION)<br />
tarball=$(P).tar.bz2<br />
install_dir=$(DESTDIR)/$(appdir)/$(APP_NAME)<br />
<br />
all:<br />
clean:<br />
rm -rf $(tarball) $(P)<br />
<br />
dist: $(tarball)<br />
<br />
install:<br />
mkdir -p "$(install_dir)"<br />
cp -a $(APP_DIST) "$(install_dir)"<br />
<br />
$(tarball): $(DISTFILES)<br />
rm -rf $(P)<br />
mkdir -p $(P)<br />
cp $(DISTFILES) $(P)<br />
$(TAR) -jcf $@ $(P)<br />
rm -rf $(P)<br />
<br />
# target that creates a tar package, unpacks is and install from package<br />
dist-install: $(tarball)<br />
$(TAR) -jxf $(tarball)<br />
$(MAKE) -C $(P) install DESTDIR=$(DESTDIR)<br />
rm -rf $(P)<br />
<br />
include config.mk<br />
<br />
.PHONY: all clean dist install dist-install<br />
<br />
Remark: Should you create additional view files for example, don't forget to place their names in Makefile under APP_DIST otherwise they will not be installed later on and your application will fail with an error message.<br />
<br />
<br />
'''config.mk:'''<br />
For use with the Makefile. Just copy/paste it. We will look at it later.<br />
prefix=/usr<br />
datadir=${prefix}/share<br />
sysconfdir=${prefix}/etc<br />
localstatedir=${prefix}/var<br />
acfdir=${datadir}/acf<br />
wwwdir=${acfdir}/www<br />
cgibindir=${acfdir}/cgi-bin<br />
appdir=${acfdir}/app<br />
acflibdir=${acfdir}/lib<br />
sessionsdir=${localstatedir}/lib/acf/sessions<br />
<br />
<br />
'''myapp-model.lsp:'''<br />
-- acf model for myapp<br />
-- Copyright(c) 2007 <Your name here> - Licensed under terms of GPL2<br />
module (..., package.seeall)<br />
<br />
cfgfile = "/tmp/myfile"<br />
<br />
-- This function returns a cfe (table of values) containing the files'<br />
-- value as string and an error code. If the file does not exist, we'll<br />
-- simply return "" (an empty string, but NOT nil)<br />
readfile = function()<br />
retval = ""<br />
error = 0<br />
fileptr = io.open( cfgfile, "r" )<br />
if fileptr ~= nil then<br />
retval = fileptr:read( "*a" )<br />
if retval == nil then<br />
retval = ""<br />
end<br />
fileptr:close()<br />
end<br />
return error, cfe({ msg = retval })<br />
end<br />
<br />
-- This function will write new contents into our file<br />
writefile = function( newcontents )<br />
fileptr = io.open( cfgfile, "w+" )<br />
if fileptr ~= nil then<br />
fileptr:write( newcontents )<br />
fileptr:close()<br />
end<br />
return<br />
end<br />
<br />
<br />
'''myapp-myview-html.lsp:'''<br />
<?<br />
form = ...<br />
option = form.option<br />
?><br />
&lt;h1>MyApp - MyView&lt;/h1><br />
<form action="" method="POST"><br />
<textarea name="textdata"><? io.write( form.value.msg ); ?></textarea><br />
<input type="submit" name="cmd" value="update"><br />
</form><br />
<br />
<br />
'''myapp-controller.lua:'''<br />
-- the myapp controller<br />
module (..., package.seeall) <br />
<br />
--- default code up here<br />
--- do not change anything except: self.conf.action for redirect<br />
local list_redir = function( self )<br />
self.conf.action = "myview"<br />
self.conf.type = "redir"<br />
error (self.conf)<br />
end<br />
<br />
local pvt = {}<br />
mvc= {}<br />
mvc.on_load = function( self, parent )<br />
if ( rawget(self.worker, self.conf.action) == nil ) then<br />
list_redir(self)<br />
end<br />
pvt.parent_on_exec = parent.worker.mvc.post_exec<br />
end<br />
<br />
-- This is where 'our' code starts<br />
<br />
myview = function( self )<br />
-- self.clientdata contains the data from the html form<br />
-- in your myapp-myview-html.lsp<br />
local clidat = self.clientdata <br />
<br />
-- user did submit the form (not just call the page)<br />
if clidat.cmd then<br />
if clidat.cmd == "update" then -- user pressed update button<br />
self.model.writefile( clidat.textdata )<br />
end<br />
end<br />
error, value = self.model.readfile()<br />
return cfe({ value = value })<br />
end<br />
<br />
<br />
'''myapp.menu:'''<br />
# Cat Group Tab Action<br />
Test MyApp MyView MyView<br />
<br />
===Step 6 - What Does It Do?===<br />
This program only just displays a &lt;textarea> box and a submit "update" button. The user can enter text which is saved into a file once he presses "update".<br />
<br />
====In Depth====<br />
Now let us have a closer look at what the different files' contents:<br />
<br />
=====myapp.menu=====<br />
In this file you define:<br />
* '''The Category''' in which a menu entry for your program will appear<br />
* '''The Group''', resp. the subheading's name under Category<br />
* '''The Action''' with-in your controller that will be called once the user klicks on the menu entry defined by Category and Group.<br />
<br />
=====myapp-controller.lua=====<br />
The controller is an event dispatcher. So in here you define all the actions that the user can call or that are defined in the menu. Each action is a separate function that will receive ''self'' as the only parameter.<br />
<br />
In our case the action is ''myview''.<br />
<br />
This function can call the ''model's'' functions to update and/or retrieve<br />
data (e.g. self.model.readfile()).<br />
<br />
Anything that this function returns will be passed on to the ''view''<br />
<br />
=====myapp-model.lua=====<br />
The functions defined in here can be accessed by the controller<br />
to update/set/retrieve data, start/stop services, basically do<br />
any 'real work'.<br />
<br />
=====myapp-myview-html.lsp=====<br />
This is our ''view''. It receives the data to be displayed via ''controller''. What ever is returned by a controller action (function) can be accessed by the view ''(see the first three lines .. &lt;? .. ?&gt;)''.<br />
<br />
====How to exchange data between model-view-controller?====<br />
To exchange data between model, view and controller ACF uses the so called<br />
''Configuration Framework Entities (CFE)''.<br />
<br />
Please see [[oink]] for further details on CFEs.</div>Macbrodyhttps://wiki.alpinelinux.org/w/index.php?title=ACF_how_to_write&diff=1879ACF how to write2007-11-17T09:46:56Z<p>Macbrody: /* Step 6 - What Does It Do? */</p>
<hr />
<div>=How to Write an ACF <span style="color:red"> Under Construction</span> =<br />
<br />
For some examples please see svn<br />
<br />
svn co svn://svn.alpinelinux.org/acf<br />
<br />
*shorewall<br />
*dhcp<br />
<br />
<br />
==From <nil> to a running ACF example application <span style="color:red">Under Construction</span>==<br />
<br />
===Step 1 - The Programming Language===<br />
* ACF uses lua as programming language. Have a look at lua.org [http://www.lua.org/] before starting.<br />
<br />
===Step 2 - The Development Environment===<br />
* Setup an ACF Development Environment: [[Getting_started_with_ACF_development]]<br />
<br />
===Step 3 - Create A Development Directory===<br />
Once you entered the ACF Development Environment as described in step 2:<br />
* in your user home create a directory for your application (e.g. mkdir ~/myapp)<br />
* and cd into it (e.g. cd ~/myapp)<br />
<br />
===Step 4 - MVC, How Does It Affect My Coding?===<br />
ACF is an MVC based framework. What does this mean to you? Your application is separated into three layers: Model, View, Controller - each of which has one or more files.<br />
* Model: In Model the 'real work' is done (e.g. modifying config files, starting/stopping services etc.)<br />
* View: This is where you define what your application will look like. You can have one or more files, each presenting a dynamic html page which only as much code as neccessary to format the data you retrieve from Model.<br />
* Controller: The event dispatcher. In controller you place one function per event. If the user calls the respective 'event page' (web), acf will fire an action - the same-named function in controller will be called. This function then retrieves neccessary data from Model and passes it to View to be displayed to the user.<br />
<br />
===Step 5 - The Example Files To Start With===<br />
Now let us have a look at the files we need to place into our application directory:<br />
<br />
* Makefile<br />
* config.mk<br />
* myapp-model.lua<br />
* myapp-myview-html.lsp<br />
* myapp-controller.lua<br />
* myapp.menu<br />
<br />
<br />
'''Makefile:'''<br />
<br />
The Makefile once called does install our acf application so that we can look at it working.<br />
APP_NAME=myapp<br />
PACKAGE=acf-$(APP_NAME)<br />
VERSION=1.0_alpha1<br />
<br />
APP_DIST=myapp-model.lua \<br />
myapp-myview-html.lsp \<br />
myapp-controller.lua \<br />
myapp.menu<br />
<br />
EXTRA_DIST=README Makefile config.mk<br />
<br />
DISTFILES=$(APP_DIST) $(EXTRA_DIST)<br />
<br />
TAR=tar<br />
<br />
P=$(PACKAGE)-$(VERSION)<br />
tarball=$(P).tar.bz2<br />
install_dir=$(DESTDIR)/$(appdir)/$(APP_NAME)<br />
<br />
all:<br />
clean:<br />
rm -rf $(tarball) $(P)<br />
<br />
dist: $(tarball)<br />
<br />
install:<br />
mkdir -p "$(install_dir)"<br />
cp -a $(APP_DIST) "$(install_dir)"<br />
<br />
$(tarball): $(DISTFILES)<br />
rm -rf $(P)<br />
mkdir -p $(P)<br />
cp $(DISTFILES) $(P)<br />
$(TAR) -jcf $@ $(P)<br />
rm -rf $(P)<br />
<br />
# target that creates a tar package, unpacks is and install from package<br />
dist-install: $(tarball)<br />
$(TAR) -jxf $(tarball)<br />
$(MAKE) -C $(P) install DESTDIR=$(DESTDIR)<br />
rm -rf $(P)<br />
<br />
include config.mk<br />
<br />
.PHONY: all clean dist install dist-install<br />
<br />
Remark: Should you create additional view files for example, don't forget to place their names in Makefile under APP_DIST otherwise they will not be installed later on and your application will fail with an error message.<br />
<br />
<br />
'''config.mk:'''<br />
For use with the Makefile. Just copy/paste it. We will look at it later.<br />
prefix=/usr<br />
datadir=${prefix}/share<br />
sysconfdir=${prefix}/etc<br />
localstatedir=${prefix}/var<br />
acfdir=${datadir}/acf<br />
wwwdir=${acfdir}/www<br />
cgibindir=${acfdir}/cgi-bin<br />
appdir=${acfdir}/app<br />
acflibdir=${acfdir}/lib<br />
sessionsdir=${localstatedir}/lib/acf/sessions<br />
<br />
<br />
'''myapp-model.lsp:'''<br />
-- acf model for myapp<br />
-- Copyright(c) 2007 <Your name here> - Licensed under terms of GPL2<br />
module (..., package.seeall)<br />
<br />
cfgfile = "/tmp/myfile"<br />
<br />
-- This function returns a cfe (table of values) containing the files'<br />
-- value as string and an error code. If the file does not exist, we'll<br />
-- simply return "" (an empty string, but NOT nil)<br />
readfile = function()<br />
retval = ""<br />
error = 0<br />
fileptr = io.open( cfgfile, "r" )<br />
if fileptr ~= nil then<br />
retval = fileptr:read( "*a" )<br />
if retval == nil then<br />
retval = ""<br />
end<br />
fileptr:close()<br />
end<br />
return error, cfe({ msg = retval })<br />
end<br />
<br />
-- This function will write new contents into our file<br />
writefile = function( newcontents )<br />
fileptr = io.open( cfgfile, "w+" )<br />
if fileptr ~= nil then<br />
fileptr:write( newcontents )<br />
fileptr:close()<br />
end<br />
return<br />
end<br />
<br />
<br />
'''myapp-myview-html.lsp:'''<br />
<?<br />
form = ...<br />
option = form.option<br />
?><br />
&lt;h1>MyApp - MyView&lt;/h1><br />
<form action="" method="POST"><br />
<textarea name="textdata"><? io.write( form.value.msg ); ?></textarea><br />
<input type="submit" name="cmd" value="update"><br />
</form><br />
<br />
<br />
'''myapp-controller.lua:'''<br />
-- the myapp controller<br />
module (..., package.seeall) <br />
<br />
--- default code up here<br />
--- do not change anything except: self.conf.action for redirect<br />
local list_redir = function( self )<br />
self.conf.action = "myview"<br />
self.conf.type = "redir"<br />
error (self.conf)<br />
end<br />
<br />
local pvt = {}<br />
mvc= {}<br />
mvc.on_load = function( self, parent )<br />
if ( rawget(self.worker, self.conf.action) == nil ) then<br />
list_redir(self)<br />
end<br />
pvt.parent_on_exec = parent.worker.mvc.post_exec<br />
end<br />
<br />
-- This is where 'our' code starts<br />
<br />
myview = function( self )<br />
-- self.clientdata contains the data from the html form<br />
-- in your myapp-myview-html.lsp<br />
local clidat = self.clientdata <br />
<br />
-- user did submit the form (not just call the page)<br />
if clidat.cmd then<br />
if clidat.cmd == "update" then -- user pressed update button<br />
self.model.writefile( clidat.textdata )<br />
end<br />
end<br />
error, value = self.model.readfile()<br />
return cfe({ value = value })<br />
end<br />
<br />
<br />
'''myapp.menu:'''<br />
# Cat Group Tab Action<br />
Test MyApp MyView MyView<br />
<br />
===Step 6 - What Does It Do?===<br />
This program only just displays a &lt;textarea> box and a submit "update" button. The user can enter text which is saved into a file once he presses "update".<br />
<br />
====In Depth====<br />
Now let us have a closer look at what the different files' contents:<br />
<br />
=====myapp.menu=====<br />
In this file you define:<br />
* '''The Category''' in which a menu entry for your program will appear<br />
* '''The Group''', resp. the subheading's name under Category<br />
* '''The Action''' with-in your controller that will be called once the user klicks on the menu entry defined by Category and Group.<br />
<br />
=====myapp-controller.lua=====<br />
The controller is an event dispatcher. So in here you define all the actions that the user can call or that are defined in the menu. Each action is a separate function that will receive ''self'' as the only parameter.<br />
<br />
In our case the action is ''myview''.<br />
<br />
This function can call the ''model's'' functions to update and/or retrieve<br />
data (e.g. self.model.readfile()).<br />
<br />
Anything that this function returns will be passed on to the ''view''<br />
<br />
=====myapp-model.lua=====<br />
The functions defined in here can be accessed by the controller<br />
to update/set/retrieve data, start/stop services, basically do<br />
any 'real work'.<br />
<br />
=====myapp-myview-html.lsp=====<br />
This is our ''view''. It receives the data to be displayed via ''controller''. What ever is returned by a controller action (function) can be accessed by the view ''(see the first three lines .. &lt;? .. ?&gt;)''.<br />
<br />
====How to exchange data between model-view-controller?====<br />
The exchange data between model, view and controller ACF uses the so called<br />
''Configuration Framework Entities (CFE)''.<br />
<br />
Please see [[oink]] for further details on CFEs.</div>Macbrodyhttps://wiki.alpinelinux.org/w/index.php?title=ACF_how_to_write&diff=1878ACF how to write2007-11-17T09:45:43Z<p>Macbrody: </p>
<hr />
<div>=How to Write an ACF <span style="color:red"> Under Construction</span> =<br />
<br />
For some examples please see svn<br />
<br />
svn co svn://svn.alpinelinux.org/acf<br />
<br />
*shorewall<br />
*dhcp<br />
<br />
<br />
==From <nil> to a running ACF example application <span style="color:red">Under Construction</span>==<br />
<br />
===Step 1 - The Programming Language===<br />
* ACF uses lua as programming language. Have a look at lua.org [http://www.lua.org/] before starting.<br />
<br />
===Step 2 - The Development Environment===<br />
* Setup an ACF Development Environment: [[Getting_started_with_ACF_development]]<br />
<br />
===Step 3 - Create A Development Directory===<br />
Once you entered the ACF Development Environment as described in step 2:<br />
* in your user home create a directory for your application (e.g. mkdir ~/myapp)<br />
* and cd into it (e.g. cd ~/myapp)<br />
<br />
===Step 4 - MVC, How Does It Affect My Coding?===<br />
ACF is an MVC based framework. What does this mean to you? Your application is separated into three layers: Model, View, Controller - each of which has one or more files.<br />
* Model: In Model the 'real work' is done (e.g. modifying config files, starting/stopping services etc.)<br />
* View: This is where you define what your application will look like. You can have one or more files, each presenting a dynamic html page which only as much code as neccessary to format the data you retrieve from Model.<br />
* Controller: The event dispatcher. In controller you place one function per event. If the user calls the respective 'event page' (web), acf will fire an action - the same-named function in controller will be called. This function then retrieves neccessary data from Model and passes it to View to be displayed to the user.<br />
<br />
===Step 5 - The Example Files To Start With===<br />
Now let us have a look at the files we need to place into our application directory:<br />
<br />
* Makefile<br />
* config.mk<br />
* myapp-model.lua<br />
* myapp-myview-html.lsp<br />
* myapp-controller.lua<br />
* myapp.menu<br />
<br />
<br />
'''Makefile:'''<br />
<br />
The Makefile once called does install our acf application so that we can look at it working.<br />
APP_NAME=myapp<br />
PACKAGE=acf-$(APP_NAME)<br />
VERSION=1.0_alpha1<br />
<br />
APP_DIST=myapp-model.lua \<br />
myapp-myview-html.lsp \<br />
myapp-controller.lua \<br />
myapp.menu<br />
<br />
EXTRA_DIST=README Makefile config.mk<br />
<br />
DISTFILES=$(APP_DIST) $(EXTRA_DIST)<br />
<br />
TAR=tar<br />
<br />
P=$(PACKAGE)-$(VERSION)<br />
tarball=$(P).tar.bz2<br />
install_dir=$(DESTDIR)/$(appdir)/$(APP_NAME)<br />
<br />
all:<br />
clean:<br />
rm -rf $(tarball) $(P)<br />
<br />
dist: $(tarball)<br />
<br />
install:<br />
mkdir -p "$(install_dir)"<br />
cp -a $(APP_DIST) "$(install_dir)"<br />
<br />
$(tarball): $(DISTFILES)<br />
rm -rf $(P)<br />
mkdir -p $(P)<br />
cp $(DISTFILES) $(P)<br />
$(TAR) -jcf $@ $(P)<br />
rm -rf $(P)<br />
<br />
# target that creates a tar package, unpacks is and install from package<br />
dist-install: $(tarball)<br />
$(TAR) -jxf $(tarball)<br />
$(MAKE) -C $(P) install DESTDIR=$(DESTDIR)<br />
rm -rf $(P)<br />
<br />
include config.mk<br />
<br />
.PHONY: all clean dist install dist-install<br />
<br />
Remark: Should you create additional view files for example, don't forget to place their names in Makefile under APP_DIST otherwise they will not be installed later on and your application will fail with an error message.<br />
<br />
<br />
'''config.mk:'''<br />
For use with the Makefile. Just copy/paste it. We will look at it later.<br />
prefix=/usr<br />
datadir=${prefix}/share<br />
sysconfdir=${prefix}/etc<br />
localstatedir=${prefix}/var<br />
acfdir=${datadir}/acf<br />
wwwdir=${acfdir}/www<br />
cgibindir=${acfdir}/cgi-bin<br />
appdir=${acfdir}/app<br />
acflibdir=${acfdir}/lib<br />
sessionsdir=${localstatedir}/lib/acf/sessions<br />
<br />
<br />
'''myapp-model.lsp:'''<br />
-- acf model for myapp<br />
-- Copyright(c) 2007 <Your name here> - Licensed under terms of GPL2<br />
module (..., package.seeall)<br />
<br />
cfgfile = "/tmp/myfile"<br />
<br />
-- This function returns a cfe (table of values) containing the files'<br />
-- value as string and an error code. If the file does not exist, we'll<br />
-- simply return "" (an empty string, but NOT nil)<br />
readfile = function()<br />
retval = ""<br />
error = 0<br />
fileptr = io.open( cfgfile, "r" )<br />
if fileptr ~= nil then<br />
retval = fileptr:read( "*a" )<br />
if retval == nil then<br />
retval = ""<br />
end<br />
fileptr:close()<br />
end<br />
return error, cfe({ msg = retval })<br />
end<br />
<br />
-- This function will write new contents into our file<br />
writefile = function( newcontents )<br />
fileptr = io.open( cfgfile, "w+" )<br />
if fileptr ~= nil then<br />
fileptr:write( newcontents )<br />
fileptr:close()<br />
end<br />
return<br />
end<br />
<br />
<br />
'''myapp-myview-html.lsp:'''<br />
<?<br />
form = ...<br />
option = form.option<br />
?><br />
&lt;h1>MyApp - MyView&lt;/h1><br />
<form action="" method="POST"><br />
<textarea name="textdata"><? io.write( form.value.msg ); ?></textarea><br />
<input type="submit" name="cmd" value="update"><br />
</form><br />
<br />
<br />
'''myapp-controller.lua:'''<br />
-- the myapp controller<br />
module (..., package.seeall) <br />
<br />
--- default code up here<br />
--- do not change anything except: self.conf.action for redirect<br />
local list_redir = function( self )<br />
self.conf.action = "myview"<br />
self.conf.type = "redir"<br />
error (self.conf)<br />
end<br />
<br />
local pvt = {}<br />
mvc= {}<br />
mvc.on_load = function( self, parent )<br />
if ( rawget(self.worker, self.conf.action) == nil ) then<br />
list_redir(self)<br />
end<br />
pvt.parent_on_exec = parent.worker.mvc.post_exec<br />
end<br />
<br />
-- This is where 'our' code starts<br />
<br />
myview = function( self )<br />
-- self.clientdata contains the data from the html form<br />
-- in your myapp-myview-html.lsp<br />
local clidat = self.clientdata <br />
<br />
-- user did submit the form (not just call the page)<br />
if clidat.cmd then<br />
if clidat.cmd == "update" then -- user pressed update button<br />
self.model.writefile( clidat.textdata )<br />
end<br />
end<br />
error, value = self.model.readfile()<br />
return cfe({ value = value })<br />
end<br />
<br />
<br />
'''myapp.menu:'''<br />
# Cat Group Tab Action<br />
Test MyApp MyView MyView<br />
<br />
===Step 6 - What Does It Do?===<br />
This program only just displays a &lt;textarea> box and a submit "update" button. The user can enter the which is saved into a file once he presses "update".<br />
<br />
====In Depth====<br />
Now let us have a closer look at what the different files' contents:<br />
<br />
=====myapp.menu=====<br />
In this file you define:<br />
* '''The Category''' in which a menu entry for your program will appear<br />
* '''The Group''', resp. the subheading's name under Category<br />
* '''The Action''' with-in your controller that will be called once the user klicks on the menu entry defined by Category and Group.<br />
<br />
=====myapp-controller.lua=====<br />
The controller is an event dispatcher. So in here you define all the actions that the user can call or that are defined in the menu. Each action is a separate function that will receive ''self'' as the only parameter.<br />
<br />
In our case the action is ''myview''.<br />
<br />
This function can call the ''model's'' functions to update and/or retrieve<br />
data (e.g. self.model.readfile()).<br />
<br />
Anything that this function returns will be passed on to the ''view''<br />
<br />
=====myapp-model.lua=====<br />
The functions defined in here can be accessed by the controller<br />
to update/set/retrieve data, start/stop services, basically do<br />
any 'real work'.<br />
<br />
=====myapp-myview-html.lsp=====<br />
This is our ''view''. It receives the data to be displayed via ''controller''. What ever is returned by a controller action (function) can be accessed by the view ''(see the first three lines .. &lt;? .. ?&gt;)''.<br />
<br />
====How to exchange data between model-view-controller?====<br />
The exchange data between model, view and controller ACF uses the so called<br />
''Configuration Framework Entities (CFE)''.<br />
<br />
Please see [[oink]] for further details on CFEs.</div>Macbrodyhttps://wiki.alpinelinux.org/w/index.php?title=ACF_how_to_write&diff=1877ACF how to write2007-11-17T09:43:09Z<p>Macbrody: /* myapp-myview-html.lsp */</p>
<hr />
<div>=How to Write an ACF <span style="color:red"> Under Construction</span> =<br />
<br />
For some examples please see svn<br />
<br />
svn co svn://svn.alpinelinux.org/acf<br />
<br />
*shorewall<br />
*dhcp<br />
<br />
<br />
==From <nil> to a running ACF example application <span style="color:red">Under Construction</span>==<br />
<br />
===Step 1 - The Programming Language===<br />
* ACF uses lua as programming language. Have a look at lua.org [http://www.lua.org/] before starting.<br />
<br />
===Step 2 - The Development Environment===<br />
* Setup an ACF Development Environment: [[Getting_started_with_ACF_development]]<br />
<br />
===Step 3 - Create A Development Directory===<br />
Once you entered the ACF Development Environment as described in step 2:<br />
* in your user home create a directory for your application (e.g. mkdir ~/myapp)<br />
* and cd into it (e.g. cd ~/myapp)<br />
<br />
===Step 4 - MVC, How Does It Affect My Coding?===<br />
ACF is an MVC based framework. What does this mean to you? Your application is separated into three layers: Model, View, Controller - each of which has one or more files.<br />
* Model: In Model the 'real work' is done (e.g. modifying config files, starting/stopping services etc.)<br />
* View: This is where you define what your application will look like. You can have one or more files, each presenting a dynamic html page which only as much code as neccessary to format the data you retrieve from Model.<br />
* Controller: The event dispatcher. In controller you place one function per event. If the user calls the respective 'event page' (web), acf will fire an action - the same-named function in controller will be called. This function then retrieves neccessary data from Model and passes it to View to be displayed to the user.<br />
<br />
===Step 5 - The Example Files To Start With===<br />
Now let us have a look at the files we need to place into our application directory:<br />
<br />
* Makefile<br />
* config.mk<br />
* myapp-model.lua<br />
* myapp-myview-html.lsp<br />
* myapp-controller.lua<br />
* myapp.menu<br />
<br />
<br />
'''Makefile:'''<br />
<br />
The Makefile once called does install our acf application so that we can look at it working.<br />
APP_NAME=myapp<br />
PACKAGE=acf-$(APP_NAME)<br />
VERSION=1.0_alpha1<br />
<br />
APP_DIST=myapp-model.lua \<br />
myapp-myview-html.lsp \<br />
myapp-controller.lua \<br />
myapp.menu<br />
<br />
EXTRA_DIST=README Makefile config.mk<br />
<br />
DISTFILES=$(APP_DIST) $(EXTRA_DIST)<br />
<br />
TAR=tar<br />
<br />
P=$(PACKAGE)-$(VERSION)<br />
tarball=$(P).tar.bz2<br />
install_dir=$(DESTDIR)/$(appdir)/$(APP_NAME)<br />
<br />
all:<br />
clean:<br />
rm -rf $(tarball) $(P)<br />
<br />
dist: $(tarball)<br />
<br />
install:<br />
mkdir -p "$(install_dir)"<br />
cp -a $(APP_DIST) "$(install_dir)"<br />
<br />
$(tarball): $(DISTFILES)<br />
rm -rf $(P)<br />
mkdir -p $(P)<br />
cp $(DISTFILES) $(P)<br />
$(TAR) -jcf $@ $(P)<br />
rm -rf $(P)<br />
<br />
# target that creates a tar package, unpacks is and install from package<br />
dist-install: $(tarball)<br />
$(TAR) -jxf $(tarball)<br />
$(MAKE) -C $(P) install DESTDIR=$(DESTDIR)<br />
rm -rf $(P)<br />
<br />
include config.mk<br />
<br />
.PHONY: all clean dist install dist-install<br />
<br />
Remark: Should you create additional view files for example, don't forget to place their names in Makefile under APP_DIST otherwise they will not be installed later on and your application will fail with an error message.<br />
<br />
<br />
'''config.mk:'''<br />
For use with the Makefile. Just copy/paste it. We will look at it later.<br />
prefix=/usr<br />
datadir=${prefix}/share<br />
sysconfdir=${prefix}/etc<br />
localstatedir=${prefix}/var<br />
acfdir=${datadir}/acf<br />
wwwdir=${acfdir}/www<br />
cgibindir=${acfdir}/cgi-bin<br />
appdir=${acfdir}/app<br />
acflibdir=${acfdir}/lib<br />
sessionsdir=${localstatedir}/lib/acf/sessions<br />
<br />
<br />
'''myapp-model.lsp:'''<br />
-- acf model for myapp<br />
-- Copyright(c) 2007 <Your name here> - Licensed under terms of GPL2<br />
module (..., package.seeall)<br />
<br />
cfgfile = "/tmp/myfile"<br />
<br />
-- This function returns a cfe (table of values) containing the files'<br />
-- value as string and an error code. If the file does not exist, we'll<br />
-- simply return "" (an empty string, but NOT nil)<br />
readfile = function()<br />
retval = ""<br />
error = 0<br />
fileptr = io.open( cfgfile, "r" )<br />
if fileptr ~= nil then<br />
retval = fileptr:read( "*a" )<br />
if retval == nil then<br />
retval = ""<br />
end<br />
fileptr:close()<br />
end<br />
return error, cfe({ msg = retval })<br />
end<br />
<br />
-- This function will write new contents into our file<br />
writefile = function( newcontents )<br />
fileptr = io.open( cfgfile, "w+" )<br />
if fileptr ~= nil then<br />
fileptr:write( newcontents )<br />
fileptr:close()<br />
end<br />
return<br />
end<br />
<br />
<br />
'''myapp-myview-html.lsp:'''<br />
<?<br />
form = ...<br />
option = form.option<br />
?><br />
&lt;h1>MyApp - MyView&lt;/h1><br />
<form action="" method="POST"><br />
<textarea name="textdata"><? io.write( form.value.msg ); ?></textarea><br />
<input type="submit" name="cmd" value="update"><br />
</form><br />
<br />
<br />
'''myapp-controller.lua:'''<br />
-- the myapp controller<br />
module (..., package.seeall) <br />
<br />
--- default code up here<br />
--- do not change anything except: self.conf.action for redirect<br />
local list_redir = function( self )<br />
self.conf.action = "myview"<br />
self.conf.type = "redir"<br />
error (self.conf)<br />
end<br />
<br />
local pvt = {}<br />
mvc= {}<br />
mvc.on_load = function( self, parent )<br />
if ( rawget(self.worker, self.conf.action) == nil ) then<br />
list_redir(self)<br />
end<br />
pvt.parent_on_exec = parent.worker.mvc.post_exec<br />
end<br />
<br />
-- This is where 'our' code starts<br />
<br />
myview = function( self )<br />
-- self.clientdata contains the data from the html form<br />
-- in your myapp-myview-html.lsp<br />
local clidat = self.clientdata <br />
<br />
-- user did submit the form (not just call the page)<br />
if clidat.cmd then<br />
if clidat.cmd == "update" then -- user pressed update button<br />
self.model.writefile( clidat.textdata )<br />
end<br />
end<br />
error, value = self.model.readfile()<br />
return cfe({ value = value })<br />
end<br />
<br />
<br />
'''myapp.menu:'''<br />
# Cat Group Tab Action<br />
Test MyApp MyView MyView<br />
<br />
===Step 6 - What Does It Do?===<br />
This program only just displays a &lt;textarea> box and a submit "update" button. The user can enter the which is saved into a file once he presses "update".<br />
<br />
====In Depth====<br />
Now let us have a closer look at what the different files' contents:<br />
<br />
=====myapp.menu=====<br />
In this file you define:<br />
* '''The Category''' in which a menu entry for your program will appear<br />
* '''The Group''', resp. the subheading's name under Category<br />
* '''The Action''' with-in your controller that will be called once the user klicks on the menu entry defined by Category and Group.<br />
<br />
=====myapp-controller.lua=====<br />
The controller is an event dispatcher. So in here you define all the actions that the user can call or that are defined in the menu. Each action is a separate function that will receive ''self'' as the only parameter.<br />
<br />
In our case the action is ''myview''.<br />
<br />
This function can call the ''model's'' functions to update and/or retrieve<br />
data (e.g. self.model.readfile()).<br />
<br />
Anything that this function returns will be passed on to the ''view''<br />
<br />
=====myapp-model.lua=====<br />
The functions defined in here can be accessed by the controller<br />
to update/set/retrieve data, start/stop services, basically do<br />
any 'real work'.<br />
<br />
=====myapp-myview-html.lsp=====<br />
This is our ''view''. It receives the data to be displayed via ''controller''. What ever is returned by a controller action (function) can be accessed by the view ''(see the first three lines .. &lt;? .. ?&gt;)''.</div>Macbrodyhttps://wiki.alpinelinux.org/w/index.php?title=ACF_how_to_write&diff=1876ACF how to write2007-11-17T09:41:12Z<p>Macbrody: /* myapp-model.lua */</p>
<hr />
<div>=How to Write an ACF <span style="color:red"> Under Construction</span> =<br />
<br />
For some examples please see svn<br />
<br />
svn co svn://svn.alpinelinux.org/acf<br />
<br />
*shorewall<br />
*dhcp<br />
<br />
<br />
==From <nil> to a running ACF example application <span style="color:red">Under Construction</span>==<br />
<br />
===Step 1 - The Programming Language===<br />
* ACF uses lua as programming language. Have a look at lua.org [http://www.lua.org/] before starting.<br />
<br />
===Step 2 - The Development Environment===<br />
* Setup an ACF Development Environment: [[Getting_started_with_ACF_development]]<br />
<br />
===Step 3 - Create A Development Directory===<br />
Once you entered the ACF Development Environment as described in step 2:<br />
* in your user home create a directory for your application (e.g. mkdir ~/myapp)<br />
* and cd into it (e.g. cd ~/myapp)<br />
<br />
===Step 4 - MVC, How Does It Affect My Coding?===<br />
ACF is an MVC based framework. What does this mean to you? Your application is separated into three layers: Model, View, Controller - each of which has one or more files.<br />
* Model: In Model the 'real work' is done (e.g. modifying config files, starting/stopping services etc.)<br />
* View: This is where you define what your application will look like. You can have one or more files, each presenting a dynamic html page which only as much code as neccessary to format the data you retrieve from Model.<br />
* Controller: The event dispatcher. In controller you place one function per event. If the user calls the respective 'event page' (web), acf will fire an action - the same-named function in controller will be called. This function then retrieves neccessary data from Model and passes it to View to be displayed to the user.<br />
<br />
===Step 5 - The Example Files To Start With===<br />
Now let us have a look at the files we need to place into our application directory:<br />
<br />
* Makefile<br />
* config.mk<br />
* myapp-model.lua<br />
* myapp-myview-html.lsp<br />
* myapp-controller.lua<br />
* myapp.menu<br />
<br />
<br />
'''Makefile:'''<br />
<br />
The Makefile once called does install our acf application so that we can look at it working.<br />
APP_NAME=myapp<br />
PACKAGE=acf-$(APP_NAME)<br />
VERSION=1.0_alpha1<br />
<br />
APP_DIST=myapp-model.lua \<br />
myapp-myview-html.lsp \<br />
myapp-controller.lua \<br />
myapp.menu<br />
<br />
EXTRA_DIST=README Makefile config.mk<br />
<br />
DISTFILES=$(APP_DIST) $(EXTRA_DIST)<br />
<br />
TAR=tar<br />
<br />
P=$(PACKAGE)-$(VERSION)<br />
tarball=$(P).tar.bz2<br />
install_dir=$(DESTDIR)/$(appdir)/$(APP_NAME)<br />
<br />
all:<br />
clean:<br />
rm -rf $(tarball) $(P)<br />
<br />
dist: $(tarball)<br />
<br />
install:<br />
mkdir -p "$(install_dir)"<br />
cp -a $(APP_DIST) "$(install_dir)"<br />
<br />
$(tarball): $(DISTFILES)<br />
rm -rf $(P)<br />
mkdir -p $(P)<br />
cp $(DISTFILES) $(P)<br />
$(TAR) -jcf $@ $(P)<br />
rm -rf $(P)<br />
<br />
# target that creates a tar package, unpacks is and install from package<br />
dist-install: $(tarball)<br />
$(TAR) -jxf $(tarball)<br />
$(MAKE) -C $(P) install DESTDIR=$(DESTDIR)<br />
rm -rf $(P)<br />
<br />
include config.mk<br />
<br />
.PHONY: all clean dist install dist-install<br />
<br />
Remark: Should you create additional view files for example, don't forget to place their names in Makefile under APP_DIST otherwise they will not be installed later on and your application will fail with an error message.<br />
<br />
<br />
'''config.mk:'''<br />
For use with the Makefile. Just copy/paste it. We will look at it later.<br />
prefix=/usr<br />
datadir=${prefix}/share<br />
sysconfdir=${prefix}/etc<br />
localstatedir=${prefix}/var<br />
acfdir=${datadir}/acf<br />
wwwdir=${acfdir}/www<br />
cgibindir=${acfdir}/cgi-bin<br />
appdir=${acfdir}/app<br />
acflibdir=${acfdir}/lib<br />
sessionsdir=${localstatedir}/lib/acf/sessions<br />
<br />
<br />
'''myapp-model.lsp:'''<br />
-- acf model for myapp<br />
-- Copyright(c) 2007 <Your name here> - Licensed under terms of GPL2<br />
module (..., package.seeall)<br />
<br />
cfgfile = "/tmp/myfile"<br />
<br />
-- This function returns a cfe (table of values) containing the files'<br />
-- value as string and an error code. If the file does not exist, we'll<br />
-- simply return "" (an empty string, but NOT nil)<br />
readfile = function()<br />
retval = ""<br />
error = 0<br />
fileptr = io.open( cfgfile, "r" )<br />
if fileptr ~= nil then<br />
retval = fileptr:read( "*a" )<br />
if retval == nil then<br />
retval = ""<br />
end<br />
fileptr:close()<br />
end<br />
return error, cfe({ msg = retval })<br />
end<br />
<br />
-- This function will write new contents into our file<br />
writefile = function( newcontents )<br />
fileptr = io.open( cfgfile, "w+" )<br />
if fileptr ~= nil then<br />
fileptr:write( newcontents )<br />
fileptr:close()<br />
end<br />
return<br />
end<br />
<br />
<br />
'''myapp-myview-html.lsp:'''<br />
<?<br />
form = ...<br />
option = form.option<br />
?><br />
&lt;h1>MyApp - MyView&lt;/h1><br />
<form action="" method="POST"><br />
<textarea name="textdata"><? io.write( form.value.msg ); ?></textarea><br />
<input type="submit" name="cmd" value="update"><br />
</form><br />
<br />
<br />
'''myapp-controller.lua:'''<br />
-- the myapp controller<br />
module (..., package.seeall) <br />
<br />
--- default code up here<br />
--- do not change anything except: self.conf.action for redirect<br />
local list_redir = function( self )<br />
self.conf.action = "myview"<br />
self.conf.type = "redir"<br />
error (self.conf)<br />
end<br />
<br />
local pvt = {}<br />
mvc= {}<br />
mvc.on_load = function( self, parent )<br />
if ( rawget(self.worker, self.conf.action) == nil ) then<br />
list_redir(self)<br />
end<br />
pvt.parent_on_exec = parent.worker.mvc.post_exec<br />
end<br />
<br />
-- This is where 'our' code starts<br />
<br />
myview = function( self )<br />
-- self.clientdata contains the data from the html form<br />
-- in your myapp-myview-html.lsp<br />
local clidat = self.clientdata <br />
<br />
-- user did submit the form (not just call the page)<br />
if clidat.cmd then<br />
if clidat.cmd == "update" then -- user pressed update button<br />
self.model.writefile( clidat.textdata )<br />
end<br />
end<br />
error, value = self.model.readfile()<br />
return cfe({ value = value })<br />
end<br />
<br />
<br />
'''myapp.menu:'''<br />
# Cat Group Tab Action<br />
Test MyApp MyView MyView<br />
<br />
===Step 6 - What Does It Do?===<br />
This program only just displays a &lt;textarea> box and a submit "update" button. The user can enter the which is saved into a file once he presses "update".<br />
<br />
====In Depth====<br />
Now let us have a closer look at what the different files' contents:<br />
<br />
=====myapp.menu=====<br />
In this file you define:<br />
* '''The Category''' in which a menu entry for your program will appear<br />
* '''The Group''', resp. the subheading's name under Category<br />
* '''The Action''' with-in your controller that will be called once the user klicks on the menu entry defined by Category and Group.<br />
<br />
=====myapp-controller.lua=====<br />
The controller is an event dispatcher. So in here you define all the actions that the user can call or that are defined in the menu. Each action is a separate function that will receive ''self'' as the only parameter.<br />
<br />
In our case the action is ''myview''.<br />
<br />
This function can call the ''model's'' functions to update and/or retrieve<br />
data (e.g. self.model.readfile()).<br />
<br />
Anything that this function returns will be passed on to the ''view''<br />
<br />
=====myapp-model.lua=====<br />
The functions defined in here can be accessed by the controller<br />
to update/set/retrieve data, start/stop services, basically do<br />
any 'real work'.<br />
<br />
=====myapp-myview-html.lsp=====</div>Macbrodyhttps://wiki.alpinelinux.org/w/index.php?title=ACF_how_to_write&diff=1875ACF how to write2007-11-17T09:39:38Z<p>Macbrody: /* myapp-controller.lua */</p>
<hr />
<div>=How to Write an ACF <span style="color:red"> Under Construction</span> =<br />
<br />
For some examples please see svn<br />
<br />
svn co svn://svn.alpinelinux.org/acf<br />
<br />
*shorewall<br />
*dhcp<br />
<br />
<br />
==From <nil> to a running ACF example application <span style="color:red">Under Construction</span>==<br />
<br />
===Step 1 - The Programming Language===<br />
* ACF uses lua as programming language. Have a look at lua.org [http://www.lua.org/] before starting.<br />
<br />
===Step 2 - The Development Environment===<br />
* Setup an ACF Development Environment: [[Getting_started_with_ACF_development]]<br />
<br />
===Step 3 - Create A Development Directory===<br />
Once you entered the ACF Development Environment as described in step 2:<br />
* in your user home create a directory for your application (e.g. mkdir ~/myapp)<br />
* and cd into it (e.g. cd ~/myapp)<br />
<br />
===Step 4 - MVC, How Does It Affect My Coding?===<br />
ACF is an MVC based framework. What does this mean to you? Your application is separated into three layers: Model, View, Controller - each of which has one or more files.<br />
* Model: In Model the 'real work' is done (e.g. modifying config files, starting/stopping services etc.)<br />
* View: This is where you define what your application will look like. You can have one or more files, each presenting a dynamic html page which only as much code as neccessary to format the data you retrieve from Model.<br />
* Controller: The event dispatcher. In controller you place one function per event. If the user calls the respective 'event page' (web), acf will fire an action - the same-named function in controller will be called. This function then retrieves neccessary data from Model and passes it to View to be displayed to the user.<br />
<br />
===Step 5 - The Example Files To Start With===<br />
Now let us have a look at the files we need to place into our application directory:<br />
<br />
* Makefile<br />
* config.mk<br />
* myapp-model.lua<br />
* myapp-myview-html.lsp<br />
* myapp-controller.lua<br />
* myapp.menu<br />
<br />
<br />
'''Makefile:'''<br />
<br />
The Makefile once called does install our acf application so that we can look at it working.<br />
APP_NAME=myapp<br />
PACKAGE=acf-$(APP_NAME)<br />
VERSION=1.0_alpha1<br />
<br />
APP_DIST=myapp-model.lua \<br />
myapp-myview-html.lsp \<br />
myapp-controller.lua \<br />
myapp.menu<br />
<br />
EXTRA_DIST=README Makefile config.mk<br />
<br />
DISTFILES=$(APP_DIST) $(EXTRA_DIST)<br />
<br />
TAR=tar<br />
<br />
P=$(PACKAGE)-$(VERSION)<br />
tarball=$(P).tar.bz2<br />
install_dir=$(DESTDIR)/$(appdir)/$(APP_NAME)<br />
<br />
all:<br />
clean:<br />
rm -rf $(tarball) $(P)<br />
<br />
dist: $(tarball)<br />
<br />
install:<br />
mkdir -p "$(install_dir)"<br />
cp -a $(APP_DIST) "$(install_dir)"<br />
<br />
$(tarball): $(DISTFILES)<br />
rm -rf $(P)<br />
mkdir -p $(P)<br />
cp $(DISTFILES) $(P)<br />
$(TAR) -jcf $@ $(P)<br />
rm -rf $(P)<br />
<br />
# target that creates a tar package, unpacks is and install from package<br />
dist-install: $(tarball)<br />
$(TAR) -jxf $(tarball)<br />
$(MAKE) -C $(P) install DESTDIR=$(DESTDIR)<br />
rm -rf $(P)<br />
<br />
include config.mk<br />
<br />
.PHONY: all clean dist install dist-install<br />
<br />
Remark: Should you create additional view files for example, don't forget to place their names in Makefile under APP_DIST otherwise they will not be installed later on and your application will fail with an error message.<br />
<br />
<br />
'''config.mk:'''<br />
For use with the Makefile. Just copy/paste it. We will look at it later.<br />
prefix=/usr<br />
datadir=${prefix}/share<br />
sysconfdir=${prefix}/etc<br />
localstatedir=${prefix}/var<br />
acfdir=${datadir}/acf<br />
wwwdir=${acfdir}/www<br />
cgibindir=${acfdir}/cgi-bin<br />
appdir=${acfdir}/app<br />
acflibdir=${acfdir}/lib<br />
sessionsdir=${localstatedir}/lib/acf/sessions<br />
<br />
<br />
'''myapp-model.lsp:'''<br />
-- acf model for myapp<br />
-- Copyright(c) 2007 <Your name here> - Licensed under terms of GPL2<br />
module (..., package.seeall)<br />
<br />
cfgfile = "/tmp/myfile"<br />
<br />
-- This function returns a cfe (table of values) containing the files'<br />
-- value as string and an error code. If the file does not exist, we'll<br />
-- simply return "" (an empty string, but NOT nil)<br />
readfile = function()<br />
retval = ""<br />
error = 0<br />
fileptr = io.open( cfgfile, "r" )<br />
if fileptr ~= nil then<br />
retval = fileptr:read( "*a" )<br />
if retval == nil then<br />
retval = ""<br />
end<br />
fileptr:close()<br />
end<br />
return error, cfe({ msg = retval })<br />
end<br />
<br />
-- This function will write new contents into our file<br />
writefile = function( newcontents )<br />
fileptr = io.open( cfgfile, "w+" )<br />
if fileptr ~= nil then<br />
fileptr:write( newcontents )<br />
fileptr:close()<br />
end<br />
return<br />
end<br />
<br />
<br />
'''myapp-myview-html.lsp:'''<br />
<?<br />
form = ...<br />
option = form.option<br />
?><br />
&lt;h1>MyApp - MyView&lt;/h1><br />
<form action="" method="POST"><br />
<textarea name="textdata"><? io.write( form.value.msg ); ?></textarea><br />
<input type="submit" name="cmd" value="update"><br />
</form><br />
<br />
<br />
'''myapp-controller.lua:'''<br />
-- the myapp controller<br />
module (..., package.seeall) <br />
<br />
--- default code up here<br />
--- do not change anything except: self.conf.action for redirect<br />
local list_redir = function( self )<br />
self.conf.action = "myview"<br />
self.conf.type = "redir"<br />
error (self.conf)<br />
end<br />
<br />
local pvt = {}<br />
mvc= {}<br />
mvc.on_load = function( self, parent )<br />
if ( rawget(self.worker, self.conf.action) == nil ) then<br />
list_redir(self)<br />
end<br />
pvt.parent_on_exec = parent.worker.mvc.post_exec<br />
end<br />
<br />
-- This is where 'our' code starts<br />
<br />
myview = function( self )<br />
-- self.clientdata contains the data from the html form<br />
-- in your myapp-myview-html.lsp<br />
local clidat = self.clientdata <br />
<br />
-- user did submit the form (not just call the page)<br />
if clidat.cmd then<br />
if clidat.cmd == "update" then -- user pressed update button<br />
self.model.writefile( clidat.textdata )<br />
end<br />
end<br />
error, value = self.model.readfile()<br />
return cfe({ value = value })<br />
end<br />
<br />
<br />
'''myapp.menu:'''<br />
# Cat Group Tab Action<br />
Test MyApp MyView MyView<br />
<br />
===Step 6 - What Does It Do?===<br />
This program only just displays a &lt;textarea> box and a submit "update" button. The user can enter the which is saved into a file once he presses "update".<br />
<br />
====In Depth====<br />
Now let us have a closer look at what the different files' contents:<br />
<br />
=====myapp.menu=====<br />
In this file you define:<br />
* '''The Category''' in which a menu entry for your program will appear<br />
* '''The Group''', resp. the subheading's name under Category<br />
* '''The Action''' with-in your controller that will be called once the user klicks on the menu entry defined by Category and Group.<br />
<br />
=====myapp-controller.lua=====<br />
The controller is an event dispatcher. So in here you define all the actions that the user can call or that are defined in the menu. Each action is a separate function that will receive ''self'' as the only parameter.<br />
<br />
In our case the action is ''myview''.<br />
<br />
This function can call the ''model's'' functions to update and/or retrieve<br />
data (e.g. self.model.readfile()).<br />
<br />
Anything that this function returns will be passed on to the ''view''<br />
<br />
=====myapp-model.lua=====<br />
<br />
=====myapp-myview-html.lsp=====</div>Macbrodyhttps://wiki.alpinelinux.org/w/index.php?title=ACF_how_to_write&diff=1874ACF how to write2007-11-17T09:37:34Z<p>Macbrody: /* myapp-controller.lua */</p>
<hr />
<div>=How to Write an ACF <span style="color:red"> Under Construction</span> =<br />
<br />
For some examples please see svn<br />
<br />
svn co svn://svn.alpinelinux.org/acf<br />
<br />
*shorewall<br />
*dhcp<br />
<br />
<br />
==From <nil> to a running ACF example application <span style="color:red">Under Construction</span>==<br />
<br />
===Step 1 - The Programming Language===<br />
* ACF uses lua as programming language. Have a look at lua.org [http://www.lua.org/] before starting.<br />
<br />
===Step 2 - The Development Environment===<br />
* Setup an ACF Development Environment: [[Getting_started_with_ACF_development]]<br />
<br />
===Step 3 - Create A Development Directory===<br />
Once you entered the ACF Development Environment as described in step 2:<br />
* in your user home create a directory for your application (e.g. mkdir ~/myapp)<br />
* and cd into it (e.g. cd ~/myapp)<br />
<br />
===Step 4 - MVC, How Does It Affect My Coding?===<br />
ACF is an MVC based framework. What does this mean to you? Your application is separated into three layers: Model, View, Controller - each of which has one or more files.<br />
* Model: In Model the 'real work' is done (e.g. modifying config files, starting/stopping services etc.)<br />
* View: This is where you define what your application will look like. You can have one or more files, each presenting a dynamic html page which only as much code as neccessary to format the data you retrieve from Model.<br />
* Controller: The event dispatcher. In controller you place one function per event. If the user calls the respective 'event page' (web), acf will fire an action - the same-named function in controller will be called. This function then retrieves neccessary data from Model and passes it to View to be displayed to the user.<br />
<br />
===Step 5 - The Example Files To Start With===<br />
Now let us have a look at the files we need to place into our application directory:<br />
<br />
* Makefile<br />
* config.mk<br />
* myapp-model.lua<br />
* myapp-myview-html.lsp<br />
* myapp-controller.lua<br />
* myapp.menu<br />
<br />
<br />
'''Makefile:'''<br />
<br />
The Makefile once called does install our acf application so that we can look at it working.<br />
APP_NAME=myapp<br />
PACKAGE=acf-$(APP_NAME)<br />
VERSION=1.0_alpha1<br />
<br />
APP_DIST=myapp-model.lua \<br />
myapp-myview-html.lsp \<br />
myapp-controller.lua \<br />
myapp.menu<br />
<br />
EXTRA_DIST=README Makefile config.mk<br />
<br />
DISTFILES=$(APP_DIST) $(EXTRA_DIST)<br />
<br />
TAR=tar<br />
<br />
P=$(PACKAGE)-$(VERSION)<br />
tarball=$(P).tar.bz2<br />
install_dir=$(DESTDIR)/$(appdir)/$(APP_NAME)<br />
<br />
all:<br />
clean:<br />
rm -rf $(tarball) $(P)<br />
<br />
dist: $(tarball)<br />
<br />
install:<br />
mkdir -p "$(install_dir)"<br />
cp -a $(APP_DIST) "$(install_dir)"<br />
<br />
$(tarball): $(DISTFILES)<br />
rm -rf $(P)<br />
mkdir -p $(P)<br />
cp $(DISTFILES) $(P)<br />
$(TAR) -jcf $@ $(P)<br />
rm -rf $(P)<br />
<br />
# target that creates a tar package, unpacks is and install from package<br />
dist-install: $(tarball)<br />
$(TAR) -jxf $(tarball)<br />
$(MAKE) -C $(P) install DESTDIR=$(DESTDIR)<br />
rm -rf $(P)<br />
<br />
include config.mk<br />
<br />
.PHONY: all clean dist install dist-install<br />
<br />
Remark: Should you create additional view files for example, don't forget to place their names in Makefile under APP_DIST otherwise they will not be installed later on and your application will fail with an error message.<br />
<br />
<br />
'''config.mk:'''<br />
For use with the Makefile. Just copy/paste it. We will look at it later.<br />
prefix=/usr<br />
datadir=${prefix}/share<br />
sysconfdir=${prefix}/etc<br />
localstatedir=${prefix}/var<br />
acfdir=${datadir}/acf<br />
wwwdir=${acfdir}/www<br />
cgibindir=${acfdir}/cgi-bin<br />
appdir=${acfdir}/app<br />
acflibdir=${acfdir}/lib<br />
sessionsdir=${localstatedir}/lib/acf/sessions<br />
<br />
<br />
'''myapp-model.lsp:'''<br />
-- acf model for myapp<br />
-- Copyright(c) 2007 <Your name here> - Licensed under terms of GPL2<br />
module (..., package.seeall)<br />
<br />
cfgfile = "/tmp/myfile"<br />
<br />
-- This function returns a cfe (table of values) containing the files'<br />
-- value as string and an error code. If the file does not exist, we'll<br />
-- simply return "" (an empty string, but NOT nil)<br />
readfile = function()<br />
retval = ""<br />
error = 0<br />
fileptr = io.open( cfgfile, "r" )<br />
if fileptr ~= nil then<br />
retval = fileptr:read( "*a" )<br />
if retval == nil then<br />
retval = ""<br />
end<br />
fileptr:close()<br />
end<br />
return error, cfe({ msg = retval })<br />
end<br />
<br />
-- This function will write new contents into our file<br />
writefile = function( newcontents )<br />
fileptr = io.open( cfgfile, "w+" )<br />
if fileptr ~= nil then<br />
fileptr:write( newcontents )<br />
fileptr:close()<br />
end<br />
return<br />
end<br />
<br />
<br />
'''myapp-myview-html.lsp:'''<br />
<?<br />
form = ...<br />
option = form.option<br />
?><br />
&lt;h1>MyApp - MyView&lt;/h1><br />
<form action="" method="POST"><br />
<textarea name="textdata"><? io.write( form.value.msg ); ?></textarea><br />
<input type="submit" name="cmd" value="update"><br />
</form><br />
<br />
<br />
'''myapp-controller.lua:'''<br />
-- the myapp controller<br />
module (..., package.seeall) <br />
<br />
--- default code up here<br />
--- do not change anything except: self.conf.action for redirect<br />
local list_redir = function( self )<br />
self.conf.action = "myview"<br />
self.conf.type = "redir"<br />
error (self.conf)<br />
end<br />
<br />
local pvt = {}<br />
mvc= {}<br />
mvc.on_load = function( self, parent )<br />
if ( rawget(self.worker, self.conf.action) == nil ) then<br />
list_redir(self)<br />
end<br />
pvt.parent_on_exec = parent.worker.mvc.post_exec<br />
end<br />
<br />
-- This is where 'our' code starts<br />
<br />
myview = function( self )<br />
-- self.clientdata contains the data from the html form<br />
-- in your myapp-myview-html.lsp<br />
local clidat = self.clientdata <br />
<br />
-- user did submit the form (not just call the page)<br />
if clidat.cmd then<br />
if clidat.cmd == "update" then -- user pressed update button<br />
self.model.writefile( clidat.textdata )<br />
end<br />
end<br />
error, value = self.model.readfile()<br />
return cfe({ value = value })<br />
end<br />
<br />
<br />
'''myapp.menu:'''<br />
# Cat Group Tab Action<br />
Test MyApp MyView MyView<br />
<br />
===Step 6 - What Does It Do?===<br />
This program only just displays a &lt;textarea> box and a submit "update" button. The user can enter the which is saved into a file once he presses "update".<br />
<br />
====In Depth====<br />
Now let us have a closer look at what the different files' contents:<br />
<br />
=====myapp.menu=====<br />
In this file you define:<br />
* '''The Category''' in which a menu entry for your program will appear<br />
* '''The Group''', resp. the subheading's name under Category<br />
* '''The Action''' with-in your controller that will be called once the user klicks on the menu entry defined by Category and Group.<br />
<br />
=====myapp-controller.lua=====<br />
The controller is an event dispatcher. So in here you define all the actions that the user can call or that are defined in the menu. Each action is a separate function that will receive ''self'' as the only parameter.<br />
<br />
In our case the action is ''myview''.<br />
<br />
=====myapp-model.lua=====<br />
<br />
=====myapp-myview-html.lsp=====</div>Macbrodyhttps://wiki.alpinelinux.org/w/index.php?title=ACF_how_to_write&diff=1873ACF how to write2007-11-17T09:36:16Z<p>Macbrody: /* myapp-controller.lua */</p>
<hr />
<div>=How to Write an ACF <span style="color:red"> Under Construction</span> =<br />
<br />
For some examples please see svn<br />
<br />
svn co svn://svn.alpinelinux.org/acf<br />
<br />
*shorewall<br />
*dhcp<br />
<br />
<br />
==From <nil> to a running ACF example application <span style="color:red">Under Construction</span>==<br />
<br />
===Step 1 - The Programming Language===<br />
* ACF uses lua as programming language. Have a look at lua.org [http://www.lua.org/] before starting.<br />
<br />
===Step 2 - The Development Environment===<br />
* Setup an ACF Development Environment: [[Getting_started_with_ACF_development]]<br />
<br />
===Step 3 - Create A Development Directory===<br />
Once you entered the ACF Development Environment as described in step 2:<br />
* in your user home create a directory for your application (e.g. mkdir ~/myapp)<br />
* and cd into it (e.g. cd ~/myapp)<br />
<br />
===Step 4 - MVC, How Does It Affect My Coding?===<br />
ACF is an MVC based framework. What does this mean to you? Your application is separated into three layers: Model, View, Controller - each of which has one or more files.<br />
* Model: In Model the 'real work' is done (e.g. modifying config files, starting/stopping services etc.)<br />
* View: This is where you define what your application will look like. You can have one or more files, each presenting a dynamic html page which only as much code as neccessary to format the data you retrieve from Model.<br />
* Controller: The event dispatcher. In controller you place one function per event. If the user calls the respective 'event page' (web), acf will fire an action - the same-named function in controller will be called. This function then retrieves neccessary data from Model and passes it to View to be displayed to the user.<br />
<br />
===Step 5 - The Example Files To Start With===<br />
Now let us have a look at the files we need to place into our application directory:<br />
<br />
* Makefile<br />
* config.mk<br />
* myapp-model.lua<br />
* myapp-myview-html.lsp<br />
* myapp-controller.lua<br />
* myapp.menu<br />
<br />
<br />
'''Makefile:'''<br />
<br />
The Makefile once called does install our acf application so that we can look at it working.<br />
APP_NAME=myapp<br />
PACKAGE=acf-$(APP_NAME)<br />
VERSION=1.0_alpha1<br />
<br />
APP_DIST=myapp-model.lua \<br />
myapp-myview-html.lsp \<br />
myapp-controller.lua \<br />
myapp.menu<br />
<br />
EXTRA_DIST=README Makefile config.mk<br />
<br />
DISTFILES=$(APP_DIST) $(EXTRA_DIST)<br />
<br />
TAR=tar<br />
<br />
P=$(PACKAGE)-$(VERSION)<br />
tarball=$(P).tar.bz2<br />
install_dir=$(DESTDIR)/$(appdir)/$(APP_NAME)<br />
<br />
all:<br />
clean:<br />
rm -rf $(tarball) $(P)<br />
<br />
dist: $(tarball)<br />
<br />
install:<br />
mkdir -p "$(install_dir)"<br />
cp -a $(APP_DIST) "$(install_dir)"<br />
<br />
$(tarball): $(DISTFILES)<br />
rm -rf $(P)<br />
mkdir -p $(P)<br />
cp $(DISTFILES) $(P)<br />
$(TAR) -jcf $@ $(P)<br />
rm -rf $(P)<br />
<br />
# target that creates a tar package, unpacks is and install from package<br />
dist-install: $(tarball)<br />
$(TAR) -jxf $(tarball)<br />
$(MAKE) -C $(P) install DESTDIR=$(DESTDIR)<br />
rm -rf $(P)<br />
<br />
include config.mk<br />
<br />
.PHONY: all clean dist install dist-install<br />
<br />
Remark: Should you create additional view files for example, don't forget to place their names in Makefile under APP_DIST otherwise they will not be installed later on and your application will fail with an error message.<br />
<br />
<br />
'''config.mk:'''<br />
For use with the Makefile. Just copy/paste it. We will look at it later.<br />
prefix=/usr<br />
datadir=${prefix}/share<br />
sysconfdir=${prefix}/etc<br />
localstatedir=${prefix}/var<br />
acfdir=${datadir}/acf<br />
wwwdir=${acfdir}/www<br />
cgibindir=${acfdir}/cgi-bin<br />
appdir=${acfdir}/app<br />
acflibdir=${acfdir}/lib<br />
sessionsdir=${localstatedir}/lib/acf/sessions<br />
<br />
<br />
'''myapp-model.lsp:'''<br />
-- acf model for myapp<br />
-- Copyright(c) 2007 <Your name here> - Licensed under terms of GPL2<br />
module (..., package.seeall)<br />
<br />
cfgfile = "/tmp/myfile"<br />
<br />
-- This function returns a cfe (table of values) containing the files'<br />
-- value as string and an error code. If the file does not exist, we'll<br />
-- simply return "" (an empty string, but NOT nil)<br />
readfile = function()<br />
retval = ""<br />
error = 0<br />
fileptr = io.open( cfgfile, "r" )<br />
if fileptr ~= nil then<br />
retval = fileptr:read( "*a" )<br />
if retval == nil then<br />
retval = ""<br />
end<br />
fileptr:close()<br />
end<br />
return error, cfe({ msg = retval })<br />
end<br />
<br />
-- This function will write new contents into our file<br />
writefile = function( newcontents )<br />
fileptr = io.open( cfgfile, "w+" )<br />
if fileptr ~= nil then<br />
fileptr:write( newcontents )<br />
fileptr:close()<br />
end<br />
return<br />
end<br />
<br />
<br />
'''myapp-myview-html.lsp:'''<br />
<?<br />
form = ...<br />
option = form.option<br />
?><br />
&lt;h1>MyApp - MyView&lt;/h1><br />
<form action="" method="POST"><br />
<textarea name="textdata"><? io.write( form.value.msg ); ?></textarea><br />
<input type="submit" name="cmd" value="update"><br />
</form><br />
<br />
<br />
'''myapp-controller.lua:'''<br />
-- the myapp controller<br />
module (..., package.seeall) <br />
<br />
--- default code up here<br />
--- do not change anything except: self.conf.action for redirect<br />
local list_redir = function( self )<br />
self.conf.action = "myview"<br />
self.conf.type = "redir"<br />
error (self.conf)<br />
end<br />
<br />
local pvt = {}<br />
mvc= {}<br />
mvc.on_load = function( self, parent )<br />
if ( rawget(self.worker, self.conf.action) == nil ) then<br />
list_redir(self)<br />
end<br />
pvt.parent_on_exec = parent.worker.mvc.post_exec<br />
end<br />
<br />
-- This is where 'our' code starts<br />
<br />
myview = function( self )<br />
-- self.clientdata contains the data from the html form<br />
-- in your myapp-myview-html.lsp<br />
local clidat = self.clientdata <br />
<br />
-- user did submit the form (not just call the page)<br />
if clidat.cmd then<br />
if clidat.cmd == "update" then -- user pressed update button<br />
self.model.writefile( clidat.textdata )<br />
end<br />
end<br />
error, value = self.model.readfile()<br />
return cfe({ value = value })<br />
end<br />
<br />
<br />
'''myapp.menu:'''<br />
# Cat Group Tab Action<br />
Test MyApp MyView MyView<br />
<br />
===Step 6 - What Does It Do?===<br />
This program only just displays a &lt;textarea> box and a submit "update" button. The user can enter the which is saved into a file once he presses "update".<br />
<br />
====In Depth====<br />
Now let us have a closer look at what the different files' contents:<br />
<br />
=====myapp.menu=====<br />
In this file you define:<br />
* '''The Category''' in which a menu entry for your program will appear<br />
* '''The Group''', resp. the subheading's name under Category<br />
* '''The Action''' with-in your controller that will be called once the user klicks on the menu entry defined by Category and Group.<br />
<br />
=====myapp-controller.lua=====<br />
The controller is an event dispatcher. So in here you define all the actions that the user can call or that are defined in the menu. Each action is a separate function that will receive ''self'' as the only parameter.<br />
<br />
=====myapp-model.lua=====<br />
<br />
=====myapp-myview-html.lsp=====</div>Macbrodyhttps://wiki.alpinelinux.org/w/index.php?title=ACF_how_to_write&diff=1872ACF how to write2007-11-17T09:30:52Z<p>Macbrody: /* myapp.menu */</p>
<hr />
<div>=How to Write an ACF <span style="color:red"> Under Construction</span> =<br />
<br />
For some examples please see svn<br />
<br />
svn co svn://svn.alpinelinux.org/acf<br />
<br />
*shorewall<br />
*dhcp<br />
<br />
<br />
==From <nil> to a running ACF example application <span style="color:red">Under Construction</span>==<br />
<br />
===Step 1 - The Programming Language===<br />
* ACF uses lua as programming language. Have a look at lua.org [http://www.lua.org/] before starting.<br />
<br />
===Step 2 - The Development Environment===<br />
* Setup an ACF Development Environment: [[Getting_started_with_ACF_development]]<br />
<br />
===Step 3 - Create A Development Directory===<br />
Once you entered the ACF Development Environment as described in step 2:<br />
* in your user home create a directory for your application (e.g. mkdir ~/myapp)<br />
* and cd into it (e.g. cd ~/myapp)<br />
<br />
===Step 4 - MVC, How Does It Affect My Coding?===<br />
ACF is an MVC based framework. What does this mean to you? Your application is separated into three layers: Model, View, Controller - each of which has one or more files.<br />
* Model: In Model the 'real work' is done (e.g. modifying config files, starting/stopping services etc.)<br />
* View: This is where you define what your application will look like. You can have one or more files, each presenting a dynamic html page which only as much code as neccessary to format the data you retrieve from Model.<br />
* Controller: The event dispatcher. In controller you place one function per event. If the user calls the respective 'event page' (web), acf will fire an action - the same-named function in controller will be called. This function then retrieves neccessary data from Model and passes it to View to be displayed to the user.<br />
<br />
===Step 5 - The Example Files To Start With===<br />
Now let us have a look at the files we need to place into our application directory:<br />
<br />
* Makefile<br />
* config.mk<br />
* myapp-model.lua<br />
* myapp-myview-html.lsp<br />
* myapp-controller.lua<br />
* myapp.menu<br />
<br />
<br />
'''Makefile:'''<br />
<br />
The Makefile once called does install our acf application so that we can look at it working.<br />
APP_NAME=myapp<br />
PACKAGE=acf-$(APP_NAME)<br />
VERSION=1.0_alpha1<br />
<br />
APP_DIST=myapp-model.lua \<br />
myapp-myview-html.lsp \<br />
myapp-controller.lua \<br />
myapp.menu<br />
<br />
EXTRA_DIST=README Makefile config.mk<br />
<br />
DISTFILES=$(APP_DIST) $(EXTRA_DIST)<br />
<br />
TAR=tar<br />
<br />
P=$(PACKAGE)-$(VERSION)<br />
tarball=$(P).tar.bz2<br />
install_dir=$(DESTDIR)/$(appdir)/$(APP_NAME)<br />
<br />
all:<br />
clean:<br />
rm -rf $(tarball) $(P)<br />
<br />
dist: $(tarball)<br />
<br />
install:<br />
mkdir -p "$(install_dir)"<br />
cp -a $(APP_DIST) "$(install_dir)"<br />
<br />
$(tarball): $(DISTFILES)<br />
rm -rf $(P)<br />
mkdir -p $(P)<br />
cp $(DISTFILES) $(P)<br />
$(TAR) -jcf $@ $(P)<br />
rm -rf $(P)<br />
<br />
# target that creates a tar package, unpacks is and install from package<br />
dist-install: $(tarball)<br />
$(TAR) -jxf $(tarball)<br />
$(MAKE) -C $(P) install DESTDIR=$(DESTDIR)<br />
rm -rf $(P)<br />
<br />
include config.mk<br />
<br />
.PHONY: all clean dist install dist-install<br />
<br />
Remark: Should you create additional view files for example, don't forget to place their names in Makefile under APP_DIST otherwise they will not be installed later on and your application will fail with an error message.<br />
<br />
<br />
'''config.mk:'''<br />
For use with the Makefile. Just copy/paste it. We will look at it later.<br />
prefix=/usr<br />
datadir=${prefix}/share<br />
sysconfdir=${prefix}/etc<br />
localstatedir=${prefix}/var<br />
acfdir=${datadir}/acf<br />
wwwdir=${acfdir}/www<br />
cgibindir=${acfdir}/cgi-bin<br />
appdir=${acfdir}/app<br />
acflibdir=${acfdir}/lib<br />
sessionsdir=${localstatedir}/lib/acf/sessions<br />
<br />
<br />
'''myapp-model.lsp:'''<br />
-- acf model for myapp<br />
-- Copyright(c) 2007 <Your name here> - Licensed under terms of GPL2<br />
module (..., package.seeall)<br />
<br />
cfgfile = "/tmp/myfile"<br />
<br />
-- This function returns a cfe (table of values) containing the files'<br />
-- value as string and an error code. If the file does not exist, we'll<br />
-- simply return "" (an empty string, but NOT nil)<br />
readfile = function()<br />
retval = ""<br />
error = 0<br />
fileptr = io.open( cfgfile, "r" )<br />
if fileptr ~= nil then<br />
retval = fileptr:read( "*a" )<br />
if retval == nil then<br />
retval = ""<br />
end<br />
fileptr:close()<br />
end<br />
return error, cfe({ msg = retval })<br />
end<br />
<br />
-- This function will write new contents into our file<br />
writefile = function( newcontents )<br />
fileptr = io.open( cfgfile, "w+" )<br />
if fileptr ~= nil then<br />
fileptr:write( newcontents )<br />
fileptr:close()<br />
end<br />
return<br />
end<br />
<br />
<br />
'''myapp-myview-html.lsp:'''<br />
<?<br />
form = ...<br />
option = form.option<br />
?><br />
&lt;h1>MyApp - MyView&lt;/h1><br />
<form action="" method="POST"><br />
<textarea name="textdata"><? io.write( form.value.msg ); ?></textarea><br />
<input type="submit" name="cmd" value="update"><br />
</form><br />
<br />
<br />
'''myapp-controller.lua:'''<br />
-- the myapp controller<br />
module (..., package.seeall) <br />
<br />
--- default code up here<br />
--- do not change anything except: self.conf.action for redirect<br />
local list_redir = function( self )<br />
self.conf.action = "myview"<br />
self.conf.type = "redir"<br />
error (self.conf)<br />
end<br />
<br />
local pvt = {}<br />
mvc= {}<br />
mvc.on_load = function( self, parent )<br />
if ( rawget(self.worker, self.conf.action) == nil ) then<br />
list_redir(self)<br />
end<br />
pvt.parent_on_exec = parent.worker.mvc.post_exec<br />
end<br />
<br />
-- This is where 'our' code starts<br />
<br />
myview = function( self )<br />
-- self.clientdata contains the data from the html form<br />
-- in your myapp-myview-html.lsp<br />
local clidat = self.clientdata <br />
<br />
-- user did submit the form (not just call the page)<br />
if clidat.cmd then<br />
if clidat.cmd == "update" then -- user pressed update button<br />
self.model.writefile( clidat.textdata )<br />
end<br />
end<br />
error, value = self.model.readfile()<br />
return cfe({ value = value })<br />
end<br />
<br />
<br />
'''myapp.menu:'''<br />
# Cat Group Tab Action<br />
Test MyApp MyView MyView<br />
<br />
===Step 6 - What Does It Do?===<br />
This program only just displays a &lt;textarea> box and a submit "update" button. The user can enter the which is saved into a file once he presses "update".<br />
<br />
====In Depth====<br />
Now let us have a closer look at what the different files' contents:<br />
<br />
=====myapp.menu=====<br />
In this file you define:<br />
* '''The Category''' in which a menu entry for your program will appear<br />
* '''The Group''', resp. the subheading's name under Category<br />
* '''The Action''' with-in your controller that will be called once the user klicks on the menu entry defined by Category and Group.<br />
<br />
=====myapp-controller.lua=====<br />
<br />
=====myapp-model.lua=====<br />
<br />
=====myapp-myview-html.lsp=====</div>Macbrodyhttps://wiki.alpinelinux.org/w/index.php?title=ACF_how_to_write&diff=1871ACF how to write2007-11-17T09:26:29Z<p>Macbrody: </p>
<hr />
<div>=How to Write an ACF <span style="color:red"> Under Construction</span> =<br />
<br />
For some examples please see svn<br />
<br />
svn co svn://svn.alpinelinux.org/acf<br />
<br />
*shorewall<br />
*dhcp<br />
<br />
<br />
==From <nil> to a running ACF example application <span style="color:red">Under Construction</span>==<br />
<br />
===Step 1 - The Programming Language===<br />
* ACF uses lua as programming language. Have a look at lua.org [http://www.lua.org/] before starting.<br />
<br />
===Step 2 - The Development Environment===<br />
* Setup an ACF Development Environment: [[Getting_started_with_ACF_development]]<br />
<br />
===Step 3 - Create A Development Directory===<br />
Once you entered the ACF Development Environment as described in step 2:<br />
* in your user home create a directory for your application (e.g. mkdir ~/myapp)<br />
* and cd into it (e.g. cd ~/myapp)<br />
<br />
===Step 4 - MVC, How Does It Affect My Coding?===<br />
ACF is an MVC based framework. What does this mean to you? Your application is separated into three layers: Model, View, Controller - each of which has one or more files.<br />
* Model: In Model the 'real work' is done (e.g. modifying config files, starting/stopping services etc.)<br />
* View: This is where you define what your application will look like. You can have one or more files, each presenting a dynamic html page which only as much code as neccessary to format the data you retrieve from Model.<br />
* Controller: The event dispatcher. In controller you place one function per event. If the user calls the respective 'event page' (web), acf will fire an action - the same-named function in controller will be called. This function then retrieves neccessary data from Model and passes it to View to be displayed to the user.<br />
<br />
===Step 5 - The Example Files To Start With===<br />
Now let us have a look at the files we need to place into our application directory:<br />
<br />
* Makefile<br />
* config.mk<br />
* myapp-model.lua<br />
* myapp-myview-html.lsp<br />
* myapp-controller.lua<br />
* myapp.menu<br />
<br />
<br />
'''Makefile:'''<br />
<br />
The Makefile once called does install our acf application so that we can look at it working.<br />
APP_NAME=myapp<br />
PACKAGE=acf-$(APP_NAME)<br />
VERSION=1.0_alpha1<br />
<br />
APP_DIST=myapp-model.lua \<br />
myapp-myview-html.lsp \<br />
myapp-controller.lua \<br />
myapp.menu<br />
<br />
EXTRA_DIST=README Makefile config.mk<br />
<br />
DISTFILES=$(APP_DIST) $(EXTRA_DIST)<br />
<br />
TAR=tar<br />
<br />
P=$(PACKAGE)-$(VERSION)<br />
tarball=$(P).tar.bz2<br />
install_dir=$(DESTDIR)/$(appdir)/$(APP_NAME)<br />
<br />
all:<br />
clean:<br />
rm -rf $(tarball) $(P)<br />
<br />
dist: $(tarball)<br />
<br />
install:<br />
mkdir -p "$(install_dir)"<br />
cp -a $(APP_DIST) "$(install_dir)"<br />
<br />
$(tarball): $(DISTFILES)<br />
rm -rf $(P)<br />
mkdir -p $(P)<br />
cp $(DISTFILES) $(P)<br />
$(TAR) -jcf $@ $(P)<br />
rm -rf $(P)<br />
<br />
# target that creates a tar package, unpacks is and install from package<br />
dist-install: $(tarball)<br />
$(TAR) -jxf $(tarball)<br />
$(MAKE) -C $(P) install DESTDIR=$(DESTDIR)<br />
rm -rf $(P)<br />
<br />
include config.mk<br />
<br />
.PHONY: all clean dist install dist-install<br />
<br />
Remark: Should you create additional view files for example, don't forget to place their names in Makefile under APP_DIST otherwise they will not be installed later on and your application will fail with an error message.<br />
<br />
<br />
'''config.mk:'''<br />
For use with the Makefile. Just copy/paste it. We will look at it later.<br />
prefix=/usr<br />
datadir=${prefix}/share<br />
sysconfdir=${prefix}/etc<br />
localstatedir=${prefix}/var<br />
acfdir=${datadir}/acf<br />
wwwdir=${acfdir}/www<br />
cgibindir=${acfdir}/cgi-bin<br />
appdir=${acfdir}/app<br />
acflibdir=${acfdir}/lib<br />
sessionsdir=${localstatedir}/lib/acf/sessions<br />
<br />
<br />
'''myapp-model.lsp:'''<br />
-- acf model for myapp<br />
-- Copyright(c) 2007 <Your name here> - Licensed under terms of GPL2<br />
module (..., package.seeall)<br />
<br />
cfgfile = "/tmp/myfile"<br />
<br />
-- This function returns a cfe (table of values) containing the files'<br />
-- value as string and an error code. If the file does not exist, we'll<br />
-- simply return "" (an empty string, but NOT nil)<br />
readfile = function()<br />
retval = ""<br />
error = 0<br />
fileptr = io.open( cfgfile, "r" )<br />
if fileptr ~= nil then<br />
retval = fileptr:read( "*a" )<br />
if retval == nil then<br />
retval = ""<br />
end<br />
fileptr:close()<br />
end<br />
return error, cfe({ msg = retval })<br />
end<br />
<br />
-- This function will write new contents into our file<br />
writefile = function( newcontents )<br />
fileptr = io.open( cfgfile, "w+" )<br />
if fileptr ~= nil then<br />
fileptr:write( newcontents )<br />
fileptr:close()<br />
end<br />
return<br />
end<br />
<br />
<br />
'''myapp-myview-html.lsp:'''<br />
<?<br />
form = ...<br />
option = form.option<br />
?><br />
&lt;h1>MyApp - MyView&lt;/h1><br />
<form action="" method="POST"><br />
<textarea name="textdata"><? io.write( form.value.msg ); ?></textarea><br />
<input type="submit" name="cmd" value="update"><br />
</form><br />
<br />
<br />
'''myapp-controller.lua:'''<br />
-- the myapp controller<br />
module (..., package.seeall) <br />
<br />
--- default code up here<br />
--- do not change anything except: self.conf.action for redirect<br />
local list_redir = function( self )<br />
self.conf.action = "myview"<br />
self.conf.type = "redir"<br />
error (self.conf)<br />
end<br />
<br />
local pvt = {}<br />
mvc= {}<br />
mvc.on_load = function( self, parent )<br />
if ( rawget(self.worker, self.conf.action) == nil ) then<br />
list_redir(self)<br />
end<br />
pvt.parent_on_exec = parent.worker.mvc.post_exec<br />
end<br />
<br />
-- This is where 'our' code starts<br />
<br />
myview = function( self )<br />
-- self.clientdata contains the data from the html form<br />
-- in your myapp-myview-html.lsp<br />
local clidat = self.clientdata <br />
<br />
-- user did submit the form (not just call the page)<br />
if clidat.cmd then<br />
if clidat.cmd == "update" then -- user pressed update button<br />
self.model.writefile( clidat.textdata )<br />
end<br />
end<br />
error, value = self.model.readfile()<br />
return cfe({ value = value })<br />
end<br />
<br />
<br />
'''myapp.menu:'''<br />
# Cat Group Tab Action<br />
Test MyApp MyView MyView<br />
<br />
===Step 6 - What Does It Do?===<br />
This program only just displays a &lt;textarea> box and a submit "update" button. The user can enter the which is saved into a file once he presses "update".<br />
<br />
====In Depth====<br />
Now let us have a closer look at what the different files' contents:<br />
<br />
=====myapp.menu=====<br />
<br />
=====myapp-controller.lua=====<br />
<br />
=====myapp-model.lua=====<br />
<br />
=====myapp-myview-html.lsp=====</div>Macbrodyhttps://wiki.alpinelinux.org/w/index.php?title=ACF_how_to_write&diff=1870ACF how to write2007-11-17T09:22:06Z<p>Macbrody: </p>
<hr />
<div>=How to Write an ACF <span style="color:red"> Under Construction</span> =<br />
<br />
For some examples please see svn<br />
<br />
svn co svn://svn.alpinelinux.org/acf<br />
<br />
*shorewall<br />
*dhcp<br />
<br />
<br />
==From <nil> to a running ACF example application <span style="color:red">Under Construction</span>==<br />
<br />
===Step 1 - The Programming Language===<br />
* ACF uses lua as programming language. Have a look at lua.org [http://www.lua.org/] before starting.<br />
<br />
===Step 2 - The Development Environment===<br />
* Setup an ACF Development Environment: [[Getting_started_with_ACF_development]]<br />
<br />
===Step 3 - Create A Development Directory===<br />
Once you entered the ACF Development Environment as described in step 2:<br />
* in your user home create a directory for your application (e.g. mkdir ~/myapp)<br />
* and cd into it (e.g. cd ~/myapp)<br />
<br />
===Step 4 - MVC, How Does It Affect My Coding?===<br />
ACF is an MVC based framework. What does this mean to you? Your application is separated into three layers: Model, View, Controller - each of which has one or more files.<br />
* Model: In Model the 'real work' is done (e.g. modifying config files, starting/stopping services etc.)<br />
* View: This is where you define what your application will look like. You can have one or more files, each presenting a dynamic html page which only as much code as neccessary to format the data you retrieve from Model.<br />
* Controller: The event dispatcher. In controller you place one function per event. If the user calls the respective 'event page' (web), acf will fire an action - the same-named function in controller will be called. This function then retrieves neccessary data from Model and passes it to View to be displayed to the user.<br />
<br />
===Step 5 - The Example Files To Start With===<br />
Now let us have a look at the files we need to place into our application directory:<br />
<br />
* Makefile<br />
* config.mk<br />
* myapp-model.lua<br />
* myapp-myview-html.lsp<br />
* myapp-controller.lua<br />
* myapp.menu<br />
<br />
<br />
'''Makefile:'''<br />
<br />
The Makefile once called does install our acf application so that we can look at it working.<br />
APP_NAME=myapp<br />
PACKAGE=acf-$(APP_NAME)<br />
VERSION=1.0_alpha1<br />
<br />
APP_DIST=myapp-model.lua \<br />
myapp-myview-html.lsp \<br />
myapp-controller.lua \<br />
myapp.menu<br />
<br />
EXTRA_DIST=README Makefile config.mk<br />
<br />
DISTFILES=$(APP_DIST) $(EXTRA_DIST)<br />
<br />
TAR=tar<br />
<br />
P=$(PACKAGE)-$(VERSION)<br />
tarball=$(P).tar.bz2<br />
install_dir=$(DESTDIR)/$(appdir)/$(APP_NAME)<br />
<br />
all:<br />
clean:<br />
rm -rf $(tarball) $(P)<br />
<br />
dist: $(tarball)<br />
<br />
install:<br />
mkdir -p "$(install_dir)"<br />
cp -a $(APP_DIST) "$(install_dir)"<br />
<br />
$(tarball): $(DISTFILES)<br />
rm -rf $(P)<br />
mkdir -p $(P)<br />
cp $(DISTFILES) $(P)<br />
$(TAR) -jcf $@ $(P)<br />
rm -rf $(P)<br />
<br />
# target that creates a tar package, unpacks is and install from package<br />
dist-install: $(tarball)<br />
$(TAR) -jxf $(tarball)<br />
$(MAKE) -C $(P) install DESTDIR=$(DESTDIR)<br />
rm -rf $(P)<br />
<br />
include config.mk<br />
<br />
.PHONY: all clean dist install dist-install<br />
<br />
Remark: Should you create additional view files for example, don't forget to place their names in Makefile under APP_DIST otherwise they will not be installed later on and your application will fail with an error message.<br />
<br />
<br />
'''config.mk:'''<br />
For use with the Makefile. Just copy/paste it. We will look at it later.<br />
prefix=/usr<br />
datadir=${prefix}/share<br />
sysconfdir=${prefix}/etc<br />
localstatedir=${prefix}/var<br />
acfdir=${datadir}/acf<br />
wwwdir=${acfdir}/www<br />
cgibindir=${acfdir}/cgi-bin<br />
appdir=${acfdir}/app<br />
acflibdir=${acfdir}/lib<br />
sessionsdir=${localstatedir}/lib/acf/sessions<br />
<br />
<br />
'''myapp-model.lsp:'''<br />
-- acf model for myapp<br />
-- Copyright(c) 2007 <Your name here> - Licensed under terms of GPL2<br />
module (..., package.seeall)<br />
<br />
cfgfile = "/tmp/myfile"<br />
<br />
-- This function returns a cfe (table of values) containing the files'<br />
-- value as string and an error code. If the file does not exist, we'll<br />
-- simply return "" (an empty string, but NOT nil)<br />
readfile = function()<br />
retval = ""<br />
error = 0<br />
fileptr = io.open( cfgfile, "r" )<br />
if fileptr ~= nil then<br />
retval = fileptr:read( "*a" )<br />
if retval == nil then<br />
retval = ""<br />
end<br />
fileptr:close()<br />
end<br />
return error, cfe({ msg = retval })<br />
end<br />
<br />
-- This function will write new contents into our file<br />
writefile = function( newcontents )<br />
fileptr = io.open( cfgfile, "w+" )<br />
if fileptr ~= nil then<br />
fileptr:write( newcontents )<br />
fileptr:close()<br />
end<br />
return<br />
end<br />
<br />
<br />
'''myapp-myview-html.lsp:'''<br />
<?<br />
form = ...<br />
option = form.option<br />
?><br />
&lt;h1>MyApp - MyView&lt;/h1><br />
<form action="" method="POST"><br />
<textarea name="textdata"><? io.write( form.value.msg ); ?></textarea><br />
<input type="submit" name="cmd" value="update"><br />
</form><br />
<br />
<br />
'''myapp-controller.lua:'''<br />
-- the myapp controller<br />
module (..., package.seeall) <br />
<br />
--- default code up here<br />
--- do not change anything except: self.conf.action for redirect<br />
local list_redir = function( self )<br />
self.conf.action = "myview"<br />
self.conf.type = "redir"<br />
error (self.conf)<br />
end<br />
<br />
local pvt = {}<br />
mvc= {}<br />
mvc.on_load = function( self, parent )<br />
if ( rawget(self.worker, self.conf.action) == nil ) then<br />
list_redir(self)<br />
end<br />
pvt.parent_on_exec = parent.worker.mvc.post_exec<br />
end<br />
<br />
-- This is where 'our' code starts<br />
<br />
myview = function( self )<br />
-- self.clientdata contains the data from the html form<br />
-- in your myapp-myview-html.lsp<br />
local clidat = self.clientdata <br />
<br />
-- user did submit the form (not just call the page)<br />
if clidat.cmd then<br />
if clidat.cmd == "update" then -- user pressed update button<br />
self.model.writefile( clidat.textdata )<br />
end<br />
end<br />
error, value = self.model.readfile()<br />
return cfe({ value = value })<br />
end<br />
<br />
<br />
'''myapp.menu:'''<br />
# Cat Group Tab Action<br />
Test MyApp MyView MyView</div>Macbrodyhttps://wiki.alpinelinux.org/w/index.php?title=ACF_how_to_write&diff=1869ACF how to write2007-11-17T09:20:50Z<p>Macbrody: </p>
<hr />
<div>=How to Write an ACF <span style="color:red"> Under Construction</span> =<br />
<br />
For some examples please see svn<br />
<br />
svn co svn://svn.alpinelinux.org/acf<br />
<br />
*shorewall<br />
*dhcp<br />
<br />
<br />
==From <nil> to a running ACF example application <span style="color:red">Under Construction</span>==<br />
<br />
===Step 1 - The Programming Language===<br />
* ACF uses lua as programming language. Have a look at lua.org [http://www.lua.org/] before starting.<br />
<br />
===Step 2 - The Development Environment===<br />
* Setup an ACF Development Environment: [[Getting_started_with_ACF_development]]<br />
<br />
===Step 3 - Create A Development Directory===<br />
Once you entered the ACF Development Environment as described in step 2:<br />
* in your user home create a directory for your application (e.g. mkdir ~/myapp)<br />
* and cd into it (e.g. cd ~/myapp)<br />
<br />
===Step 4 - MVC, How Does It Affect My Coding?===<br />
ACF is an MVC based framework. What does this mean to you? Your application is separated into three layers: Model, View, Controller - each of which has one or more files.<br />
* Model: In Model the 'real work' is done (e.g. modifying config files, starting/stopping services etc.)<br />
* View: This is where you define what your application will look like. You can have one or more files, each presenting a dynamic html page which only as much code as neccessary to format the data you retrieve from Model.<br />
* Controller: The event dispatcher. In controller you place one function per event. If the user calls the respective 'event page' (web), acf will fire an action - the same-named function in controller will be called. This function then retrieves neccessary data from Model and passes it to View to be displayed to the user.<br />
<br />
===Step 5 - The Example Files To Start With===<br />
Now let us have a look at the files we need to place into our application directory:<br />
<br />
* Makefile<br />
* config.mk<br />
* myapp-model.lua<br />
* myapp-myview-html.lsp<br />
* myapp-controller.lua<br />
* myapp.menu<br />
<br />
<br />
'''Makefile:'''<br />
<br />
The Makefile once called does install our acf application so that we can look at it working.<br />
APP_NAME=myapp<br />
PACKAGE=acf-$(APP_NAME)<br />
VERSION=1.0_alpha1<br />
<br />
APP_DIST=myapp-model.lua \<br />
myapp-myview-html.lsp \<br />
myapp-controller.lua \<br />
myapp.menu<br />
<br />
EXTRA_DIST=README Makefile config.mk<br />
<br />
DISTFILES=$(APP_DIST) $(EXTRA_DIST)<br />
<br />
TAR=tar<br />
<br />
P=$(PACKAGE)-$(VERSION)<br />
tarball=$(P).tar.bz2<br />
install_dir=$(DESTDIR)/$(appdir)/$(APP_NAME)<br />
<br />
all:<br />
clean:<br />
rm -rf $(tarball) $(P)<br />
<br />
dist: $(tarball)<br />
<br />
install:<br />
mkdir -p "$(install_dir)"<br />
cp -a $(APP_DIST) "$(install_dir)"<br />
<br />
$(tarball): $(DISTFILES)<br />
rm -rf $(P)<br />
mkdir -p $(P)<br />
cp $(DISTFILES) $(P)<br />
$(TAR) -jcf $@ $(P)<br />
rm -rf $(P)<br />
<br />
# target that creates a tar package, unpacks is and install from package<br />
dist-install: $(tarball)<br />
$(TAR) -jxf $(tarball)<br />
$(MAKE) -C $(P) install DESTDIR=$(DESTDIR)<br />
rm -rf $(P)<br />
<br />
include config.mk<br />
<br />
.PHONY: all clean dist install dist-install<br />
<br />
Remark: Should you create additional view files for example, don't forget to place their names in Makefile under APP_DIST otherwise they will not be installed later on and your application will fail with an error message.<br />
<br />
<br />
'''config.mk:'''<br />
For use with the Makefile. Just copy/paste it. We will look at it later.<br />
prefix=/usr<br />
datadir=${prefix}/share<br />
sysconfdir=${prefix}/etc<br />
localstatedir=${prefix}/var<br />
acfdir=${datadir}/acf<br />
wwwdir=${acfdir}/www<br />
cgibindir=${acfdir}/cgi-bin<br />
appdir=${acfdir}/app<br />
acflibdir=${acfdir}/lib<br />
sessionsdir=${localstatedir}/lib/acf/sessions<br />
<br />
<br />
'''myapp-model.lsp:'''<br />
-- acf model for myapp<br />
-- Copyright(c) 2007 <Your name here> - Licensed under terms of GPL2<br />
module (..., package.seeall)<br />
<br />
cfgfile = "/tmp/myfile"<br />
<br />
-- This function returns a cfe (table of values) containing the files'<br />
-- value as string and an error code. If the file does not exist, we'll<br />
-- simply return "" (an empty string, but NOT nil)<br />
readfile = function()<br />
retval = ""<br />
error = 0<br />
fileptr = io.open( cfgfile, "r" )<br />
if fileptr ~= nil then<br />
retval = fileptr:read( "*a" )<br />
if retval == nil then<br />
retval = ""<br />
end<br />
fileptr:close()<br />
end<br />
return error, cfe({ msg = retval })<br />
end<br />
<br />
-- This function will write new contents into our file<br />
writefile = function( newcontents )<br />
fileptr = io.open( cfgfile, "w+" )<br />
if fileptr ~= nil then<br />
fileptr:write( newcontents )<br />
fileptr:close()<br />
end<br />
return<br />
end<br />
<br />
<br />
'''myapp-myview-html.lsp:'''<br />
<?<br />
form = ...<br />
option = form.option<br />
?><br />
&lt;h1>MyApp - MyView&lt;/h1><br />
<form action="" method="POST"><br />
<textarea name="textdata"><? io.write( form.value.msg ); ?></textarea><br />
<input type="submit" name="cmd" value="update"><br />
</form><br />
<br />
<br />
'''myapp-controller.lua:'''<br />
-- the myapp controller<br />
module (..., package.seeall) <br />
<br />
--- default code up here<br />
--- do not change anything except: self.conf.action for redirect<br />
local list_redir = function( self )<br />
self.conf.action = "myview"<br />
self.conf.type = "redir"<br />
error (self.conf)<br />
end<br />
<br />
local pvt = {}<br />
mvc= {}<br />
mvc.on_load = function( self, parent )<br />
if ( rawget(self.worker, self.conf.action) == nil ) then<br />
list_redir(self)<br />
end<br />
pvt.parent_on_exec = parent.worker.mvc.post_exec<br />
end<br />
<br />
-- This is where 'our' code starts<br />
<br />
myview = function( self )<br />
-- self.clientdata contains the data from the html form<br />
-- in your myapp-myview-html.lsp<br />
local clidat = self.clientdata <br />
<br />
-- user did submit the form (not just call the page)<br />
if clidat.cmd then<br />
if clidat.cmd == "update" then -- user pressed update button<br />
self.model.writefile( clidat.textdata )<br />
end<br />
end<br />
error, value = self.model.readfile()<br />
return cfe({ value = value })<br />
end</div>Macbrodyhttps://wiki.alpinelinux.org/w/index.php?title=ACF_how_to_write&diff=1868ACF how to write2007-11-17T09:19:58Z<p>Macbrody: </p>
<hr />
<div>=How to Write an ACF <span style="color:red"> Under Construction</span> =<br />
<br />
For some examples please see svn<br />
<br />
svn co svn://svn.alpinelinux.org/acf<br />
<br />
*shorewall<br />
*dhcp<br />
<br />
<br />
==From <nil> to a running ACF example application <span style="color:red">Under Construction</span>==<br />
<br />
===Step 1 - The Programming Language===<br />
* ACF uses lua as programming language. Have a look at lua.org [http://www.lua.org/] before starting.<br />
<br />
===Step 2 - The Development Environment===<br />
* Setup an ACF Development Environment: [[Getting_started_with_ACF_development]]<br />
<br />
===Step 3 - Create A Development Directory===<br />
Once you entered the ACF Development Environment as described in step 2:<br />
* in your user home create a directory for your application (e.g. mkdir ~/myapp)<br />
* and cd into it (e.g. cd ~/myapp)<br />
<br />
===Step 4 - MVC, How Does It Affect My Coding?===<br />
ACF is an MVC based framework. What does this mean to you? Your application is separated into three layers: Model, View, Controller - each of which has one or more files.<br />
* Model: In Model the 'real work' is done (e.g. modifying config files, starting/stopping services etc.)<br />
* View: This is where you define what your application will look like. You can have one or more files, each presenting a dynamic html page which only as much code as neccessary to format the data you retrieve from Model.<br />
* Controller: The event dispatcher. In controller you place one function per event. If the user calls the respective 'event page' (web), acf will fire an action - the same-named function in controller will be called. This function then retrieves neccessary data from Model and passes it to View to be displayed to the user.<br />
<br />
===Step 5 - The Example Files To Start With===<br />
Now let us have a look at the files we need to place into our application directory:<br />
<br />
* Makefile<br />
* config.mk<br />
* myapp-model.lua<br />
* myapp-myview-html.lsp<br />
* myapp-controller.lua<br />
* myapp.menu<br />
<br />
<br />
'''Makefile:'''<br />
<br />
The Makefile once called does install our acf application so that we can look at it working.<br />
APP_NAME=myapp<br />
PACKAGE=acf-$(APP_NAME)<br />
VERSION=1.0_alpha1<br />
<br />
APP_DIST=myapp-model.lua \<br />
myapp-myview-html.lsp \<br />
myapp-controller.lua \<br />
myapp.menu<br />
<br />
EXTRA_DIST=README Makefile config.mk<br />
<br />
DISTFILES=$(APP_DIST) $(EXTRA_DIST)<br />
<br />
TAR=tar<br />
<br />
P=$(PACKAGE)-$(VERSION)<br />
tarball=$(P).tar.bz2<br />
install_dir=$(DESTDIR)/$(appdir)/$(APP_NAME)<br />
<br />
all:<br />
clean:<br />
rm -rf $(tarball) $(P)<br />
<br />
dist: $(tarball)<br />
<br />
install:<br />
mkdir -p "$(install_dir)"<br />
cp -a $(APP_DIST) "$(install_dir)"<br />
<br />
$(tarball): $(DISTFILES)<br />
rm -rf $(P)<br />
mkdir -p $(P)<br />
cp $(DISTFILES) $(P)<br />
$(TAR) -jcf $@ $(P)<br />
rm -rf $(P)<br />
<br />
# target that creates a tar package, unpacks is and install from package<br />
dist-install: $(tarball)<br />
$(TAR) -jxf $(tarball)<br />
$(MAKE) -C $(P) install DESTDIR=$(DESTDIR)<br />
rm -rf $(P)<br />
<br />
include config.mk<br />
<br />
.PHONY: all clean dist install dist-install<br />
<br />
Remark: Should you create additional view files for example, don't forget to place their names in Makefile under APP_DIST otherwise they will not be installed later on and your application will fail with an error message.<br />
<br />
<br />
'''config.mk:'''<br />
For use with the Makefile. Just copy/paste it. We will look at it later.<br />
prefix=/usr<br />
datadir=${prefix}/share<br />
sysconfdir=${prefix}/etc<br />
localstatedir=${prefix}/var<br />
acfdir=${datadir}/acf<br />
wwwdir=${acfdir}/www<br />
cgibindir=${acfdir}/cgi-bin<br />
appdir=${acfdir}/app<br />
acflibdir=${acfdir}/lib<br />
sessionsdir=${localstatedir}/lib/acf/sessions<br />
<br />
<br />
'''myapp-model.lsp:'''<br />
-- acf model for myapp<br />
-- Copyright(c) 2007 <Your name here> - Licensed under terms of GPL2<br />
module (..., package.seeall)<br />
<br />
cfgfile = "/tmp/myfile"<br />
<br />
-- This function returns a cfe (table of values) containing the files'<br />
-- value as string and an error code. If the file does not exist, we'll<br />
-- simply return "" (an empty string, but NOT nil)<br />
readfile = function()<br />
retval = ""<br />
error = 0<br />
fileptr = io.open( cfgfile, "r" )<br />
if fileptr ~= nil then<br />
retval = fileptr:read( "*a" )<br />
if retval == nil then<br />
retval = ""<br />
end<br />
fileptr:close()<br />
end<br />
return error, cfe({ msg = retval })<br />
end<br />
<br />
-- This function will write new contents into our file<br />
writefile = function( newcontents )<br />
fileptr = io.open( cfgfile, "w+" )<br />
if fileptr ~= nil then<br />
fileptr:write( newcontents )<br />
fileptr:close()<br />
end<br />
return<br />
end<br />
<br />
<br />
'''myapp-myview-html.lsp:'''<br />
<?<br />
form = ...<br />
option = form.option<br />
?><br />
<h1>MyApp - MyView</h1><br />
<form action="" method="POST"><br />
<textarea name="textdata"><? io.write( form.value.msg ); ?></textarea><br />
<input type="submit" name="cmd" value="update"><br />
</form><br />
<br />
<br />
'''myapp-controller.lua:'''<br />
-- the myapp controller<br />
module (..., package.seeall) <br />
<br />
--- default code up here<br />
--- do not change anything except: self.conf.action for redirect<br />
local list_redir = function( self )<br />
self.conf.action = "myview"<br />
self.conf.type = "redir"<br />
error (self.conf)<br />
end<br />
<br />
local pvt = {}<br />
mvc= {}<br />
mvc.on_load = function( self, parent )<br />
if ( rawget(self.worker, self.conf.action) == nil ) then<br />
list_redir(self)<br />
end<br />
pvt.parent_on_exec = parent.worker.mvc.post_exec<br />
end<br />
<br />
-- This is where 'our' code starts<br />
<br />
myview = function( self )<br />
-- self.clientdata contains the data from the html form<br />
-- in your myapp-myview-html.lsp<br />
local clidat = self.clientdata <br />
<br />
-- user did submit the form (not just call the page)<br />
if clidat.cmd then<br />
if clidat.cmd == "update" then -- user pressed update button<br />
self.model.writefile( clidat.textdata )<br />
end<br />
end<br />
error, value = self.model.readfile()<br />
return cfe({ value = value })<br />
end</div>Macbrodyhttps://wiki.alpinelinux.org/w/index.php?title=ACF_how_to_write&diff=1867ACF how to write2007-11-17T09:01:31Z<p>Macbrody: </p>
<hr />
<div>=How to Write an ACF <span style="color:red"> Under Construction</span> =<br />
<br />
For some examples please see svn<br />
<br />
svn co svn://svn.alpinelinux.org/acf<br />
<br />
*shorewall<br />
*dhcp<br />
<br />
<br />
==From <nil> to a running ACF example application <span style="color:red">Under Construction</span>==<br />
<br />
===Step 1 - The Programming Language===<br />
* ACF uses lua as programming language. Have a look at lua.org [http://www.lua.org/] before starting.<br />
<br />
===Step 2 - The Development Environment===<br />
* Setup an ACF Development Environment: [[Getting_started_with_ACF_development]]<br />
<br />
===Step 3 - Create A Development Directory===<br />
Once you entered the ACF Development Environment as described in step 2:<br />
* in your user home create a directory for your application (e.g. mkdir ~/myapp)<br />
* and cd into it (e.g. cd ~/myapp)<br />
<br />
===Step 4 - MVC, How Does It Affect My Coding?===<br />
ACF is an MVC based framework. What does this mean to you? Your application is separated into three layers: Model, View, Controller - each of which has one or more files.<br />
* Model: In Model the 'real work' is done (e.g. modifying config files, starting/stopping services etc.)<br />
* View: This is where you define what your application will look like. You can have one or more files, each presenting a dynamic html page which only as much code as neccessary to format the data you retrieve from Model.<br />
* Controller: The event dispatcher. In controller you place one function per event. If the user calls the respective 'event page' (web), acf will fire an action - the same-named function in controller will be called. This function then retrieves neccessary data from Model and passes it to View to be displayed to the user.<br />
<br />
===Step 5 - The Example Files To Start With===<br />
Now let us have a look at the files we need to place into our application directory:<br />
<br />
* Makefile<br />
* config.mk<br />
* myapp-model.lua<br />
* myapp-myview-html.lsp<br />
* myapp-controller.lua<br />
* myapp.menu<br />
<br />
<br />
'''Makefile:'''<br />
<br />
The Makefile once called does install our acf application so that we can look at it working.<br />
APP_NAME=myapp<br />
PACKAGE=acf-$(APP_NAME)<br />
VERSION=1.0_alpha1<br />
<br />
APP_DIST=myapp-model.lua \<br />
myapp-myview-html.lsp \<br />
myapp-controller.lua \<br />
myapp.menu<br />
<br />
EXTRA_DIST=README Makefile config.mk<br />
<br />
DISTFILES=$(APP_DIST) $(EXTRA_DIST)<br />
<br />
TAR=tar<br />
<br />
P=$(PACKAGE)-$(VERSION)<br />
tarball=$(P).tar.bz2<br />
install_dir=$(DESTDIR)/$(appdir)/$(APP_NAME)<br />
<br />
all:<br />
clean:<br />
rm -rf $(tarball) $(P)<br />
<br />
dist: $(tarball)<br />
<br />
install:<br />
mkdir -p "$(install_dir)"<br />
cp -a $(APP_DIST) "$(install_dir)"<br />
<br />
$(tarball): $(DISTFILES)<br />
rm -rf $(P)<br />
mkdir -p $(P)<br />
cp $(DISTFILES) $(P)<br />
$(TAR) -jcf $@ $(P)<br />
rm -rf $(P)<br />
<br />
# target that creates a tar package, unpacks is and install from package<br />
dist-install: $(tarball)<br />
$(TAR) -jxf $(tarball)<br />
$(MAKE) -C $(P) install DESTDIR=$(DESTDIR)<br />
rm -rf $(P)<br />
<br />
include config.mk<br />
<br />
.PHONY: all clean dist install dist-install<br />
<br />
Remark: Should you create additional view files for example, don't forget to place their names in Makefile under APP_DIST otherwise they will not be installed later on and your application will fail with an error message.<br />
<br />
<br />
'''config.mk:'''<br />
For use with the Makefile. Just copy/paste it. We will look at it later.<br />
prefix=/usr<br />
datadir=${prefix}/share<br />
sysconfdir=${prefix}/etc<br />
localstatedir=${prefix}/var<br />
acfdir=${datadir}/acf<br />
wwwdir=${acfdir}/www<br />
cgibindir=${acfdir}/cgi-bin<br />
appdir=${acfdir}/app<br />
acflibdir=${acfdir}/lib<br />
sessionsdir=${localstatedir}/lib/acf/sessions<br />
<br />
<br />
'''myapp-myview-html.lsp:'''<br />
-- acf model for myapp<br />
-- Copyright(c) 2007 <Your name here> - Licensed under terms of GPL2<br />
module (..., package.seeall)<br />
<br />
cfgfile = "/tmp/myfile"<br />
<br />
-- This function returns a cfe (table of values) containing the files'<br />
-- value as string and an error code. If the file does not exist, we'll<br />
-- simply return "" (an empty string, but NOT nil)<br />
readfile = function()<br />
retval = ""<br />
error = 0<br />
fileptr = io.open( cfgfile, "r" )<br />
if fileptr ~= nil then<br />
retval = fileptr:read( "*a" )<br />
if retval == nil then<br />
retval = ""<br />
end<br />
fileptr:close()<br />
end<br />
return error, cfe({ msg = retval })<br />
end<br />
<br />
-- This function will write new contents into our file<br />
writefile = function( newcontents )<br />
fileptr = io.open( cfgfile, "w+" )<br />
if fileptr ~= nil then<br />
fileptr:write( newcontents )<br />
fileptr:close()<br />
end<br />
return<br />
end</div>Macbrodyhttps://wiki.alpinelinux.org/w/index.php?title=ACF_how_to_write&diff=1866ACF how to write2007-11-17T08:52:55Z<p>Macbrody: </p>
<hr />
<div>=How to Write an ACF <span style="color:red"> Under Construction</span> =<br />
<br />
For some examples please see svn<br />
<br />
svn co svn://svn.alpinelinux.org/acf<br />
<br />
*shorewall<br />
*dhcp<br />
<br />
<br />
==From <nil> to a running ACF example application <span style="color:red">Under Construction</span>==<br />
<br />
===Step 1 - The Programming Language===<br />
* ACF uses lua as programming language. Have a look at lua.org [http://www.lua.org/] before starting.<br />
<br />
===Step 2 - The Development Environment===<br />
* Setup an ACF Development Environment: [[Getting_started_with_ACF_development]]<br />
<br />
===Step 3 - Create A Development Directory===<br />
Once you entered the ACF Development Environment as described in step 2:<br />
* in your user home create a directory for your application (e.g. mkdir ~/myapp)<br />
* and cd into it (e.g. cd ~/myapp)<br />
<br />
===Step 4 - MVC, How Does It Affect My Coding?===<br />
ACF is an MVC based framework. What does this mean to you? Your application is separated into three layers: Model, View, Controller - each of which has one or more files.<br />
* Model: In Model the 'real work' is done (e.g. modifying config files, starting/stopping services etc.)<br />
* View: This is where you define what your application will look like. You can have one or more files, each presenting a dynamic html page which only as much code as neccessary to format the data you retrieve from Model.<br />
* Controller: The event dispatcher. In controller you place one function per event. If the user calls the respective 'event page' (web), acf will fire an action - the same-named function in controller will be called. This function then retrieves neccessary data from Model and passes it to View to be displayed to the user.<br />
<br />
===Step 5 - The Example Files To Start With===<br />
Now let us have a look at the files we need to place into our application directory:<br />
<br />
* Makefile<br />
* config.mk<br />
* myapp-model.lua<br />
* myapp-myview-html.lsp<br />
* myapp-controller.lua<br />
* myapp.menu<br />
<br />
<br />
'''Makefile:'''<br />
<br />
The Makefile once called does install our acf application so that we can look at it working.<br />
APP_NAME=myapp<br />
PACKAGE=acf-$(APP_NAME)<br />
VERSION=1.0_alpha1<br />
<br />
APP_DIST=myapp-model.lua \<br />
myapp-myview-html.lsp \<br />
myapp-controller.lua \<br />
myapp.menu<br />
<br />
EXTRA_DIST=README Makefile config.mk<br />
<br />
DISTFILES=$(APP_DIST) $(EXTRA_DIST)<br />
<br />
TAR=tar<br />
<br />
P=$(PACKAGE)-$(VERSION)<br />
tarball=$(P).tar.bz2<br />
install_dir=$(DESTDIR)/$(appdir)/$(APP_NAME)<br />
<br />
all:<br />
clean:<br />
rm -rf $(tarball) $(P)<br />
<br />
dist: $(tarball)<br />
<br />
install:<br />
mkdir -p "$(install_dir)"<br />
cp -a $(APP_DIST) "$(install_dir)"<br />
<br />
$(tarball): $(DISTFILES)<br />
rm -rf $(P)<br />
mkdir -p $(P)<br />
cp $(DISTFILES) $(P)<br />
$(TAR) -jcf $@ $(P)<br />
rm -rf $(P)<br />
<br />
# target that creates a tar package, unpacks is and install from package<br />
dist-install: $(tarball)<br />
$(TAR) -jxf $(tarball)<br />
$(MAKE) -C $(P) install DESTDIR=$(DESTDIR)<br />
rm -rf $(P)<br />
<br />
include config.mk<br />
<br />
.PHONY: all clean dist install dist-install<br />
<br />
Remark: Should you create additional view files for example, don't forget to place their names in Makefile under APP_DIST otherwise they will not be installed later on and your application will fail with an error message.<br />
<br />
<br />
'''config.mk:'''<br />
For use with the Makefile. Just copy/paste it. We will look at it later.<br />
prefix=/usr<br />
datadir=${prefix}/share<br />
sysconfdir=${prefix}/etc<br />
localstatedir=${prefix}/var<br />
acfdir=${datadir}/acf<br />
wwwdir=${acfdir}/www<br />
cgibindir=${acfdir}/cgi-bin<br />
appdir=${acfdir}/app<br />
acflibdir=${acfdir}/lib<br />
sessionsdir=${localstatedir}/lib/acf/sessions<br />
<br />
<br />
'''myapp-myview-html.lsp:'''<br />
-- acf model for myapp<br />
-- Copyright(c) 2007 <Your name here> - Licensed under terms of GPL2<br />
module (..., package.seeall)<br />
<br />
cfgfile = "/tmp/myfile"<br />
<br />
# This function returns a cfe (table of values) containing the files'<br />
# value as string and an error code. If the file does not exist, we'll<br />
# simply return "" (an empty string, but NOT nil)<br />
readfile = function()<br />
retval = ""<br />
error = 0<br />
fileptr = io.open( cfgfile, "r" )<br />
if fileptr ~= nil then<br />
retval = fileptr:read( "*a" )<br />
if retval == nil then<br />
retval = ""<br />
end<br />
fileptr:close()<br />
end<br />
return error, cfe({ msg = retval })<br />
end<br />
<br />
# This function will write new contents into our file<br />
writefile = function( newcontents )<br />
fileptr = io.open( cfgfile, "w+" )<br />
if fileptr ~= nil then<br />
fileptr:write( newcontents )<br />
fileptr:close()<br />
end<br />
return<br />
end</div>Macbrodyhttps://wiki.alpinelinux.org/w/index.php?title=ACF_how_to_write&diff=1865ACF how to write2007-11-17T08:45:53Z<p>Macbrody: </p>
<hr />
<div>=How to Write an ACF <span style="color:red"> Under Construction</span> =<br />
<br />
For some examples please see svn<br />
<br />
svn co svn://svn.alpinelinux.org/acf<br />
<br />
*shorewall<br />
*dhcp<br />
<br />
<br />
==From <nil> to a running ACF example application <span style="color:red">Under Construction</span>==<br />
<br />
===Step 1 - The Programming Language===<br />
* ACF uses lua as programming language. Have a look at lua.org [http://www.lua.org/] before starting.<br />
<br />
===Step 2 - The Development Environment===<br />
* Setup an ACF Development Environment: [[Getting_started_with_ACF_development]]<br />
<br />
===Step 3 - Create A Development Directory===<br />
Once you entered the ACF Development Environment as described in step 2:<br />
* in your user home create a directory for your application (e.g. mkdir ~/myapp)<br />
* and cd into it (e.g. cd ~/myapp)<br />
<br />
===Step 4 - MVC, How Does It Affect My Coding?===<br />
ACF is an MVC based framework. What does this mean to you? Your application is separated into three layers: Model, View, Controller - each of which has one or more files.<br />
* Model: In Model the 'real work' is done (e.g. modifying config files, starting/stopping services etc.)<br />
* View: This is where you define what your application will look like. You can have one or more files, each presenting a dynamic html page which only as much code as neccessary to format the data you retrieve from Model.<br />
* Controller: The event dispatcher. In controller you place one function per event. If the user calls the respective 'event page' (web), acf will fire an action - the same-named function in controller will be called. This function then retrieves neccessary data from Model and passes it to View to be displayed to the user.<br />
<br />
===Step 5 - The Example Files To Start With===<br />
Now let us have a look at the files we need to place into our application directory:<br />
<br />
* Makefile<br />
* config.mk<br />
* myapp-model.lua<br />
* myapp-myview-html.lsp<br />
* myapp-controller.lua<br />
* myapp.menu<br />
<br />
<br />
'''Makefile:'''<br />
<br />
The Makefile once called does install our acf application so that we can look at it working.<br />
APP_NAME=myapp<br />
PACKAGE=acf-$(APP_NAME)<br />
VERSION=1.0_alpha1<br />
<br />
APP_DIST=myapp-model.lua \<br />
myapp-myview-html.lsp \<br />
myapp-controller.lua \<br />
myapp.menu<br />
<br />
EXTRA_DIST=README Makefile config.mk<br />
<br />
DISTFILES=$(APP_DIST) $(EXTRA_DIST)<br />
<br />
TAR=tar<br />
<br />
P=$(PACKAGE)-$(VERSION)<br />
tarball=$(P).tar.bz2<br />
install_dir=$(DESTDIR)/$(appdir)/$(APP_NAME)<br />
<br />
all:<br />
clean:<br />
rm -rf $(tarball) $(P)<br />
<br />
dist: $(tarball)<br />
<br />
install:<br />
mkdir -p "$(install_dir)"<br />
cp -a $(APP_DIST) "$(install_dir)"<br />
<br />
$(tarball): $(DISTFILES)<br />
rm -rf $(P)<br />
mkdir -p $(P)<br />
cp $(DISTFILES) $(P)<br />
$(TAR) -jcf $@ $(P)<br />
rm -rf $(P)<br />
<br />
# target that creates a tar package, unpacks is and install from package<br />
dist-install: $(tarball)<br />
$(TAR) -jxf $(tarball)<br />
$(MAKE) -C $(P) install DESTDIR=$(DESTDIR)<br />
rm -rf $(P)<br />
<br />
include config.mk<br />
<br />
.PHONY: all clean dist install dist-install<br />
<br />
Remark: Should you create additional view files for example, don't forget to place their names in Makefile under APP_DIST otherwise they will not be installed later on and your application will fail with an error message.<br />
<br />
<br />
'''config.mk:'''<br />
For use with the Makefile. Just copy/paste it. We will look at it later.<br />
prefix=/usr<br />
datadir=${prefix}/share<br />
sysconfdir=${prefix}/etc<br />
localstatedir=${prefix}/var<br />
acfdir=${datadir}/acf<br />
wwwdir=${acfdir}/www<br />
cgibindir=${acfdir}/cgi-bin<br />
appdir=${acfdir}/app<br />
acflibdir=${acfdir}/lib<br />
sessionsdir=${localstatedir}/lib/acf/sessions<br />
<br />
<br />
'''myapp-myview-html.lsp:'''<br />
-- acf model for myapp<br />
-- Copyright(c) 2007 <Your name here> - Licensed under terms of GPL2<br />
module (..., package.seeall)<br />
<br />
cfgfile = "/tmp/myfile"<br />
<br />
# This function returns a cfe (table of values) containing the files'<br />
# value as string and an error code. If the file does not exist, we'll<br />
# simply return "" (an empty string, but NOT nil)<br />
readfile = function()<br />
retval = ""<br />
fileptr = io.open( cfgfile, "r" )<br />
if fileptr ~= nil then<br />
retval = fileptr:read( "*a" )<br />
if retval == nil then<br />
retval = ""<br />
end<br />
fileptr:close()<br />
end<br />
return cfe({ error = 0, msg = retval })<br />
end<br />
<br />
# This function will write new contents into our file<br />
writefile = function( newcontents )<br />
fileptr = io.open( cfgfile, "w+" )<br />
if fileptr ~= nil then<br />
fileptr:write( newcontents )<br />
fileptr:close()<br />
end<br />
return<br />
end</div>Macbrodyhttps://wiki.alpinelinux.org/w/index.php?title=ACF_how_to_write&diff=1864ACF how to write2007-11-17T08:33:57Z<p>Macbrody: </p>
<hr />
<div>=How to Write an ACF <span style="color:red"> Under Construction</span> =<br />
<br />
For some examples please see svn<br />
<br />
svn co svn://svn.alpinelinux.org/acf<br />
<br />
*shorewall<br />
*dhcp<br />
<br />
<br />
==From <nil> to a running ACF example application <span style="color:red">Under Construction</span>==<br />
<br />
===Step 1 - The Programming Language===<br />
* ACF uses lua as programming language. Have a look at lua.org [http://www.lua.org/] before starting.<br />
<br />
===Step 2 - The Development Environment===<br />
* Setup an ACF Development Environment: [[Getting_started_with_ACF_development]]<br />
<br />
===Step 3 - Create A Development Directory===<br />
Once you entered the ACF Development Environment as described in step 2:<br />
* in your user home create a directory for your application (e.g. mkdir ~/myapp)<br />
* and cd into it (e.g. cd ~/myapp)<br />
<br />
===Step 4 - MVC, How Does It Affect My Coding?===<br />
ACF is an MVC based framework. What does this mean to you? Your application is separated into three layers: Model, View, Controller - each of which has one or more files.<br />
* Model: In Model the 'real work' is done (e.g. modifying config files, starting/stopping services etc.)<br />
* View: This is where you define what your application will look like. You can have one or more files, each presenting a dynamic html page which only as much code as neccessary to format the data you retrieve from Model.<br />
* Controller: The event dispatcher. In controller you place one function per event. If the user calls the respective 'event page' (web), acf will fire an action - the same-named function in controller will be called. This function then retrieves neccessary data from Model and passes it to View to be displayed to the user.<br />
<br />
===Step 5 - The Example Files To Start With===<br />
Now let us have a look at the files we need to place into our application directory:<br />
<br />
* Makefile<br />
* config.mk<br />
* myapp-model.lua<br />
* myapp-myview-html.lsp<br />
* myapp-controller.lua<br />
* myapp.menu<br />
<br />
<br />
'''Makefile:'''<br />
<br />
The Makefile once called does install our acf application so that we can look at it working.<br />
APP_NAME=myapp<br />
PACKAGE=acf-$(APP_NAME)<br />
VERSION=1.0_alpha1<br />
<br />
APP_DIST=myapp-model.lua \<br />
myapp-myview-html.lsp \<br />
myapp-controller.lua \<br />
myapp.menu<br />
<br />
EXTRA_DIST=README Makefile config.mk<br />
<br />
DISTFILES=$(APP_DIST) $(EXTRA_DIST)<br />
<br />
TAR=tar<br />
<br />
P=$(PACKAGE)-$(VERSION)<br />
tarball=$(P).tar.bz2<br />
install_dir=$(DESTDIR)/$(appdir)/$(APP_NAME)<br />
<br />
all:<br />
clean:<br />
rm -rf $(tarball) $(P)<br />
<br />
dist: $(tarball)<br />
<br />
install:<br />
mkdir -p "$(install_dir)"<br />
cp -a $(APP_DIST) "$(install_dir)"<br />
<br />
$(tarball): $(DISTFILES)<br />
rm -rf $(P)<br />
mkdir -p $(P)<br />
cp $(DISTFILES) $(P)<br />
$(TAR) -jcf $@ $(P)<br />
rm -rf $(P)<br />
<br />
# target that creates a tar package, unpacks is and install from package<br />
dist-install: $(tarball)<br />
$(TAR) -jxf $(tarball)<br />
$(MAKE) -C $(P) install DESTDIR=$(DESTDIR)<br />
rm -rf $(P)<br />
<br />
include config.mk<br />
<br />
.PHONY: all clean dist install dist-install<br />
<br />
Remark: Should you create additional view files for example, don't forget to place their names in Makefile under APP_DIST otherwise they will not be installed later on and your application will fail with an error message.<br />
<br />
<br />
'''config.mk:'''<br />
For use with the Makefile. Just copy/paste it. We will look at it later.<br />
prefix=/usr<br />
datadir=${prefix}/share<br />
sysconfdir=${prefix}/etc<br />
localstatedir=${prefix}/var<br />
acfdir=${datadir}/acf<br />
wwwdir=${acfdir}/www<br />
cgibindir=${acfdir}/cgi-bin<br />
appdir=${acfdir}/app<br />
acflibdir=${acfdir}/lib<br />
sessionsdir=${localstatedir}/lib/acf/sessions<br />
<br />
<br />
'''myapp-mymodel.lsp:'''</div>Macbrodyhttps://wiki.alpinelinux.org/w/index.php?title=ACF_how_to_write&diff=1863ACF how to write2007-11-17T08:31:53Z<p>Macbrody: </p>
<hr />
<div>=How to Write an ACF <span style="color:red"> Under Construction</span> =<br />
<br />
For some examples please see svn<br />
<br />
svn co svn://svn.alpinelinux.org/acf<br />
<br />
*shorewall<br />
*dhcp<br />
<br />
<br />
==From <nil> to a running ACF example application <span style="color:red">Under Construction</span>==<br />
<br />
===Step 1 - The Programming Language===<br />
* ACF uses lua as programming language. Have a look at lua.org [http://www.lua.org/] before starting.<br />
<br />
===Step 2 - The Development Environment===<br />
* Setup an ACF Development Environment: [[Getting_started_with_ACF_development]]<br />
<br />
===Step 3 - Create A Development Directory===<br />
Once you entered the ACF Development Environment as described in step 2:<br />
* in your user home create a directory for your application (e.g. mkdir ~/myapp)<br />
* and cd into it (e.g. cd ~/myapp)<br />
<br />
===Step 4 - MVC, How Does It Affect My Coding?===<br />
ACF is an MVC based framework. What does this mean to you? Your application is separated into three layers: Model, View, Controller - each of which has one or more files.<br />
* Model: In Model the 'real work' is done (e.g. modifying config files, starting/stopping services etc.)<br />
* View: This is where you define what your application will look like. You can have one or more files, each presenting a dynamic html page which only as much code as neccessary to format the data you retrieve from Model.<br />
* Controller: The event dispatcher. In controller you place one function per event. If the user calls the respective 'event page' (web), acf will fire an action - the same-named function in controller will be called. This function then retrieves neccessary data from Model and passes it to View to be displayed to the user.<br />
<br />
===Step 5 - The Example Files To Start With===<br />
Now let us have a look at the files we need to place into our application directory:<br />
<br />
* Makefile<br />
* config.mk<br />
* myapp-model.lua<br />
* myapp-myview-html.lsp<br />
* myapp-controller.lua<br />
* myapp.menu<br />
<br />
<br />
'''Makefile:'''<br />
<br />
The Makefile once called does install our acf application so that we can look at it working.<br />
APP_NAME=myapp<br />
PACKAGE=acf-$(APP_NAME)<br />
VERSION=1.0_alpha1<br />
<br />
APP_DIST=myapp-model.lua \<br />
myapp-myview-html.lsp \<br />
myapp-controller.lua \<br />
myapp.menu<br />
<br />
EXTRA_DIST=README Makefile config.mk<br />
<br />
DISTFILES=$(APP_DIST) $(EXTRA_DIST)<br />
<br />
TAR=tar<br />
<br />
P=$(PACKAGE)-$(VERSION)<br />
tarball=$(P).tar.bz2<br />
install_dir=$(DESTDIR)/$(appdir)/$(APP_NAME)<br />
<br />
all:<br />
clean:<br />
rm -rf $(tarball) $(P)<br />
<br />
dist: $(tarball)<br />
<br />
install:<br />
mkdir -p "$(install_dir)"<br />
cp -a $(APP_DIST) "$(install_dir)"<br />
<br />
$(tarball): $(DISTFILES)<br />
rm -rf $(P)<br />
mkdir -p $(P)<br />
cp $(DISTFILES) $(P)<br />
$(TAR) -jcf $@ $(P)<br />
rm -rf $(P)<br />
<br />
# target that creates a tar package, unpacks is and install from package<br />
dist-install: $(tarball)<br />
$(TAR) -jxf $(tarball)<br />
$(MAKE) -C $(P) install DESTDIR=$(DESTDIR)<br />
rm -rf $(P)<br />
<br />
include config.mk<br />
<br />
.PHONY: all clean dist install dist-install<br />
<br />
Remark: Should you create additional view files for example, don't forget to place their names in Makefile under APP_DIST otherwise they will not be installed later on and your application will fail with an error message.<br />
<br />
<br />
'''config.mk:'''<br />
For use with the Makefile. Just copy/paste it. We will look at it later.<br />
prefix=/usr<br />
datadir=${prefix}/share<br />
sysconfdir=${prefix}/etc<br />
localstatedir=${prefix}/var<br />
acfdir=${datadir}/acf<br />
wwwdir=${acfdir}/www<br />
cgibindir=${acfdir}/cgi-bin<br />
appdir=${acfdir}/app<br />
acflibdir=${acfdir}/lib<br />
sessionsdir=${localstatedir}/lib/acf/sessions</div>Macbrodyhttps://wiki.alpinelinux.org/w/index.php?title=ACF_how_to_write&diff=1862ACF how to write2007-11-17T08:29:53Z<p>Macbrody: /* Step 5 */</p>
<hr />
<div>=How to Write an ACF <span style="color:red"> Under Construction</span> =<br />
<br />
For some examples please see svn<br />
<br />
svn co svn://svn.alpinelinux.org/acf<br />
<br />
*shorewall<br />
*dhcp<br />
<br />
<br />
==From <nil> to a running ACF example application <span style="color:red">Under Construction</span>==<br />
<br />
===Step 1 - The Programming Language===<br />
* ACF uses lua as programming language. Have a look at lua.org [http://www.lua.org/] before starting.<br />
<br />
===Step 2 - The Development Environment===<br />
* Setup an ACF Development Environment: [[Getting_started_with_ACF_development]]<br />
<br />
===Step 3 - Create A Development Directory===<br />
Once you entered the ACF Development Environment as described in step 2:<br />
* in your user home create a directory for your application (e.g. mkdir ~/myapp)<br />
* and cd into it (e.g. cd ~/myapp)<br />
<br />
===Step 4 - MVC, How Does It Affect My Coding?===<br />
ACF is an MVC based framework. What does this mean to you? Your application is separated into three layers: Model, View, Controller - each of which has one or more files.<br />
* Model: In Model the 'real work' is done (e.g. modifying config files, starting/stopping services etc.)<br />
* View: This is where you define what your application will look like. You can have one or more files, each presenting a dynamic html page which only as much code as neccessary to format the data you retrieve from Model.<br />
* Controller: The event dispatcher. In controller you place one function per event. If the user calls the respective 'event page' (web), acf will fire an action - the same-named function in controller will be called. This function then retrieves neccessary data from Model and passes it to View to be displayed to the user.<br />
<br />
===Step 5 - The Example Files To Start With===<br />
Now let us have a look at the files we need to place into our application directory:<br />
<br />
* Makefile<br />
* config.mk<br />
* myapp-model.lua<br />
* myapp-view-html.lsp<br />
* myapp-controller.lua<br />
* myapp.menu<br />
<br />
<br />
'''Makefile:'''<br />
<br />
The Makefile once called does install our acf application so that we can look at it working.<br />
APP_NAME=myapp<br />
PACKAGE=acf-$(APP_NAME)<br />
VERSION=1.0_alpha1<br />
<br />
APP_DIST=myapp-model.lua \<br />
myapp-view-html.lsp \<br />
myapp-controller.lua \<br />
myapp.menu<br />
<br />
EXTRA_DIST=README Makefile config.mk<br />
<br />
DISTFILES=$(APP_DIST) $(EXTRA_DIST)<br />
<br />
TAR=tar<br />
<br />
P=$(PACKAGE)-$(VERSION)<br />
tarball=$(P).tar.bz2<br />
install_dir=$(DESTDIR)/$(appdir)/$(APP_NAME)<br />
<br />
all:<br />
clean:<br />
rm -rf $(tarball) $(P)<br />
<br />
dist: $(tarball)<br />
<br />
install:<br />
mkdir -p "$(install_dir)"<br />
cp -a $(APP_DIST) "$(install_dir)"<br />
<br />
$(tarball): $(DISTFILES)<br />
rm -rf $(P)<br />
mkdir -p $(P)<br />
cp $(DISTFILES) $(P)<br />
$(TAR) -jcf $@ $(P)<br />
rm -rf $(P)<br />
<br />
# target that creates a tar package, unpacks is and install from package<br />
dist-install: $(tarball)<br />
$(TAR) -jxf $(tarball)<br />
$(MAKE) -C $(P) install DESTDIR=$(DESTDIR)<br />
rm -rf $(P)<br />
<br />
include config.mk<br />
<br />
.PHONY: all clean dist install dist-install<br />
<br />
Remark: Should you create additional view files for example, don't forget to place their names in Makefile under APP_DIST otherwise they will not be installed later on and your application will fail with an error message.<br />
<br />
<br />
'''config.mk:'''<br />
For use with the Makefile. Just copy/paste it. We will look at it later.<br />
prefix=/usr<br />
datadir=${prefix}/share<br />
sysconfdir=${prefix}/etc<br />
localstatedir=${prefix}/var<br />
acfdir=${datadir}/acf<br />
wwwdir=${acfdir}/www<br />
cgibindir=${acfdir}/cgi-bin<br />
appdir=${acfdir}/app<br />
acflibdir=${acfdir}/lib<br />
sessionsdir=${localstatedir}/lib/acf/sessions</div>Macbrodyhttps://wiki.alpinelinux.org/w/index.php?title=ACF_how_to_write&diff=1861ACF how to write2007-11-17T08:29:09Z<p>Macbrody: /* Step 4 */</p>
<hr />
<div>=How to Write an ACF <span style="color:red"> Under Construction</span> =<br />
<br />
For some examples please see svn<br />
<br />
svn co svn://svn.alpinelinux.org/acf<br />
<br />
*shorewall<br />
*dhcp<br />
<br />
<br />
==From <nil> to a running ACF example application <span style="color:red">Under Construction</span>==<br />
<br />
===Step 1 - The Programming Language===<br />
* ACF uses lua as programming language. Have a look at lua.org [http://www.lua.org/] before starting.<br />
<br />
===Step 2 - The Development Environment===<br />
* Setup an ACF Development Environment: [[Getting_started_with_ACF_development]]<br />
<br />
===Step 3 - Create A Development Directory===<br />
Once you entered the ACF Development Environment as described in step 2:<br />
* in your user home create a directory for your application (e.g. mkdir ~/myapp)<br />
* and cd into it (e.g. cd ~/myapp)<br />
<br />
===Step 4 - MVC, How Does It Affect My Coding?===<br />
ACF is an MVC based framework. What does this mean to you? Your application is separated into three layers: Model, View, Controller - each of which has one or more files.<br />
* Model: In Model the 'real work' is done (e.g. modifying config files, starting/stopping services etc.)<br />
* View: This is where you define what your application will look like. You can have one or more files, each presenting a dynamic html page which only as much code as neccessary to format the data you retrieve from Model.<br />
* Controller: The event dispatcher. In controller you place one function per event. If the user calls the respective 'event page' (web), acf will fire an action - the same-named function in controller will be called. This function then retrieves neccessary data from Model and passes it to View to be displayed to the user.<br />
<br />
===Step 5===<br />
Now let us have a look at the files we need to place into our application directory:<br />
<br />
* Makefile<br />
* config.mk<br />
* myapp-model.lua<br />
* myapp-view-html.lsp<br />
* myapp-controller.lua<br />
* myapp.menu<br />
<br />
<br />
'''Makefile:'''<br />
<br />
The Makefile once called does install our acf application so that we can look at it working.<br />
APP_NAME=myapp<br />
PACKAGE=acf-$(APP_NAME)<br />
VERSION=1.0_alpha1<br />
<br />
APP_DIST=myapp-model.lua \<br />
myapp-view-html.lsp \<br />
myapp-controller.lua \<br />
myapp.menu<br />
<br />
EXTRA_DIST=README Makefile config.mk<br />
<br />
DISTFILES=$(APP_DIST) $(EXTRA_DIST)<br />
<br />
TAR=tar<br />
<br />
P=$(PACKAGE)-$(VERSION)<br />
tarball=$(P).tar.bz2<br />
install_dir=$(DESTDIR)/$(appdir)/$(APP_NAME)<br />
<br />
all:<br />
clean:<br />
rm -rf $(tarball) $(P)<br />
<br />
dist: $(tarball)<br />
<br />
install:<br />
mkdir -p "$(install_dir)"<br />
cp -a $(APP_DIST) "$(install_dir)"<br />
<br />
$(tarball): $(DISTFILES)<br />
rm -rf $(P)<br />
mkdir -p $(P)<br />
cp $(DISTFILES) $(P)<br />
$(TAR) -jcf $@ $(P)<br />
rm -rf $(P)<br />
<br />
# target that creates a tar package, unpacks is and install from package<br />
dist-install: $(tarball)<br />
$(TAR) -jxf $(tarball)<br />
$(MAKE) -C $(P) install DESTDIR=$(DESTDIR)<br />
rm -rf $(P)<br />
<br />
include config.mk<br />
<br />
.PHONY: all clean dist install dist-install<br />
<br />
Remark: Should you create additional view files for example, don't forget to place their names in Makefile under APP_DIST otherwise they will not be installed later on and your application will fail with an error message.<br />
<br />
<br />
'''config.mk:'''<br />
For use with the Makefile. Just copy/paste it. We will look at it later.<br />
prefix=/usr<br />
datadir=${prefix}/share<br />
sysconfdir=${prefix}/etc<br />
localstatedir=${prefix}/var<br />
acfdir=${datadir}/acf<br />
wwwdir=${acfdir}/www<br />
cgibindir=${acfdir}/cgi-bin<br />
appdir=${acfdir}/app<br />
acflibdir=${acfdir}/lib<br />
sessionsdir=${localstatedir}/lib/acf/sessions</div>Macbrodyhttps://wiki.alpinelinux.org/w/index.php?title=ACF_how_to_write&diff=1860ACF how to write2007-11-17T08:28:07Z<p>Macbrody: /* Step 3 */</p>
<hr />
<div>=How to Write an ACF <span style="color:red"> Under Construction</span> =<br />
<br />
For some examples please see svn<br />
<br />
svn co svn://svn.alpinelinux.org/acf<br />
<br />
*shorewall<br />
*dhcp<br />
<br />
<br />
==From <nil> to a running ACF example application <span style="color:red">Under Construction</span>==<br />
<br />
===Step 1 - The Programming Language===<br />
* ACF uses lua as programming language. Have a look at lua.org [http://www.lua.org/] before starting.<br />
<br />
===Step 2 - The Development Environment===<br />
* Setup an ACF Development Environment: [[Getting_started_with_ACF_development]]<br />
<br />
===Step 3 - Create A Development Directory===<br />
Once you entered the ACF Development Environment as described in step 2:<br />
* in your user home create a directory for your application (e.g. mkdir ~/myapp)<br />
* and cd into it (e.g. cd ~/myapp)<br />
<br />
===Step 4===<br />
ACF is an MVC based framework. What does this mean to you? Your application is separated into three layers: Model, View, Controller - each of which has one or more files.<br />
* Model: In Model the 'real work' is done (e.g. modifying config files, starting/stopping services etc.)<br />
* View: This is where you define what your application will look like. You can have one or more files, each presenting a dynamic html page which only as much code as neccessary to format the data you retrieve from Model.<br />
* Controller: The event dispatcher. In controller you place one function per event. If the user calls the respective 'event page' (web), acf will fire an action - the same-named function in controller will be called. This function then retrieves neccessary data from Model and passes it to View to be displayed to the user.<br />
<br />
===Step 5===<br />
Now let us have a look at the files we need to place into our application directory:<br />
<br />
* Makefile<br />
* config.mk<br />
* myapp-model.lua<br />
* myapp-view-html.lsp<br />
* myapp-controller.lua<br />
* myapp.menu<br />
<br />
<br />
'''Makefile:'''<br />
<br />
The Makefile once called does install our acf application so that we can look at it working.<br />
APP_NAME=myapp<br />
PACKAGE=acf-$(APP_NAME)<br />
VERSION=1.0_alpha1<br />
<br />
APP_DIST=myapp-model.lua \<br />
myapp-view-html.lsp \<br />
myapp-controller.lua \<br />
myapp.menu<br />
<br />
EXTRA_DIST=README Makefile config.mk<br />
<br />
DISTFILES=$(APP_DIST) $(EXTRA_DIST)<br />
<br />
TAR=tar<br />
<br />
P=$(PACKAGE)-$(VERSION)<br />
tarball=$(P).tar.bz2<br />
install_dir=$(DESTDIR)/$(appdir)/$(APP_NAME)<br />
<br />
all:<br />
clean:<br />
rm -rf $(tarball) $(P)<br />
<br />
dist: $(tarball)<br />
<br />
install:<br />
mkdir -p "$(install_dir)"<br />
cp -a $(APP_DIST) "$(install_dir)"<br />
<br />
$(tarball): $(DISTFILES)<br />
rm -rf $(P)<br />
mkdir -p $(P)<br />
cp $(DISTFILES) $(P)<br />
$(TAR) -jcf $@ $(P)<br />
rm -rf $(P)<br />
<br />
# target that creates a tar package, unpacks is and install from package<br />
dist-install: $(tarball)<br />
$(TAR) -jxf $(tarball)<br />
$(MAKE) -C $(P) install DESTDIR=$(DESTDIR)<br />
rm -rf $(P)<br />
<br />
include config.mk<br />
<br />
.PHONY: all clean dist install dist-install<br />
<br />
Remark: Should you create additional view files for example, don't forget to place their names in Makefile under APP_DIST otherwise they will not be installed later on and your application will fail with an error message.<br />
<br />
<br />
'''config.mk:'''<br />
For use with the Makefile. Just copy/paste it. We will look at it later.<br />
prefix=/usr<br />
datadir=${prefix}/share<br />
sysconfdir=${prefix}/etc<br />
localstatedir=${prefix}/var<br />
acfdir=${datadir}/acf<br />
wwwdir=${acfdir}/www<br />
cgibindir=${acfdir}/cgi-bin<br />
appdir=${acfdir}/app<br />
acflibdir=${acfdir}/lib<br />
sessionsdir=${localstatedir}/lib/acf/sessions</div>Macbrodyhttps://wiki.alpinelinux.org/w/index.php?title=ACF_how_to_write&diff=1859ACF how to write2007-11-17T08:26:39Z<p>Macbrody: /* Step 2 */</p>
<hr />
<div>=How to Write an ACF <span style="color:red"> Under Construction</span> =<br />
<br />
For some examples please see svn<br />
<br />
svn co svn://svn.alpinelinux.org/acf<br />
<br />
*shorewall<br />
*dhcp<br />
<br />
<br />
==From <nil> to a running ACF example application <span style="color:red">Under Construction</span>==<br />
<br />
===Step 1 - The Programming Language===<br />
* ACF uses lua as programming language. Have a look at lua.org [http://www.lua.org/] before starting.<br />
<br />
===Step 2 - The Development Environment===<br />
* Setup an ACF Development Environment: [[Getting_started_with_ACF_development]]<br />
<br />
===Step 3===<br />
Once you entered the ACF Development Environment as described in step 2:<br />
* in your user home create a directory for your application (e.g. mkdir ~/myapp)<br />
* and cd into it (e.g. cd ~/myapp)<br />
<br />
===Step 4===<br />
ACF is an MVC based framework. What does this mean to you? Your application is separated into three layers: Model, View, Controller - each of which has one or more files.<br />
* Model: In Model the 'real work' is done (e.g. modifying config files, starting/stopping services etc.)<br />
* View: This is where you define what your application will look like. You can have one or more files, each presenting a dynamic html page which only as much code as neccessary to format the data you retrieve from Model.<br />
* Controller: The event dispatcher. In controller you place one function per event. If the user calls the respective 'event page' (web), acf will fire an action - the same-named function in controller will be called. This function then retrieves neccessary data from Model and passes it to View to be displayed to the user.<br />
<br />
===Step 5===<br />
Now let us have a look at the files we need to place into our application directory:<br />
<br />
* Makefile<br />
* config.mk<br />
* myapp-model.lua<br />
* myapp-view-html.lsp<br />
* myapp-controller.lua<br />
* myapp.menu<br />
<br />
<br />
'''Makefile:'''<br />
<br />
The Makefile once called does install our acf application so that we can look at it working.<br />
APP_NAME=myapp<br />
PACKAGE=acf-$(APP_NAME)<br />
VERSION=1.0_alpha1<br />
<br />
APP_DIST=myapp-model.lua \<br />
myapp-view-html.lsp \<br />
myapp-controller.lua \<br />
myapp.menu<br />
<br />
EXTRA_DIST=README Makefile config.mk<br />
<br />
DISTFILES=$(APP_DIST) $(EXTRA_DIST)<br />
<br />
TAR=tar<br />
<br />
P=$(PACKAGE)-$(VERSION)<br />
tarball=$(P).tar.bz2<br />
install_dir=$(DESTDIR)/$(appdir)/$(APP_NAME)<br />
<br />
all:<br />
clean:<br />
rm -rf $(tarball) $(P)<br />
<br />
dist: $(tarball)<br />
<br />
install:<br />
mkdir -p "$(install_dir)"<br />
cp -a $(APP_DIST) "$(install_dir)"<br />
<br />
$(tarball): $(DISTFILES)<br />
rm -rf $(P)<br />
mkdir -p $(P)<br />
cp $(DISTFILES) $(P)<br />
$(TAR) -jcf $@ $(P)<br />
rm -rf $(P)<br />
<br />
# target that creates a tar package, unpacks is and install from package<br />
dist-install: $(tarball)<br />
$(TAR) -jxf $(tarball)<br />
$(MAKE) -C $(P) install DESTDIR=$(DESTDIR)<br />
rm -rf $(P)<br />
<br />
include config.mk<br />
<br />
.PHONY: all clean dist install dist-install<br />
<br />
Remark: Should you create additional view files for example, don't forget to place their names in Makefile under APP_DIST otherwise they will not be installed later on and your application will fail with an error message.<br />
<br />
<br />
'''config.mk:'''<br />
For use with the Makefile. Just copy/paste it. We will look at it later.<br />
prefix=/usr<br />
datadir=${prefix}/share<br />
sysconfdir=${prefix}/etc<br />
localstatedir=${prefix}/var<br />
acfdir=${datadir}/acf<br />
wwwdir=${acfdir}/www<br />
cgibindir=${acfdir}/cgi-bin<br />
appdir=${acfdir}/app<br />
acflibdir=${acfdir}/lib<br />
sessionsdir=${localstatedir}/lib/acf/sessions</div>Macbrodyhttps://wiki.alpinelinux.org/w/index.php?title=ACF_how_to_write&diff=1858ACF how to write2007-11-17T08:26:13Z<p>Macbrody: /* Step 1 */</p>
<hr />
<div>=How to Write an ACF <span style="color:red"> Under Construction</span> =<br />
<br />
For some examples please see svn<br />
<br />
svn co svn://svn.alpinelinux.org/acf<br />
<br />
*shorewall<br />
*dhcp<br />
<br />
<br />
==From <nil> to a running ACF example application <span style="color:red">Under Construction</span>==<br />
<br />
===Step 1 - The Programming Language===<br />
* ACF uses lua as programming language. Have a look at lua.org [http://www.lua.org/] before starting.<br />
<br />
===Step 2===<br />
* Setup an ACF Development Environment: [[Getting_started_with_ACF_development]]<br />
<br />
===Step 3===<br />
Once you entered the ACF Development Environment as described in step 2:<br />
* in your user home create a directory for your application (e.g. mkdir ~/myapp)<br />
* and cd into it (e.g. cd ~/myapp)<br />
<br />
===Step 4===<br />
ACF is an MVC based framework. What does this mean to you? Your application is separated into three layers: Model, View, Controller - each of which has one or more files.<br />
* Model: In Model the 'real work' is done (e.g. modifying config files, starting/stopping services etc.)<br />
* View: This is where you define what your application will look like. You can have one or more files, each presenting a dynamic html page which only as much code as neccessary to format the data you retrieve from Model.<br />
* Controller: The event dispatcher. In controller you place one function per event. If the user calls the respective 'event page' (web), acf will fire an action - the same-named function in controller will be called. This function then retrieves neccessary data from Model and passes it to View to be displayed to the user.<br />
<br />
===Step 5===<br />
Now let us have a look at the files we need to place into our application directory:<br />
<br />
* Makefile<br />
* config.mk<br />
* myapp-model.lua<br />
* myapp-view-html.lsp<br />
* myapp-controller.lua<br />
* myapp.menu<br />
<br />
<br />
'''Makefile:'''<br />
<br />
The Makefile once called does install our acf application so that we can look at it working.<br />
APP_NAME=myapp<br />
PACKAGE=acf-$(APP_NAME)<br />
VERSION=1.0_alpha1<br />
<br />
APP_DIST=myapp-model.lua \<br />
myapp-view-html.lsp \<br />
myapp-controller.lua \<br />
myapp.menu<br />
<br />
EXTRA_DIST=README Makefile config.mk<br />
<br />
DISTFILES=$(APP_DIST) $(EXTRA_DIST)<br />
<br />
TAR=tar<br />
<br />
P=$(PACKAGE)-$(VERSION)<br />
tarball=$(P).tar.bz2<br />
install_dir=$(DESTDIR)/$(appdir)/$(APP_NAME)<br />
<br />
all:<br />
clean:<br />
rm -rf $(tarball) $(P)<br />
<br />
dist: $(tarball)<br />
<br />
install:<br />
mkdir -p "$(install_dir)"<br />
cp -a $(APP_DIST) "$(install_dir)"<br />
<br />
$(tarball): $(DISTFILES)<br />
rm -rf $(P)<br />
mkdir -p $(P)<br />
cp $(DISTFILES) $(P)<br />
$(TAR) -jcf $@ $(P)<br />
rm -rf $(P)<br />
<br />
# target that creates a tar package, unpacks is and install from package<br />
dist-install: $(tarball)<br />
$(TAR) -jxf $(tarball)<br />
$(MAKE) -C $(P) install DESTDIR=$(DESTDIR)<br />
rm -rf $(P)<br />
<br />
include config.mk<br />
<br />
.PHONY: all clean dist install dist-install<br />
<br />
Remark: Should you create additional view files for example, don't forget to place their names in Makefile under APP_DIST otherwise they will not be installed later on and your application will fail with an error message.<br />
<br />
<br />
'''config.mk:'''<br />
For use with the Makefile. Just copy/paste it. We will look at it later.<br />
prefix=/usr<br />
datadir=${prefix}/share<br />
sysconfdir=${prefix}/etc<br />
localstatedir=${prefix}/var<br />
acfdir=${datadir}/acf<br />
wwwdir=${acfdir}/www<br />
cgibindir=${acfdir}/cgi-bin<br />
appdir=${acfdir}/app<br />
acflibdir=${acfdir}/lib<br />
sessionsdir=${localstatedir}/lib/acf/sessions</div>Macbrodyhttps://wiki.alpinelinux.org/w/index.php?title=ACF_how_to_write&diff=1857ACF how to write2007-11-17T08:25:22Z<p>Macbrody: Added the "From <nil> to a running ACF example application"</p>
<hr />
<div>=How to Write an ACF <span style="color:red"> Under Construction</span> =<br />
<br />
For some examples please see svn<br />
<br />
svn co svn://svn.alpinelinux.org/acf<br />
<br />
*shorewall<br />
*dhcp<br />
<br />
<br />
==From <nil> to a running ACF example application <span style="color:red">Under Construction</span>==<br />
<br />
===Step 1===<br />
* ACF uses lua as programming language. Have a look at lua.org [http://www.lua.org/] before starting.<br />
<br />
===Step 2===<br />
* Setup an ACF Development Environment: [[Getting_started_with_ACF_development]]<br />
<br />
===Step 3===<br />
Once you entered the ACF Development Environment as described in step 2:<br />
* in your user home create a directory for your application (e.g. mkdir ~/myapp)<br />
* and cd into it (e.g. cd ~/myapp)<br />
<br />
===Step 4===<br />
ACF is an MVC based framework. What does this mean to you? Your application is separated into three layers: Model, View, Controller - each of which has one or more files.<br />
* Model: In Model the 'real work' is done (e.g. modifying config files, starting/stopping services etc.)<br />
* View: This is where you define what your application will look like. You can have one or more files, each presenting a dynamic html page which only as much code as neccessary to format the data you retrieve from Model.<br />
* Controller: The event dispatcher. In controller you place one function per event. If the user calls the respective 'event page' (web), acf will fire an action - the same-named function in controller will be called. This function then retrieves neccessary data from Model and passes it to View to be displayed to the user.<br />
<br />
===Step 5===<br />
Now let us have a look at the files we need to place into our application directory:<br />
<br />
* Makefile<br />
* config.mk<br />
* myapp-model.lua<br />
* myapp-view-html.lsp<br />
* myapp-controller.lua<br />
* myapp.menu<br />
<br />
<br />
'''Makefile:'''<br />
<br />
The Makefile once called does install our acf application so that we can look at it working.<br />
APP_NAME=myapp<br />
PACKAGE=acf-$(APP_NAME)<br />
VERSION=1.0_alpha1<br />
<br />
APP_DIST=myapp-model.lua \<br />
myapp-view-html.lsp \<br />
myapp-controller.lua \<br />
myapp.menu<br />
<br />
EXTRA_DIST=README Makefile config.mk<br />
<br />
DISTFILES=$(APP_DIST) $(EXTRA_DIST)<br />
<br />
TAR=tar<br />
<br />
P=$(PACKAGE)-$(VERSION)<br />
tarball=$(P).tar.bz2<br />
install_dir=$(DESTDIR)/$(appdir)/$(APP_NAME)<br />
<br />
all:<br />
clean:<br />
rm -rf $(tarball) $(P)<br />
<br />
dist: $(tarball)<br />
<br />
install:<br />
mkdir -p "$(install_dir)"<br />
cp -a $(APP_DIST) "$(install_dir)"<br />
<br />
$(tarball): $(DISTFILES)<br />
rm -rf $(P)<br />
mkdir -p $(P)<br />
cp $(DISTFILES) $(P)<br />
$(TAR) -jcf $@ $(P)<br />
rm -rf $(P)<br />
<br />
# target that creates a tar package, unpacks is and install from package<br />
dist-install: $(tarball)<br />
$(TAR) -jxf $(tarball)<br />
$(MAKE) -C $(P) install DESTDIR=$(DESTDIR)<br />
rm -rf $(P)<br />
<br />
include config.mk<br />
<br />
.PHONY: all clean dist install dist-install<br />
<br />
Remark: Should you create additional view files for example, don't forget to place their names in Makefile under APP_DIST otherwise they will not be installed later on and your application will fail with an error message.<br />
<br />
<br />
'''config.mk:'''<br />
For use with the Makefile. Just copy/paste it. We will look at it later.<br />
prefix=/usr<br />
datadir=${prefix}/share<br />
sysconfdir=${prefix}/etc<br />
localstatedir=${prefix}/var<br />
acfdir=${datadir}/acf<br />
wwwdir=${acfdir}/www<br />
cgibindir=${acfdir}/cgi-bin<br />
appdir=${acfdir}/app<br />
acflibdir=${acfdir}/lib<br />
sessionsdir=${localstatedir}/lib/acf/sessions</div>Macbrodyhttps://wiki.alpinelinux.org/w/index.php?title=Setting_up_the_build_environment_1.7&diff=1845Setting up the build environment 1.72007-11-14T23:08:41Z<p>Macbrody: replaced 'buildroot' occurences with 'sdk'</p>
<hr />
<div>Quick note on how to set up a build environment.<br />
<br />
In this document the build environment will be created in /opt/alpine/1.7. You can ofcourse place it anywhere you have space.<br />
You will need a few Gigabytes to have enough space for kernel cmpiling and storing all the binary packages and iso image.<br />
<br />
If you already done this part and only want to 'update your build env.' then see bottom of this page.<br />
<br />
== Requirements ==<br />
You need a 2.6 kernel to use the chroot build environment.<br />
<br />
* '''Note:''' Make sure your running kernel supports 16bit UIDs for backward compatibility. uCLibc needs them. Check it with:<br />
<br />
zcat /proc/config.gz | grep CONFIG_UID16<br />
<br />
or if you dont have /proc/config.gz:<br />
<br />
grep CONFIG_UID16 /boot/config-`uname -r`<br />
<br />
You should se something like:<br />
<br />
CONFIG_UID16=y<br />
<br />
== Step-by-step ==<br />
'''Before you go on please read this!'''<br />
1) There is the hard way - do it yourself - if you want that go on with step-by-step<br />
2) The quick/easy way: download a script that will do it for you: [http://dev.alpinelinux.org/~abrodman/create-alpine-sdk.sh]<br />
1) download the script<br />
2) chmod +x create-alpine-sdk.sh<br />
3) ./create-alpine-sdk.sh<br />
-> it will download, unpack and compile everything for you<br />
-> location: /opt/alpine/alpine-sdk<br />
<br />
<br />
All packages are downloaded from http://dev.alpinelinux.org/alpine/v1.7<br />
<br />
* Download latest buildroot package from [http://dev.alpinelinux.org/alpine/v1.7/sdk/] and unpack it in /opt/alpine, using the --preserve-permissions option and create a symblink named 1.7 for the development branch.<br />
<br />
sudo mkdir -p /opt/alpine/alpine-sdk<br />
cd /opt/alpine/alpine-sdk<br />
wget -q -O - http://dev.alpinelinux.org/alpine/v1.7/sdk/alpine-sdk-latest.tar.bz2\<br />
| sudo tar -vjxp<br />
cd ..<br />
sudo ln -s alpine-sdk 1.7<br />
<br />
* Copy your DNS configuration to the build environment and mount proc.<br />
<br />
sudo cp /etc/resolv.conf /opt/alpine/1.7/etc/<br />
sudo mount -t proc proc /opt/alpine/1.7/proc<br />
<br />
* Enter the chroot and change the prompt to reflect your chroot environment<br />
<br />
sudo chroot /opt/alpine/1.7 /bin/bash --login<br />
echo 'PS1="(chroot)$PS1"' >> /etc/profile<br />
<br />
Now we are in the build environment chroot.<br />
<br />
* Download latest portage snapshot [http://mirror.gentoo.se/snapshots/portage-latest.tar.bz2 portage-latest.tar.bz2] from Gentoo and unpack it to /usr<br />
<br />
cd /usr<br />
wget -q -O - http://mirror.gentoo.se/snapshots/portage-latest.tar.bz2 portage-latest.tar.bz2 | tar -vjx<br />
<br />
* Check out the alpine-portage overlay from svn.<br />
<br />
svn co svn://svn.alpinelinux.org/alpine-portage/trunk /usr/alpine-portage<br />
<br />
* Download all the [http://dl.alpinelinux.org/alpine/v1.7/tbz2 tbz2] packages into the var/cache/packages directory. This is probably easiest with rsync.<br />
<br />
rsync -rauv rsync://rsync.alpinelinux.org/alpine/v1.7/tbz2/* /var/cache/packages/<br />
<br />
* Check out the alpine-builder scripts in usr/src/<br />
<br />
svn co svn://svn.alpinelinux.org/alpine-builder/trunk /usr/src/alpine<br />
'''NOTE:''' The trunk is constantly changing. You might want to use a tagged release like ''svn://svn.alpinelinux.org/alpine-builder/tags/release-1.7.7''<br />
<br />
* Configure portage to use the config from alpine-builder.<br />
<br />
rm -r /etc/make.conf /etc/portage<br />
ln -s /usr/src/alpine/sdk/etc/make.conf /etc<br />
ln -s /usr/src/alpine/sdk/etc/portage /etc<br />
<br />
* Update the portage tree (this takes some time first time you do it)<br />
<br />
emerge --sync<br />
<br />
* Build the alpine images (iso, usb, flash, etc.)<br />
<br />
cd /usr/src/alpine<br />
make<br />
<br />
'''Failure compiling ipp2p:''' just manually 'emerge iptables' and issue 'make' again.<br />
<br />
<br />
If you get failures while building kernel drivers then you can workaround that by commenting out the specific in ''/usr/src/alpine/kernel/generic/drivers''.<br />
<br />
<br />
'''NOTE when leaving chroot:''' When leaving your chroot, you should unmount the /proc<br />
exit<br />
sudo umount /opt/alpine/1.7/proc<br />
<br />
== Updating the build env. ==<br />
If you already setup the build env earlier and only want to enter it, update it and maybe create a iso, then this part of the documentation is what you are looking for.<br />
* Mount proc.<br />
<br />
sudo mount -t proc proc /opt/alpine/1.7/proc<br />
<br />
* Enter the chroot and change the prompt to reflect your chroot environment<br />
<br />
sudo chroot /opt/alpine/1.7 /bin/bash --login<br />
<br />
Now we are in the build environment chroot.<br />
<br />
* Update the portage snapshot from Gentoo<br />
emerge --sync<br />
When emerge has done syncing, you could be advised to update the portage. In such case, you just follow instructions.<br />
<br />
One instruction could be "* To update portage, run 'emerge portage'".<br />
emerge portage<br />
<br />
Another case could be that you see "* IMPORTANT: x config files in '/etc' need updating.". In that case run the dispatch-conf tool.<br />
dispatch-conf<br />
In most cases (when using the 'dispatch-conf') you should use the new config (by pressing 'u' in the console).<br />
<br />
* Check out the alpine-portage overlay from svn.<br />
<br />
cd /usr/alpine-portage && svn up<br />
<br />
* Download all the [http://dl.alpinelinux.org/alpine/v1.7/tbz2 tbz2] packages into the var/cache/packages directory. This is probably easiest with rsync.<br />
<br />
rsync -rauv rsync://rsync.alpinelinux.org/alpine/v1.7/tbz2/* /var/cache/packages/<br />
<br />
* Check out the alpine-builder scripts in usr/src/<br />
<br />
cd /usr/src/alpine && svn up<br />
<br />
* Build the alpine images (iso, usb, flash, etc.)<br />
<br />
cd /usr/src/alpine<br />
make clean iso<br />
<br />
<br />
'''NOTE when leaving chroot:''' When leaving your chroot, you should unmount the /proc<br />
exit<br />
sudo umount /opt/alpine/1.7/proc</div>Macbrodyhttps://wiki.alpinelinux.org/w/index.php?title=Setting_up_the_build_environment_1.7&diff=1844Setting up the build environment 1.72007-11-14T22:01:00Z<p>Macbrody: made this page fit for alpine-sdk</p>
<hr />
<div>Quick note on how to set up a build environment.<br />
<br />
In this document the build environment will be created in /opt/alpine/1.7. You can ofcourse place it anywhere you have space.<br />
You will need a few Gigabytes to have enough space for kernel cmpiling and storing all the binary packages and iso image.<br />
<br />
If you already done this part and only want to 'update your build env.' then see bottom of this page.<br />
<br />
== Requirements ==<br />
You need a 2.6 kernel to use the chroot build environment.<br />
<br />
* '''Note:''' Make sure your running kernel supports 16bit UIDs for backward compatibility. uCLibc needs them. Check it with:<br />
<br />
zcat /proc/config.gz | grep CONFIG_UID16<br />
<br />
or if you dont have /proc/config.gz:<br />
<br />
grep CONFIG_UID16 /boot/config-`uname -r`<br />
<br />
You should se something like:<br />
<br />
CONFIG_UID16=y<br />
<br />
== Step-by-step ==<br />
'''Before you go on please read this!'''<br />
1) There is the hard way - do it yourself - if you want that go on with step-by-step<br />
2) The quick/easy way: download a script that will do it for you: [http://dev.alpinelinux.org/~abrodman/create-alpine-sdk.sh]<br />
1) download the script<br />
2) chmod +x create-alpine-sdk.sh<br />
3) ./create-alpine-sdk.sh<br />
-> it will download, unpack and compile everything for you<br />
-> location: /opt/alpine/alpine-sdk<br />
<br />
<br />
All packages are downloaded from http://dev.alpinelinux.org/alpine/v1.7<br />
<br />
* Download latest buildroot package from [http://dev.alpinelinux.org/alpine/v1.7/sdk/] and unpack it in /opt/alpine, using the --preserve-permissions option and create a symblink named 1.7 for the development branch.<br />
<br />
sudo mkdir -p /opt/alpine/alpine-sdk<br />
cd /opt/alpine/alpine-sdk<br />
wget -q -O - http://dev.alpinelinux.org/alpine/v1.7/sdk/alpine-sdk-latest.tar.bz2\<br />
| sudo tar -vjxp<br />
cd ..<br />
sudo ln -s alpine-sdk 1.7<br />
<br />
* Copy your DNS configuration to the build environment and mount proc.<br />
<br />
sudo cp /etc/resolv.conf /opt/alpine/1.7/etc/<br />
sudo mount -t proc proc /opt/alpine/1.7/proc<br />
<br />
* Enter the chroot and change the prompt to reflect your chroot environment<br />
<br />
sudo chroot /opt/alpine/1.7 /bin/bash --login<br />
echo 'PS1="(chroot)$PS1"' >> /etc/profile<br />
<br />
Now we are in the build environment chroot.<br />
<br />
* Download latest portage snapshot [http://mirror.gentoo.se/snapshots/portage-latest.tar.bz2 portage-latest.tar.bz2] from Gentoo and unpack it to /usr<br />
<br />
cd /usr<br />
wget -q -O - http://mirror.gentoo.se/snapshots/portage-latest.tar.bz2 portage-latest.tar.bz2 | tar -vjx<br />
<br />
* Check out the alpine-portage overlay from svn.<br />
<br />
svn co svn://svn.alpinelinux.org/alpine-portage/trunk /usr/alpine-portage<br />
<br />
* Download all the [http://dl.alpinelinux.org/alpine/v1.7/tbz2 tbz2] packages into the var/cache/packages directory. This is probably easiest with rsync.<br />
<br />
rsync -rauv rsync://rsync.alpinelinux.org/alpine/v1.7/tbz2/* /var/cache/packages/<br />
<br />
* Check out the alpine-builder scripts in usr/src/<br />
<br />
svn co svn://svn.alpinelinux.org/alpine-builder/trunk /usr/src/alpine<br />
'''NOTE:''' The trunk is constantly changing. You might want to use a tagged release like ''svn://svn.alpinelinux.org/alpine-builder/tags/release-1.7.7''<br />
<br />
* Configure portage to use the config from alpine-builder.<br />
<br />
rm -r /etc/make.conf /etc/portage<br />
ln -s /usr/src/alpine/buildroot/etc/make.conf /etc<br />
ln -s /usr/src/alpine/buildroot/etc/portage /etc<br />
<br />
* Update the portage tree (this takes some time first time you do it)<br />
<br />
emerge --sync<br />
<br />
* Build the alpine images (iso, usb, flash, etc.)<br />
<br />
cd /usr/src/alpine<br />
make<br />
<br />
'''Failure compiling ipp2p:''' just manually 'emerge iptables' and issue 'make' again.<br />
<br />
<br />
If you get failures while building kernel drivers then you can workaround that by commenting out the specific in ''/usr/src/alpine/kernel/generic/drivers''.<br />
<br />
<br />
'''NOTE when leaving chroot:''' When leaving your chroot, you should unmount the /proc<br />
exit<br />
sudo umount /opt/alpine/1.7/proc<br />
<br />
== Updating the build env. ==<br />
If you already setup the build env earlier and only want to enter it, update it and maybe create a iso, then this part of the documentation is what you are looking for.<br />
* Mount proc.<br />
<br />
sudo mount -t proc proc /opt/alpine/1.7/proc<br />
<br />
* Enter the chroot and change the prompt to reflect your chroot environment<br />
<br />
sudo chroot /opt/alpine/1.7 /bin/bash --login<br />
<br />
Now we are in the build environment chroot.<br />
<br />
* Update the portage snapshot from Gentoo<br />
emerge --sync<br />
When emerge has done syncing, you could be advised to update the portage. In such case, you just follow instructions.<br />
<br />
One instruction could be "* To update portage, run 'emerge portage'".<br />
emerge portage<br />
<br />
Another case could be that you see "* IMPORTANT: x config files in '/etc' need updating.". In that case run the dispatch-conf tool.<br />
dispatch-conf<br />
In most cases (when using the 'dispatch-conf') you should use the new config (by pressing 'u' in the console).<br />
<br />
* Check out the alpine-portage overlay from svn.<br />
<br />
cd /usr/alpine-portage && svn up<br />
<br />
* Download all the [http://dl.alpinelinux.org/alpine/v1.7/tbz2 tbz2] packages into the var/cache/packages directory. This is probably easiest with rsync.<br />
<br />
rsync -rauv rsync://rsync.alpinelinux.org/alpine/v1.7/tbz2/* /var/cache/packages/<br />
<br />
* Check out the alpine-builder scripts in usr/src/<br />
<br />
cd /usr/src/alpine && svn up<br />
<br />
* Build the alpine images (iso, usb, flash, etc.)<br />
<br />
cd /usr/src/alpine<br />
make clean iso<br />
<br />
<br />
'''NOTE when leaving chroot:''' When leaving your chroot, you should unmount the /proc<br />
exit<br />
sudo umount /opt/alpine/1.7/proc</div>Macbrodyhttps://wiki.alpinelinux.org/w/index.php?title=Setting_up_the_build_environment_1.7&diff=1836Setting up the build environment 1.72007-11-14T13:39:07Z<p>Macbrody: added ipp2p issue</p>
<hr />
<div>Quick note on how to set up a build environment.<br />
<br />
In this document the build environment will be created in /opt/alpine/1.7. You can ofcourse place it anywhere you have space.<br />
You will need a few Gigabytes to have enough space for kernel cmpiling and storing all the binary packages and iso image.<br />
<br />
If you already done this part and only want to 'update your build env.' then see bottom of this page.<br />
<br />
== Requirements ==<br />
You need a 2.6 kernel to use the chroot build environment.<br />
<br />
* '''Note:''' Make sure your running kernel supports 16bit UIDs for backward compatibility. uCLibc needs them. Check it with:<br />
<br />
zcat /proc/config.gz | grep CONFIG_UID16<br />
<br />
or if you dont have /proc/config.gz:<br />
<br />
grep CONFIG_UID16 /boot/config-`uname -r`<br />
<br />
You should se something like:<br />
<br />
CONFIG_UID16=y<br />
<br />
== Step-by-step ==<br />
All packages are downloaded from http://dev.alpinelinux.org/alpine/v1.7<br />
<br />
* Download latest buildroot package from [http://dev.alpinelinux.org/alpine/v1.7/buildroot/] and unpack it in /opt/alpine, using the --preserve-permissions option and create a symblink named 1.7 for the development branch.<br />
<br />
sudo mkdir -p /opt/alpine<br />
cd /opt/alpine<br />
wget -q -O - http://dev.alpinelinux.org/alpine/v1.7/buildroot/alpine-buildroot-latest.tar.bz2\<br />
| sudo tar -vjxp<br />
sudo ln -s alpine-buildroot-1.7.6 1.7<br />
<br />
* Copy your DNS configuration to the build environment and mount proc.<br />
<br />
sudo cp /etc/resolv.conf /opt/alpine/1.7/etc/<br />
sudo mount -t proc proc /opt/alpine/1.7/proc<br />
<br />
* Enter the chroot and change the prompt to reflect your chroot environment<br />
<br />
sudo chroot /opt/alpine/1.7 /bin/bash --login<br />
echo 'PS1="(chroot)$PS1"' >> /etc/profile<br />
<br />
Now we are in the build environment chroot.<br />
<br />
* Download latest portage snapshot [http://mirror.gentoo.se/snapshots/portage-latest.tar.bz2 portage-latest.tar.bz2] from Gentoo and unpack it to /usr<br />
<br />
cd /usr<br />
wget -q -O - http://mirror.gentoo.se/snapshots/portage-latest.tar.bz2 portage-latest.tar.bz2 | tar -vjx<br />
<br />
* Check out the alpine-portage overlay from svn.<br />
<br />
svn co svn://svn.alpinelinux.org/alpine-portage/trunk /usr/alpine-portage<br />
<br />
* Download all the [http://dl.alpinelinux.org/alpine/v1.7/tbz2 tbz2] packages into the var/cache/packages directory. This is probably easiest with rsync.<br />
<br />
rsync -rauv rsync://rsync.alpinelinux.org/alpine/v1.7/tbz2/* /var/cache/packages/<br />
<br />
* Check out the alpine-builder scripts in usr/src/<br />
<br />
svn co svn://svn.alpinelinux.org/alpine-builder/trunk /usr/src/alpine<br />
'''NOTE:''' The trunk is constantly changing. You might want to use a tagged release like ''svn://svn.alpinelinux.org/alpine-builder/tags/release-1.7.7''<br />
<br />
* Configure portage to use the config from alpine-builder.<br />
<br />
rm -r /etc/make.conf /etc/portage<br />
ln -s /usr/src/alpine/buildroot/etc/make.conf /etc<br />
ln -s /usr/src/alpine/buildroot/etc/portage /etc<br />
<br />
* Update the portage tree (this takes some time first time you do it)<br />
<br />
emerge --sync<br />
<br />
* Build the alpine images (iso, usb, flash, etc.)<br />
<br />
cd /usr/src/alpine<br />
make<br />
<br />
'''Failure compiling ipp2p:''' just manually 'emerge iptables' and issue 'make' again.<br />
<br />
<br />
If you get failures while building kernel drivers then you can workaround that by commenting out the specific in ''/usr/src/alpine/kernel/generic/drivers''.<br />
<br />
<br />
'''NOTE when leaving chroot:''' When leaving your chroot, you should unmount the /proc<br />
exit<br />
sudo umount /opt/alpine/1.7/proc<br />
<br />
== Updating the build env. ==<br />
If you already setup the build env earlier and only want to enter it, update it and maybe create a iso, then this part of the documentation is what you are looking for.<br />
* Mount proc.<br />
<br />
sudo mount -t proc proc /opt/alpine/1.7/proc<br />
<br />
* Enter the chroot and change the prompt to reflect your chroot environment<br />
<br />
sudo chroot /opt/alpine/1.7 /bin/bash --login<br />
<br />
Now we are in the build environment chroot.<br />
<br />
* Update the portage snapshot from Gentoo<br />
emerge --sync<br />
When emerge has done syncing, you could be advised to update the portage. In such case, you just follow instructions.<br />
<br />
One instruction could be "* To update portage, run 'emerge portage'".<br />
emerge portage<br />
<br />
Another case could be that you see "* IMPORTANT: x config files in '/etc' need updating.". In that case run the dispatch-conf tool.<br />
dispatch-conf<br />
In most cases (when using the 'dispatch-conf') you should use the new config (by pressing 'u' in the console).<br />
<br />
* Check out the alpine-portage overlay from svn.<br />
<br />
cd /usr/alpine-portage && svn up<br />
<br />
* Download all the [http://dl.alpinelinux.org/alpine/v1.7/tbz2 tbz2] packages into the var/cache/packages directory. This is probably easiest with rsync.<br />
<br />
rsync -rauv rsync://rsync.alpinelinux.org/alpine/v1.7/tbz2/* /var/cache/packages/<br />
<br />
* Check out the alpine-builder scripts in usr/src/<br />
<br />
cd /usr/src/alpine && svn up<br />
<br />
* Build the alpine images (iso, usb, flash, etc.)<br />
<br />
cd /usr/src/alpine<br />
make clean iso<br />
<br />
<br />
'''NOTE when leaving chroot:''' When leaving your chroot, you should unmount the /proc<br />
exit<br />
sudo umount /opt/alpine/1.7/proc</div>Macbrodyhttps://wiki.alpinelinux.org/w/index.php?title=Alpine_Configuration_Framework_Design&diff=1800Alpine Configuration Framework Design2007-11-12T09:54:50Z<p>Macbrody: Added dhcp</p>
<hr />
<div>= Alpine Configuration Framework =<br />
<br />
The Alpine Configuration Framework (ACF) is a mvc-style application for configuring an Alpine device. The primary focus is for a web interface - ACF's main goal is to be a light-weight MVC "webmin".<br />
<br />
== Why Haserl + Lua == <br />
<br />
Other competitors in the arena were Webmin, Ruby on Rails, PHP with templates.<br />
<br />
A full webmin (Perl), RoR or PHP implementation each require several MB of installed code, and can have very slow startup times, especially when used in "cgi" mode. After evaluating many options, we found that [http://www.lua.org Lua] has the following advantages:<br />
<br />
* It is small (typically ~200KB of compiled code)<br />
* It compiles and runs much faster than [http://shootout.alioth.debian.org/gp4/benchmark.php?test=all&lang=lua&lang2=php PHP], [http://shootout.alioth.debian.org/gp4/benchmark.php?test=all&lang=lua&lang2=perl Perl] or [http://shootout.alioth.debian.org/gp4/benchmark.php?test=all&lang=lua&lang2=ruby Ruby]<br />
* It provides a "normal" scripting language with [http://en.wikipedia.org/wiki/Lua_(programming_language)#Features features] similar to PHP, perl, java, awk, etc. <br />
<br />
Haserl + Lua provides a 'good enough' toolset to build a full-featured web application.<br />
<br />
== Why ACF is MVC ==<br />
<br />
The MVC design pattern is used to separate presentation information from control logic. By MVC we mean:<br />
<br />
* '''Model''' - code that reads / writes a config file, starts / stops daemons, or does other work modifying the router.<br />
* '''View''' - code that formats data for output<br />
* '''Controller''' - code that glues the two together<br />
<br />
Note the lack of words like: HTML, XML, OO, AJAX, etc. The purpose of ACF's MVC is simply to separate the configuration logic from the presentation of the output. <br />
<br />
The flow of a single transaction is:<br />
<br />
start -> <br />
execute requested function in '''controller''', <br />
optionally reading/writing a file using functions in the '''model''' -><br />
execute the '''view''' to format the output -><br />
end<br />
<br />
''Every'' transaction follows this pattern. For ACF developers, the focus should be on getting a model that does a proper job of abstracting the config file into useable entities and then building a controller that presents useable "actions" based on the model. The presentation layer should be last on the priority list.<br />
<br />
For good background information on what ACF attempts to do, please see Terence Parr's paper "Enforcing Strict Model-View Separation in Template Engines" at <br />
[http://www.cs.usfca.edu/~parrt/papers/mvc.templates.pdf http://www.cs.usfcs.edu] or the [[Media:Mvc.templates.pdf|local copy]] of the pdf.<br />
<br />
= ACF Developer's Guides =<br />
<br />
# [[ACF_mvc.lua_reference|mvc.lua reference]] - mvc.lua is the core of ACF<br />
# [[ACF_mvc.lua_example|mvc.lua example]] - build a simple (command-line) application<br />
# [[ACF_acf_www-controller.lua_reference|acf www-controller reference]] - ACF www application functions<br />
# [[ACF_acf_www_example| acf www-controller example]] - webify the above examples<br />
<br />
# [[ACF core principles]] (Things that are standard across the application)<br />
# [[ACF Libraries ]] Document the libraries and common functions<br />
# [[LPOSIX]] Documentation for the Lua Posix functions<br />
<br />
= ACF Modules =<br />
<br />
== Networking ==<br />
=== Firewall ===<br />
based on shorewall. Will need an advanced and simple interface<br />
<br />
=== Routing ===<br />
this is for remote/multi box routing, bgp...etc<br />
<br />
=== Interfaces ===<br />
Local interface management-local routing taken care of here<br />
<br />
=== DNS ===<br />
Caching/Hosting/for both Internet and Inside firewall nets<br />
<br />
=== DHCP ===<br />
Creation and configuration of a config for the isc-dhcp daemon. Allow for several subnets to be configured independantly.<br />
<br />
== Proxies ==<br />
=== Web Proxies ===<br />
Squid<br />
=== Web Filtering ===<br />
Dansguardian<br />
=== Mail ===<br />
May Include fetchmail configuration/Relay host/store and forward<br />
<br />
== Connectivity == <br />
=== VPN ===<br />
Needs to be split into an administrative end for letting people connect to you(rogue warriors,personal laptop size connectivity) and VPN connectivity to other sites(remote office or location). These are to configured differently.<br />
<br />
=== Dialup ===<br />
Start/Stop Dialup connection<br />
<br />
=== Dialup/PPPoE ===<br />
Configure Dialup/PPP/PPPoE connectivity. Maybe other Internet connections that aren't ethernet-which is Interfaces<br />
<br />
== Backup/Packages ==<br />
=== Backup ===<br />
Way to have save things not in /etc and just kickoff a lbu commit<br />
=== Source Manager ===<br />
Way to change the /etc/apk/apk.conf<br />
=== Package Manager ===<br />
Way to say what to upgrade-install-remove...apk_*<br />
<br />
== General ==<br />
=== Password Manager ===<br />
Local password changer<br />
=== Logfiles ===<br />
* General<br />
** The logfiles-model decides which folders should be listed.<BR>Based on this list files could be deleted/view/downloaded.<br />
** By manually entering a filename that doesn't match the logfiles-list you get a error message (wrong files could not be deleted/viewed/...) <br />
* Delete<br />
** File is blocked for removal if the file is in use.<BR>'fuser ''filename''' checks if file is in use at the moment.<br />
* View<br />
** Files could be blocked for viewing if this was programmed in the logfiles-model.<BR>Preparations has been done, but no rules has been defined if some file/files are blocked for viewing.<br />
* Download<br />
** Logfiles should be able to be downloaded.<br />
<br />
=== Diagnostic ===<br />
Stats/Resource use/maybe graphs-rrd</div>Macbrodyhttps://wiki.alpinelinux.org/w/index.php?title=LuaPosix&diff=1785LuaPosix2007-11-11T21:31:10Z<p>Macbrody: Added example and more detailed description of the luaposix.access function</p>
<hr />
<div>=Lua Posix=<br />
This is a list of the Lua Posix functions. Included is helpful snipets of code.<br />
Install lua posix. To get this list do:<br />
bar = require "posix"<br />
for a in pairs(bar) do print(a) end<br />
<br />
==access==<br />
'''INPUT'''<br />
*Path- file or directory path that wants to be checked<br />
*Permission - what permissions do you want to check<br />
** "r" = read <br />
** "w" = write<br />
** "x" = execute<br />
** "f" = all permissions? <span style="color:red">not sure</span><br />
'''OUPUT'''<br />
*string - 0 for success, nil for failure if done<br />
bar = require "posix"<br />
temp = bar.access("/etc/passwd", "w")<br />
print(temp)<br />
Will give more information like<br />
bar = require "posix"<br />
print(bar.access("/etc/passwd", "w"))<br />
--If nil will give back the error too<br />
nil /etc/passwd: Permission denied 13<br />
<br />
==chdir==<br />
'''INPUT'''<br />
*Path - where do you want to change directory to<br />
'''OUPUT'''<br />
* 0 if success<br />
** nil if failed<br />
<br />
bar = require "posix"<br />
bar.chdir("/etc/")<br />
--print(bar.getcwd()) to see where you are<br />
0 if success, nil if failure. If you <br />
print(bar.chdir("/var/lob"))<br />
-- it will print the system error message also<br />
nil /var/lob: No such file or directory 2<br />
<br />
<br />
The access function returns three values altogether; the following example may help to distinguish their use:<br />
<br />
lpos = require "posix"<br />
ptr, msg, code = lpos.access("/etc/dhcp")<br />
if ptr == nil then<br />
print("msg = " .. msg)<br />
print("code = " .. code)<br />
else<br />
print("ptr = " .. ptr)<br />
end<br />
<br />
==chmod==<br />
'''INPUT'''<br />
*PATH - where is the file or directory<br />
**MODE - what mode to you want to change on the file<br />
'''OUPUT'''<br />
* string - 0 if sucess, nil failure<br />
bar = require "posix"<br />
bar.chmod("/etc/passwd", "a=rwx")<br />
--looks like you need to use the ugoa format for this, not numbers<br />
<br />
==chown==<br />
'''INPUT'''<br />
*Path-location of file or directory<br />
* UID - User id number<br />
* GID - Group id number<br />
'''OUPUT'''<br />
*String - 0 is success and nil for failure<br />
bar = require "posix"<br />
print(bar.chown("/etc/passwd",100,200)<br />
--above will give back nil. Since we printed it will also give back the system errors.<br />
<br />
==ctermid==<br />
'''INPUT'''<br />
*NONE- DISPLAYS the terminal id<br />
'''OUTPUT'''<br />
*String with the terminal id<br />
bar = require "posix"<br />
print(bar.ctermid())<br />
<br />
==dir==<br />
Directory listing<br />
'''INPUT'''<br />
* PATH - directory<br />
'''OUTPUT'''<br />
*TABLE - table with the file name contents of the directory<br />
**Failure returns a nil value<br />
bar = require "posix"<br />
bobo = bar.dir("/var/log")<br />
for a,b in ipairs(bobo) do print(b) end<br />
-- the bobo table will output all the file names in /var/log/<br />
<br />
==errno==<br />
<br />
Display the error information<br />
<br />
'''INPUT'''<br />
*NONE<br />
'''OUPUT'''<br />
*Success, or Error message<br />
bar = require "posix"<br />
a,b = bar.dir("/var/foo"), bar.errno()<br />
print(a,b)<br />
-- a will be nil or 0, b will be No such file or directory or Success<br />
<br />
==exec==<br />
Replaces the running process with the command specified. Command line arguments are given as additional arguments. (To start a sub process, you probably want fork+exec, not just exec.)<br />
<br />
'''INPUT'''<br />
*PATH-Location of binary<br />
*ARGs-options to pass to binary<br />
'''OUTPUT'''<br />
*Strings<br />
bar = require "posix"<br />
bobo = bar.exec("/bin/ls", "-l", "/etc/")<br />
<br />
==files==<br />
Returns an interator function that loops over each file in the given directory<br />
<br />
'''INPUT'''<br />
*PATH- Directory<br />
'''OUPUT'''<br />
require "posix"<br />
<br />
for name in posix.files("/etc") do<br />
print (name)<br />
end<br />
<br />
==fork==<br />
'''INPUT'''<br />
*None<br />
'''OUTPUT'''<br />
returns: -1 on error, 0 to the child process, and the pid of the child to the parent.<br />
<br />
require("posix")<br />
<br />
print ("parent: my pid is: " .. posix.getpid("pid")) <br />
<br />
local pid = posix.fork () <br />
<br />
if ( pid == -1 ) then<br />
print ("parent: The fork failed.")<br />
elseif ( pid == 0 ) then<br />
print ("child: Hello World! I am pid: " .. posix.getpid("pid") )<br />
print ("child: I'll sleep for 1 second ... ")<br />
posix.sleep(1)<br />
print ("child: Good bye");<br />
else<br />
print ("parent: While the child sleeps, I'm still running.")<br />
print ("parent: waiting for child (pid:" .. pid .. ") to die...")<br />
posix.wait(pid)<br />
print ("parent: child died, but I'm still alive.")<br />
print ("parent: Good bye")<br />
end<br />
<br />
parent: my pid is: 11050<br />
child: Hello World! I am pid: 11051<br />
child: I'll sleep for 1 second ... <br />
parent: While the child sleeps, I'm still running.<br />
parent: waiting for child (pid:11051) to die...<br />
child: Good bye<br />
parent: child died, but I'm still alive.<br />
parent: Good bye<br />
<br />
==getcwd==<br />
'''INPUT'''<br />
*NONE<br />
'''OUTPUT'''<br />
*String- contents of which is the current working directory<br />
bar = require "posix"<br />
print(bar.getcwd())<br />
<br />
==getenv==<br />
'''INPUT'''<br />
*NONE<br />
'''OUPUT'''<br />
*Table - Current Environment settings<br />
<br />
bar = require "posix"<br />
bobo = bar.getenv()<br />
for a,b in pairs(bobo) do print(b) end<br />
-- Varible - Value<br />
<br />
==getgroup==<br />
'''INPUT'''<br />
*GID, or groupname<br />
'''OUPUT'''<br />
*TABLE -contents of which hold the group name,gid, and users<br />
bar = require "posix"<br />
bobo = bar.getgroup(1000)<br />
for a,b in pairs(bobo) do print(a,b) end<br />
--if you use pairs then bobo will print also the name and gid or the group<br />
--if you use ipairs then just the group members<br />
1 user1<br />
2 user2<br />
name wheel<br />
gid 1<br />
<br />
==getlogin==<br />
<span style="color:red">Couldn't get it to work</span><br />
<br />
'''INPUT'''<br />
*NONE<br />
'''OUPUT'''<br />
*UNKNOWN<br />
<br />
==getpassword==<br />
'''INPUT'''<br />
*NAME or UID<br />
'''OUPUT'''<br />
*TABLE- values from /etc/passwd<br />
uid,name,gid,password,gecos,dir,shell<br />
bar = require "posix"<br />
bobo = bar.getpasswd("root")<br />
for a,b in pairs(bobo) do print(a,b) end<br />
--uid 0<br />
--name root<br />
--gid 0<br />
--passwd x<br />
--gecos root<br />
--dir /root/<br />
--shell /bin/bash<br />
<br />
==getprocessid==<br />
'''INPUT'''<br />
*Selector - either [egid,euid,gid,uid,pgrp,pid,ppid,NULL]<br />
'''OUPUT'''<br />
*Number that matches the current process and the selector<br />
bar = require "posix"<br />
print(bar.getprocessid("gid"))<br />
18456 <br />
--it just printed the current process id for the script or interactive lua.<br />
<br />
<br />
Is there a version difference here? AL 1.7.7 calls this "getpid" [[User:Nangel|Nangel]]<br />
<br />
==kill==<br />
'''INPUT'''<br />
*PID- process identifier<br />
*Signal- to send to the process<br />
'''OUPUT'''<br />
<br />
bar = require "posix"<br />
--kill your current process<br />
bobo = bar.getprocessid("pid")<br />
bar.kill(bobo,9)<br />
---Signals looks to be the number signals accepted in Unix<br />
<br />
==link==<br />
Hard Links<br />
'''INPUT'''<br />
*Oldpath-<br />
*Newpath-<br />
'''OUTPUT''<br />
If you want output 0 sucess, nil errors<br />
<br />
bar = require "posix"<br />
bobo = bar.link("/etc/passwd", "testfile")<br />
-- 0 for success, nil for errors<br />
<br />
==mkdir==<br />
'''INPUT'''<br />
*PATH-path to new dir<br />
'''OUTPUT'''<br />
If you are looking for output-<br />
*0 for success<br />
*nil for failure<br />
<br />
bar = require "posix"<br />
bar.mkdir("/home/user/bobo")<br />
--set the above to a variable to get output<br />
<br />
==mkfifo==<br />
'''INPUT'''<br />
*PATH- where to make the fifo<br />
<br />
==patchconf==<br />
<br />
==putenv==<br />
<br />
==readlink==<br />
<br />
==rmdir==<br />
<br />
==setgid==<br />
<br />
==setuid==<br />
<br />
==sleep==<br />
<br />
==stat==<br />
<br />
==symlink==<br />
<br />
==sysconf==<br />
<br />
==times==<br />
<br />
==ttyname==<br />
<br />
==umask==<br />
<br />
==uname==<br />
<br />
==utime==<br />
<br />
==wait==<br />
<br />
----<br />
<br />
'''If you are using this under linux also get '''<br />
<br />
==setenv==<br />
<br />
==unsetenv==</div>Macbrodyhttps://wiki.alpinelinux.org/w/index.php?title=Setting_up_the_build_environment_1.7&diff=1648Setting up the build environment 1.72007-10-26T13:08:38Z<p>Macbrody: threw out mounting /dev in chroot</p>
<hr />
<div>Quick note on how to set up a build environment.<br />
<br />
In this document the build environment will be created in /opt/alpine/1.7. You can ofcourse place it anywhere you have space.<br />
You will need a few Gigabytes to have enough space for kernel cmpiling and storing all the binary packages and iso image.<br />
<br />
== Requirements ==<br />
You need a 2.6 kernel to use the chroot build environment.<br />
<br />
* '''Note:''' Make sure your running kernel supports 16bit UIDs for backward compatibility. uCLibc needs them. Check it with:<br />
<br />
zcat /proc/config.gz | grep CONFIG_UID16<br />
<br />
or if you dont have /proc/config.gz:<br />
<br />
grep CONFIG_UID16 /boot/config-`uname -r`<br />
<br />
You should se something like:<br />
<br />
CONFIG_UID16=y<br />
<br />
== Step-by-step ==<br />
All packages are downloaded from http://dev.alpinelinux.org/alpine/v1.7<br />
<br />
* Download latest buildroot package from [http://dev.alpinelinux.org/alpine/v1.7/buildroot/] and unpack it in /opt/alpine, using the --preserve-permissions option and create a symblink named 1.7 for the development branch.<br />
<br />
sudo mkdir -p /opt/alpine<br />
cd /opt/alpine<br />
wget -q -O - http://dev.alpinelinux.org/alpine/v1.7/buildroot/alpine-buildroot-latest.tar.bz2\<br />
| sudo tar -vjxp<br />
sudo ln -s alpine-buildroot-1.7.6 1.7<br />
<br />
<br />
* Copy your DNS configuration to the build environment and mount proc.<br />
<br />
sudo cp /etc/resolv.conf /opt/alpine/1.7/etc/<br />
sudo mount -t proc proc /opt/alpine/1.7/proc<br />
<br />
* Enter the chroot and change the prompt to reflect your chroot environment<br />
<br />
sudo chroot /opt/alpine/1.7 /bin/bash --login<br />
export PS1="(chroot) $PS1"<br />
<br />
Now we are in the build environment chroot.<br />
<br />
* Download latest portage snapshot [http://mirror.gentoo.se/snapshots/portage-latest.tar.bz2 portage-latest.tar.bz2] from Gentoo and unpack it to /usr<br />
<br />
cd /usr<br />
wget -q -O - http://mirror.gentoo.se/snapshots/portage-latest.tar.bz2 portage-latest.tar.bz2 | tar -vjx<br />
<br />
* Check out the alpine-portage overlay from svn.<br />
<br />
svn co svn://svn.alpinelinux.org/alpine-portage/trunk /usr/alpine-portage<br />
<br />
* Download all the [http://dl.alpinelinux.org/alpine/v1.7/tbz2 tbz2] packages into the var/cache/packages directory. This is probably easiest with rsync.<br />
<br />
rsync -rauv rsync://rsync.alpinelinux.org/alpine/v1.7/tbz2/* /var/cache/packages/<br />
<br />
* Check out the alpine-builder scripts in usr/src/<br />
<br />
svn co svn://svn.alpinelinux.org/alpine-builder/trunk /usr/src/alpine<br />
'''NOTE:''' The trunk is constantly changing. You might want to use a tagged release like ''svn://svn.alpinelinux.org/alpine-builder/tags/release-1.7.7''<br />
<br />
* Configure portage to use the config from alpine-builder.<br />
<br />
rm -r /etc/make.conf /etc/portage<br />
ln -s /usr/src/alpine/buildroot/etc/make.conf /etc<br />
ln -s /usr/src/alpine/buildroot/etc/portage /etc<br />
<br />
* Update the portage tree (this takes some time first time you do it)<br />
<br />
emerge --sync<br />
<br />
* Build the alpine images (iso, usb, flash, etc.)<br />
<br />
cd /usr/src/alpine<br />
make<br />
<br />
If you get failures while building kernel drivers then you can workaround that by commenting out the specific in ''/usr/src/alpine/kernel/generic/drivers''.</div>Macbrodyhttps://wiki.alpinelinux.org/w/index.php?title=Setting_up_the_build_environment_1.7&diff=1604Setting up the build environment 1.72007-10-18T07:32:52Z<p>Macbrody: add modification of $PS1 to reflect chroot environment</p>
<hr />
<div>Quick note on how to set up a build environment.<br />
<br />
In this document the build environment will be created in /opt/alpine/1.7. You can ofcourse place it anywhere you have space.<br />
You will need a few Gigabytes to have enough space for kernel cmpiling and storing all the binary packages and iso image.<br />
<br />
== Requirements ==<br />
You need a 2.6 kernel to use the chroot build environment.<br />
<br />
* '''Note:''' Make sure your running kernel supports 16bit UIDs for backward compatibility. uCLibc needs them. Check it with:<br />
<br />
zcat /proc/config.gz | grep CONFIG_UID16<br />
<br />
<br />
== Step-by-step ==<br />
All packages are downloaded from http://dev.alpinelinux.org/alpine/v1.7<br />
<br />
* Download latest buildroot package from [http://dev.alpinelinux.org/alpine/v1.7/buildroot/] and unpack it in /opt/alpine, using the --preserve-permissions option and create a symblink named 1.7 for the development branch.<br />
<br />
sudo mkdir -p /opt/alpine<br />
cd /opt/alpine<br />
wget -q -O - http://dev.alpinelinux.org/alpine/v1.7/buildroot/alpine-buildroot-latest.tar.bz2\<br />
| sudo tar -vjxp<br />
sudo ln -s alpine-buildroot-1.7.6 1.7<br />
<br />
<br />
* Copy your DNS configuration to the build environment and mount proc.<br />
<br />
sudo cp /etc/resolv.conf /opt/alpine/1.7/etc/<br />
sudo mount -t proc proc /opt/alpine/1.7/proc<br />
sudo mount -o bind /dev /opt/alpine/1.7/dev<br />
<br />
* Enter the chroot and change the prompt to reflect your chroot environment<br />
<br />
sudo chroot /opt/alpine/1.7 /bin/bash --login<br />
export PS1="(chroot) $PS1"<br />
<br />
Now we are in the build environment chroot.<br />
<br />
* Download latest portage snapshot [http://mirror.gentoo.se/snapshots/portage-latest.tar.bz2 portage-latest.tar.bz2] from Gentoo and unpack it to /usr<br />
<br />
cd /usr<br />
wget -q -O - http://mirror.gentoo.se/snapshots/portage-latest.tar.bz2 portage-latest.tar.bz2 | tar -vjx<br />
<br />
* Check out the alpine-portage overlay from svn.<br />
<br />
svn co svn://svn.alpinelinux.org/alpine-portage/trunk /usr/alpine-portage<br />
<br />
* Download all the [http://dl.alpinelinux.org/alpine/v1.7/tbz2 tbz2] packages into the var/cache/packages directory. This is probably easiest with rsync.<br />
<br />
rsync -rauv rsync://rsync.alpinelinux.org/alpine/v1.7/tbz2/* /var/cache/packages/<br />
<br />
* Check out the alpine-builder scripts in usr/src/<br />
<br />
svn co svn://svn.alpinelinux.org/alpine-builder/trunk /usr/src/alpine<br />
<br />
* Configure portage to use the config from alpine-builder.<br />
<br />
rm -r /etc/make.conf /etc/portage<br />
ln -s /usr/src/alpine/buildroot/etc/make.conf /etc<br />
ln -s /usr/src/alpine/buildroot/etc/portage /etc<br />
<br />
* Update the portage tree (this takes some time first time you do it)<br />
<br />
emerge --sync<br />
<br />
* Install the kernel sources, using the downloaded tbz2. <br />
<br />
''This step is no longer neccessary as this is done automatically within the build script.''<br />
<br />
* Make sure that /usr/src/linux points to your kernel version: ''(the below mentioned steps are optional as this is done automatically by the alpine build process - in case your build breaks, check if the linux source link exists)''<br />
<br />
cd /usr/src<br />
rm -f linux<br />
ln -s linux-2.6.20-hardened-r10 linux<br />
<br />
* Build the alpine images (iso, usb, flash, etc.)<br />
<br />
cd /usr/src/alpine<br />
make<br />
<br />
If you get failures while building kernel drivers then you can workaround that by commenting out the specific in ''/usr/src/alpine/kernel/generic/drivers''.</div>Macbrodyhttps://wiki.alpinelinux.org/w/index.php?title=Setting_up_the_build_environment_1.7&diff=1603Setting up the build environment 1.72007-10-17T21:27:40Z<p>Macbrody: updated kernel version directory for linking with /usr/src/linux</p>
<hr />
<div>Quick note on how to set up a build environment.<br />
<br />
In this document the build environment will be created in /opt/alpine/1.7. You can ofcourse place it anywhere you have space.<br />
You will need a few Gigabytes to have enough space for kernel cmpiling and storing all the binary packages and iso image.<br />
<br />
== Requirements ==<br />
You need a 2.6 kernel to use the chroot build environment.<br />
<br />
* '''Note:''' Make sure your running kernel supports 16bit UIDs for backward compatibility. uCLibc needs them. Check it with:<br />
<br />
zcat /proc/config.gz | grep CONFIG_UID16<br />
<br />
<br />
== Step-by-step ==<br />
All packages are downloaded from http://dev.alpinelinux.org/alpine/v1.7<br />
<br />
* Download latest buildroot package from [http://dev.alpinelinux.org/alpine/v1.7/buildroot/] and unpack it in /opt/alpine, using the --preserve-permissions option and create a symblink named 1.7 for the development branch.<br />
<br />
sudo mkdir -p /opt/alpine<br />
cd /opt/alpine<br />
wget -q -O - http://dev.alpinelinux.org/alpine/v1.7/buildroot/alpine-buildroot-latest.tar.bz2\<br />
| sudo tar -vjxp<br />
sudo ln -s alpine-buildroot-1.7.6 1.7<br />
<br />
<br />
* Copy your DNS configuration to the build environment and mount proc.<br />
<br />
sudo cp /etc/resolv.conf /opt/alpine/1.7/etc/<br />
sudo mount -t proc proc /opt/alpine/1.7/proc<br />
sudo mount -o bind /dev /opt/alpine/1.7/dev<br />
<br />
* Enter the chroot<br />
<br />
sudo chroot /opt/alpine/1.7 /bin/bash --login<br />
<br />
Now we are in the build environment chroot.<br />
<br />
* Download latest portage snapshot [http://mirror.gentoo.se/snapshots/portage-latest.tar.bz2 portage-latest.tar.bz2] from Gentoo and unpack it to /usr<br />
<br />
cd /usr<br />
wget -q -O - http://mirror.gentoo.se/snapshots/portage-latest.tar.bz2 portage-latest.tar.bz2 | tar -vjx<br />
<br />
* Check out the alpine-portage overlay from svn.<br />
<br />
svn co svn://svn.alpinelinux.org/alpine-portage/trunk /usr/alpine-portage<br />
<br />
* Download all the [http://dl.alpinelinux.org/alpine/v1.7/tbz2 tbz2] packages into the var/cache/packages directory. This is probably easiest with rsync.<br />
<br />
rsync -rauv rsync://rsync.alpinelinux.org/alpine/v1.7/tbz2/* /var/cache/packages/<br />
<br />
* Check out the alpine-builder scripts in usr/src/<br />
<br />
svn co svn://svn.alpinelinux.org/alpine-builder/trunk /usr/src/alpine<br />
<br />
* Configure portage to use the config from alpine-builder.<br />
<br />
rm -r /etc/make.conf /etc/portage<br />
ln -s /usr/src/alpine/buildroot/etc/make.conf /etc<br />
ln -s /usr/src/alpine/buildroot/etc/portage /etc<br />
<br />
* Update the portage tree (this takes some time first time you do it)<br />
<br />
emerge --sync<br />
<br />
* Install the kernel sources, using the downloaded tbz2. <br />
<br />
''This step is no longer neccessary as this is done automatically within the build script.''<br />
<br />
* Make sure that /usr/src/linux points to your kernel version: ''(the below mentioned steps are optional as this is done automatically by the alpine build process - in case your build breaks, check if the linux source link exists)''<br />
<br />
cd /usr/src<br />
rm -f linux<br />
ln -s linux-2.6.20-hardened-r10 linux<br />
<br />
* Build the alpine images (iso, usb, flash, etc.)<br />
<br />
cd /usr/src/alpine<br />
make<br />
<br />
If you get failures while building kernel drivers then you can workaround that by commenting out the specific in ''/usr/src/alpine/kernel/generic/drivers''.</div>Macbrodyhttps://wiki.alpinelinux.org/w/index.php?title=Setting_up_the_build_environment_1.7&diff=1602Setting up the build environment 1.72007-10-17T20:46:29Z<p>Macbrody: add some explanations</p>
<hr />
<div>Quick note on how to set up a build environment.<br />
<br />
In this document the build environment will be created in /opt/alpine/1.7. You can ofcourse place it anywhere you have space.<br />
You will need a few Gigabytes to have enough space for kernel cmpiling and storing all the binary packages and iso image.<br />
<br />
== Requirements ==<br />
You need a 2.6 kernel to use the chroot build environment.<br />
<br />
* '''Note:''' Make sure your running kernel supports 16bit UIDs for backward compatibility. uCLibc needs them. Check it with:<br />
<br />
zcat /proc/config.gz | grep CONFIG_UID16<br />
<br />
<br />
== Step-by-step ==<br />
All packages are downloaded from http://dev.alpinelinux.org/alpine/v1.7<br />
<br />
* Download latest buildroot package from [http://dev.alpinelinux.org/alpine/v1.7/buildroot/] and unpack it in /opt/alpine, using the --preserve-permissions option and create a symblink named 1.7 for the development branch.<br />
<br />
sudo mkdir -p /opt/alpine<br />
cd /opt/alpine<br />
wget -q -O - http://dev.alpinelinux.org/alpine/v1.7/buildroot/alpine-buildroot-latest.tar.bz2\<br />
| sudo tar -vjxp<br />
sudo ln -s alpine-buildroot-1.7.6 1.7<br />
<br />
<br />
* Copy your DNS configuration to the build environment and mount proc.<br />
<br />
sudo cp /etc/resolv.conf /opt/alpine/1.7/etc/<br />
sudo mount -t proc proc /opt/alpine/1.7/proc<br />
sudo mount -o bind /dev /opt/alpine/1.7/dev<br />
<br />
* Enter the chroot<br />
<br />
sudo chroot /opt/alpine/1.7 /bin/bash --login<br />
<br />
Now we are in the build environment chroot.<br />
<br />
* Download latest portage snapshot [http://mirror.gentoo.se/snapshots/portage-latest.tar.bz2 portage-latest.tar.bz2] from Gentoo and unpack it to /usr<br />
<br />
cd /usr<br />
wget -q -O - http://mirror.gentoo.se/snapshots/portage-latest.tar.bz2 portage-latest.tar.bz2 | tar -vjx<br />
<br />
* Check out the alpine-portage overlay from svn.<br />
<br />
svn co svn://svn.alpinelinux.org/alpine-portage/trunk /usr/alpine-portage<br />
<br />
* Download all the [http://dl.alpinelinux.org/alpine/v1.7/tbz2 tbz2] packages into the var/cache/packages directory. This is probably easiest with rsync.<br />
<br />
rsync -rauv rsync://rsync.alpinelinux.org/alpine/v1.7/tbz2/* /var/cache/packages/<br />
<br />
* Check out the alpine-builder scripts in usr/src/<br />
<br />
svn co svn://svn.alpinelinux.org/alpine-builder/trunk /usr/src/alpine<br />
<br />
* Configure portage to use the config from alpine-builder.<br />
<br />
rm -r /etc/make.conf /etc/portage<br />
ln -s /usr/src/alpine/buildroot/etc/make.conf /etc<br />
ln -s /usr/src/alpine/buildroot/etc/portage /etc<br />
<br />
* Update the portage tree (this takes some time first time you do it)<br />
<br />
emerge --sync<br />
<br />
* Install the kernel sources, using the downloaded tbz2. <br />
<br />
''This step is no longer neccessary as this is done automatically within the build script.''<br />
<br />
* Make sure that /usr/src/linux points to your kernel version: ''(the below mentioned steps are optional as this is done automatically by the alpine build process - in case your build breaks, check if the linux source link exists)''<br />
<br />
cd /usr/src<br />
rm -f linux<br />
ln -s linux-2.6.20-hardened-r6 linux<br />
<br />
* Build the alpine images (iso, usb, flash, etc.)<br />
<br />
cd /usr/src/alpine<br />
make<br />
<br />
If you get failures while building kernel drivers then you can workaround that by commenting out the specific in ''/usr/src/alpine/kernel/generic/drivers''.</div>Macbrodyhttps://wiki.alpinelinux.org/w/index.php?title=Setting_up_the_build_environment_1.7&diff=1555Setting up the build environment 1.72007-09-21T09:43:18Z<p>Macbrody: emerging the kernel sources is no longer neccessary</p>
<hr />
<div>Quick note on how to set up a build environment.<br />
<br />
In this document the build environment will be created in /opt/alpine/1.7. You can ofcourse place it anywhere you have space.<br />
You will need a few Gigabytes to have enough space for kernel cmpiling and storing all the binary packages and iso image.<br />
<br />
== Requirements ==<br />
You need a 2.6 kernel to use the chroot build environment.<br />
<br />
* '''Note:''' Make sure your running kernel supports 16bit UIDs for backward compatibility. uCLibc needs them. Check it with:<br />
<br />
zcat /proc/config.gz | grep CONFIG_UID16<br />
<br />
<br />
== Step-by-step ==<br />
All packages are downloaded from http://dl.alpinelinux.org/alpine/v1.7<br />
<br />
* Download latest buildroot package from [http://dl.alpinelinux.org/alpine/v1.7/buildroot/] and unpack it in /opt/alpine, using the --preserve-permissions option and create a symblink named 1.7 for the development branch.<br />
<br />
sudo mkdir -p /opt/alpine<br />
cd /opt/alpine<br />
wget -q -O - http://dl.alpinelinux.org/alpine/v1.7/buildroot/alpine-buildroot-1.7.2.tar.bz2 | sudo tar -vjxp<br />
sudo ln -s alpine-buildroot-1.7.2 1.7<br />
<br />
<br />
* Copy your DNS configuration to the build environment and mount proc.<br />
<br />
sudo cp /etc/resolv.conf /opt/alpine/1.7/etc/<br />
sudo mount -t proc proc /opt/alpine/1.7/proc<br />
sudo mount -o bind /dev /opt/alpine/1.7/dev<br />
<br />
* Enter the chroot<br />
<br />
sudo chroot /opt/alpine/1.7 /bin/bash --login<br />
<br />
Now we are in the build environment chroot.<br />
<br />
* Download latest portage snapshot [http://mirror.gentoo.se/snapshots/portage-latest.tar.bz2 portage-latest.tar.bz2] from Gentoo and unpack it to /usr<br />
<br />
cd /usr<br />
wget -q -O - http://mirror.gentoo.se/snapshots/portage-latest.tar.bz2 portage-latest.tar.bz2 | tar -vjx<br />
<br />
* Check out the alpine-portage overlay from svn.<br />
<br />
svn co svn://svn.alpinelinux.org/alpine-portage/trunk /usr/alpine-portage<br />
<br />
* Download all the [http://dl.alpinelinux.org/alpine/v1.7/tbz2 tbz2] packages into the var/cache/packages directory. This is probably easiest with rsync.<br />
<br />
rsync -rauv rsync://rsync.alpinelinux.org/alpine/v1.7/tbz2/* /var/cache/packages/<br />
<br />
* Check out the alpine-builder scripts in usr/src/<br />
<br />
svn co svn://svn.alpinelinux.org/alpine-builder/trunk /usr/src/alpine<br />
<br />
* Configure portage to use the config from alpine-builder.<br />
<br />
rm -r /etc/make.conf /etc/portage<br />
ln -s /usr/src/alpine/buildroot/etc/make.conf /etc<br />
ln -s /usr/src/alpine/buildroot/etc/portage /etc<br />
<br />
* Update the portage tree (this takes some time first time you do it)<br />
<br />
emerge --sync<br />
<br />
* Install the kernel sources, using the downloaded tbz2. <br />
<br />
''This step is no longer neccessary as this is done automatically within the build script.''<br />
<br />
* Make sure that /usr/src/linux points to your kernel version:<br />
<br />
cd /usr/src<br />
rm -f linux<br />
ln -s linux-2.6.20-hardened-r6 linux<br />
<br />
* Build the iso image<br />
<br />
cd /usr/src/alpine<br />
make<br />
<br />
If you get failures while building kernel drivers then you can workaround that by commenting out the specific in ''/usr/src/alpine/kernel/generic/drivers''.</div>Macbrodyhttps://wiki.alpinelinux.org/w/index.php?title=Setting_up_the_build_environment_1.7&diff=1554Setting up the build environment 1.72007-09-21T09:42:37Z<p>Macbrody: </p>
<hr />
<div>Quick note on how to set up a build environment.<br />
<br />
In this document the build environment will be created in /opt/alpine/1.7. You can ofcourse place it anywhere you have space.<br />
You will need a few Gigabytes to have enough space for kernel cmpiling and storing all the binary packages and iso image.<br />
<br />
== Requirements ==<br />
You need a 2.6 kernel to use the chroot build environment.<br />
<br />
* '''Note:''' Make sure your running kernel supports 16bit UIDs for backward compatibility. uCLibc needs them. Check it with:<br />
<br />
zcat /proc/config.gz | grep CONFIG_UID16<br />
<br />
<br />
== Step-by-step ==<br />
All packages are downloaded from http://dl.alpinelinux.org/alpine/v1.7<br />
<br />
* Download latest buildroot package from [http://dl.alpinelinux.org/alpine/v1.7/buildroot/] and unpack it in /opt/alpine, using the --preserve-permissions option and create a symblink named 1.7 for the development branch.<br />
<br />
sudo mkdir -p /opt/alpine<br />
cd /opt/alpine<br />
wget -q -O - http://dl.alpinelinux.org/alpine/v1.7/buildroot/alpine-buildroot-1.7.2.tar.bz2 | sudo tar -vjxp<br />
sudo ln -s alpine-buildroot-1.7.2 1.7<br />
<br />
<br />
* Copy your DNS configuration to the build environment and mount proc.<br />
<br />
sudo cp /etc/resolv.conf /opt/alpine/1.7/etc/<br />
sudo mount -t proc proc /opt/alpine/1.7/proc<br />
sudo mount -o bind /dev /opt/alpine/1.7/dev<br />
<br />
* Enter the chroot<br />
<br />
sudo chroot /opt/alpine/1.7 /bin/bash --login<br />
<br />
Now we are in the build environment chroot.<br />
<br />
* Download latest portage snapshot [http://mirror.gentoo.se/snapshots/portage-latest.tar.bz2 portage-latest.tar.bz2] from Gentoo and unpack it to /usr<br />
<br />
cd /usr<br />
wget -q -O - http://mirror.gentoo.se/snapshots/portage-latest.tar.bz2 portage-latest.tar.bz2 | tar -vjx<br />
<br />
* Check out the alpine-portage overlay from svn.<br />
<br />
svn co svn://svn.alpinelinux.org/alpine-portage/trunk /usr/alpine-portage<br />
<br />
* Download all the [http://dl.alpinelinux.org/alpine/v1.7/tbz2 tbz2] packages into the var/cache/packages directory. This is probably easiest with rsync.<br />
<br />
rsync -rauv rsync://rsync.alpinelinux.org/alpine/v1.7/tbz2/* /var/cache/packages/<br />
<br />
* Check out the alpine-builder scripts in usr/src/<br />
<br />
svn co svn://svn.alpinelinux.org/alpine-builder/trunk /usr/src/alpine<br />
<br />
* Configure portage to use the config from alpine-builder.<br />
<br />
rm -r /etc/make.conf /etc/portage<br />
ln -s /usr/src/alpine/buildroot/etc/make.conf /etc<br />
ln -s /usr/src/alpine/buildroot/etc/portage /etc<br />
<br />
* Update the portage tree (this takes some time first time you do it)<br />
<br />
emerge --sync<br />
<br />
* Install the kernel sources, using the downloaded tbz2. <br />
<br />
''This step is no longer neccessary as this is done automatically within the build script.''<br />
<br />
<br />
* Make sure that /usr/src/linux points to your kernel version:<br />
<br />
cd /usr/src<br />
rm -f linux<br />
ln -s linux-2.6.20-hardened-r6 linux<br />
<br />
* Build the iso image<br />
<br />
cd /usr/src/alpine<br />
make<br />
<br />
If you get failures while building kernel drivers then you can workaround that by commenting out the specific in ''/usr/src/alpine/kernel/generic/drivers''.</div>Macbrodyhttps://wiki.alpinelinux.org/w/index.php?title=Setting_up_the_build_environment_1.7&diff=1553Setting up the build environment 1.72007-09-21T09:41:50Z<p>Macbrody: </p>
<hr />
<div>Quick note on how to set up a build environment.<br />
<br />
In this document the build environment will be created in /opt/alpine/1.7. You can ofcourse place it anywhere you have space.<br />
You will need a few Gigabytes to have enough space for kernel cmpiling and storing all the binary packages and iso image.<br />
<br />
== Requirements ==<br />
You need a 2.6 kernel to use the chroot build environment.<br />
<br />
* '''Note:''' Make sure your running kernel supports 16bit UIDs for backward compatibility. uCLibc needs them. Check it with:<br />
<br />
zcat /proc/config.gz | grep CONFIG_UID16<br />
<br />
<br />
== Step-by-step ==<br />
All packages are downloaded from http://dl.alpinelinux.org/alpine/v1.7<br />
<br />
* Download latest buildroot package from [http://dl.alpinelinux.org/alpine/v1.7/buildroot/] and unpack it in /opt/alpine, using the --preserve-permissions option and create a symblink named 1.7 for the development branch.<br />
<br />
sudo mkdir -p /opt/alpine<br />
cd /opt/alpine<br />
wget -q -O - http://dl.alpinelinux.org/alpine/v1.7/buildroot/alpine-buildroot-1.7.2.tar.bz2 | sudo tar -vjxp<br />
sudo ln -s alpine-buildroot-1.7.2 1.7<br />
<br />
<br />
* Copy your DNS configuration to the build environment and mount proc.<br />
<br />
sudo cp /etc/resolv.conf /opt/alpine/1.7/etc/<br />
sudo mount -t proc proc /opt/alpine/1.7/proc<br />
sudo mount -o bind /dev /opt/alpine/1.7/dev<br />
<br />
* Enter the chroot<br />
<br />
sudo chroot /opt/alpine/1.7 /bin/bash --login<br />
<br />
Now we are in the build environment chroot.<br />
<br />
* Download latest portage snapshot [http://mirror.gentoo.se/snapshots/portage-latest.tar.bz2 portage-latest.tar.bz2] from Gentoo and unpack it to /usr<br />
<br />
cd /usr<br />
wget -q -O - http://mirror.gentoo.se/snapshots/portage-latest.tar.bz2 portage-latest.tar.bz2 | tar -vjx<br />
<br />
* Check out the alpine-portage overlay from svn.<br />
<br />
svn co svn://svn.alpinelinux.org/alpine-portage/trunk /usr/alpine-portage<br />
<br />
* Download all the [http://dl.alpinelinux.org/alpine/v1.7/tbz2 tbz2] packages into the var/cache/packages directory. This is probably easiest with rsync.<br />
<br />
rsync -rauv rsync://rsync.alpinelinux.org/alpine/v1.7/tbz2/* /var/cache/packages/<br />
<br />
* Check out the alpine-builder scripts in usr/src/<br />
<br />
svn co svn://svn.alpinelinux.org/alpine-builder/trunk /usr/src/alpine<br />
<br />
* Configure portage to use the config from alpine-builder.<br />
<br />
rm -r /etc/make.conf /etc/portage<br />
ln -s /usr/src/alpine/buildroot/etc/make.conf /etc<br />
ln -s /usr/src/alpine/buildroot/etc/portage /etc<br />
<br />
* Update the portage tree (this takes some time first time you do it)<br />
<br />
emerge --sync<br />
<br />
* Install the kernel sources, using the downloaded tbz2. <br />
<br />
''This step is no longer neccessary as this is done automatically within the build script.''<br />
<br />
Note that its a "precompiled" source package. It means it contains the kernel sources.<br />
<br />
* Make sure that /usr/src/linux points to your kernel version:<br />
<br />
cd /usr/src<br />
rm -f linux<br />
ln -s linux-2.6.20-hardened-r6 linux<br />
<br />
* Build the iso image<br />
<br />
cd /usr/src/alpine<br />
make<br />
<br />
If you get failures while building kernel drivers then you can workaround that by commenting out the specific in ''/usr/src/alpine/kernel/generic/drivers''.</div>Macbrodyhttps://wiki.alpinelinux.org/w/index.php?title=ACF_core_principles&diff=1535ACF core principles2007-09-18T06:28:01Z<p>Macbrody: Copied page from old wiki</p>
<hr />
<div>While the mvc.lua code provides a generic framework for any lua "mvc"-based appliction, "acf" is the component that makes the mvc.lua framework into a configuration Application. Some ideas and rationales for application-wide settings are discussed here.<br />
<br />
= Use of ''cfe'' =<br />
<br />
A ''cfe'' ('''C'''onfiguration '''F'''ramework '''E'''ntity) is a way to pass data between a model,controller and view in a common way. There are many ways to do this (e.g. closures, AKClass); use of cfe is an arbitrary decision just to keep development moving forward.<br />
<br />
A cfe is a table with some fields guaranteed to exist. It is also a way to abstract user-modifiable data from view-centric html input types. ACF isn't necessarily web-only. With a different controller and views, it could be cli (or gui?!)<br />
<br />
== Fields in all cfes ==<br />
<br />
cfe's are constructed from a function in <tt>acf-controller.lua</tt> that returns an anonymous table with the following fields<br />
<br />
{| border=1<br />
! Field !! Default !! Description<br />
|-<br />
|value || empty ||The value of the cfe (e.g. the ip address, hostname, password, etc.)<br />
|-<br />
|type || text || The type of entity (see below)<br />
|-<br />
|option ||empty ||common modifiers for this type of cfe<br />
|- <br />
|errtxt || empty ||text explaining why validation failed<br />
|}<br />
<br />
The reason for having these fields pre-defined is to allow models,controllers and views to use the indexes without having to first check if they exist. For example the entity will always have a value and type.<br />
<br />
cfe's can have other fields, or can have their defaults overwritten by specifying a table in the argument list to the cfe constructor:<br />
<br />
:mycfe = cfe({label="Foo", type="boolean", value=true})<br />
is equivalent to<br />
:mycfe = {value=true, type="boolean", option="", errtxt="", label="Foo"}<br />
<br />
== cfe types ==<br />
<br />
The ''type'' field of a cfe can be one of the following:<br />
<br />
{|<br />
|-<br />
! type !! Description !! Modifiers <br />
|-<br />
| text || a text field, typically one line of text ||<br />
|-<br />
| longtext || a multi-line text field, like a textarea ||<br />
|-<br />
| select || a select list || ''value'' is the currently selected item <br>''option'' is a table of select options <br />
|-<br />
| boolean || a checkbox ||<br />
|-<br />
| action || a submit button or link to an action || ''option'' is a table with keys of "prefix", "controller", "action", etc <br />
|-<br />
| message || a text message || typically used for something the view should not allow the user to change.<br />
|-<br />
| raw || raw binary data || <br />
|-<br />
| closure || a function || <br />
|-<br />
| form || a set of cfe's that make up a form || ''value'' is a table of cfes<br>''option'' is a table with keys of "prefix", "controller", "action", etc.<br />
|-<br />
| group || a set of cfe's that make up an anonymous group || ''value'' is a table of grouped cfes (can be used when several cfe's share the same name)<br />
|}<br />
<br />
<br />
= Use of CRUD =<br />
<br />
CRUD stands for Create Read Update Delete. Where possible, ACF models/controllers should follow this pattern. To help reuse of code, the functions in models and controllers should have one of Cread Read Update or Delete in their names (create_interface_by_name, update_hostname, delete_package, read_timezone, etc.)<br />
<br />
= Use of cmd =<br />
<br />
The use of a standard "do this" cfe in all acf controllers may also allow more reuse. It is suggested to use "cmd" as the ''name'' of this cfe, with the value being the command to perform.<br />
<br />
<br />
= The Model defines the object set =<br />
<br />
The model is responsible for writing and reading from the running system. The model also does not need to know which part of a specific acf module it is running under. It is not mandatory that the model be lua "oop" as the rest of the system is. (the model may not have any need to know "self")<br />
<br />
<br />
Since the model can choose how much or how little of the system to expose, the basic data set should be defined in the model (perhaps as a constructor function)</div>Macbrodyhttps://wiki.alpinelinux.org/w/index.php?title=ACF_mvc.lua_reference&diff=1534ACF mvc.lua reference2007-09-18T06:27:24Z<p>Macbrody: Copied page from old wiki</p>
<hr />
<div>= The Model Viewer Controller (mvc.lua) Module =<br />
<br />
mvc.lua is a proposed framework for building acf, the alpine configuration framework. This page demonstrates how to build a very simple application using mvc.lua and haserl. This is the "Haserl Light Rail" framework<br />
<br />
== Architecture ==<br />
<br />
mvc.lua has a ''':new''' constructor that creates a mvc "object". Through the use of metatable ._index methods, these objects are nested to construct the MVC based application:<br />
<br />
/-----------------------------------------------------------\ <br />
| |<br />
| the "mvc" object, with default methods and properties |<br />
| |<br />
| /-------------------------------------------\|<br />
| | |<br />
| | the "application" object |<br />
| | |<br />
| | /---------------------------------\|<br />
| | | the "controller" object |<br />
| \ \ |<br />
\-----------------------------------------------------------/<br />
<br />
Each of these objects are the same - they are built from the core mvc:new function, but with "lua-style" oop. (They inherit some properties from the parent.)<br />
<br />
Each mvc object contains:<br />
{|-<br />
|worker<br />
|The controller (A table of controller methods), as well as an optional initializer.<br />
|-<br />
|model<br />
|The model (A table of model methods)<br />
|-<br />
|conf<br />
|A table of configuration parameters - application name, config file, application directory, selected prefix, controller, action, etc.<br />
|-<br />
|clientdata<br />
|A table for user supplied data.<br />
|-<br />
|view_resolver<br />
|A function that finds the view, and returns it as a function<br />
|-<br />
|exception_handler<br />
|A function that gets called if an error occurs<br />
|-<br />
|other local methods<br />
|as needed<br />
|}<br />
<br />
== The framework is not an application ==<br />
mvc.lua provides everything to build a web-based mvc application, ''but it is not a full application.'' Normally, the application will call ''':dispatch()''', which performs the following steps:<br />
<br />
# Determine the application name <br />
# Load the configuration file if found<br />
# Parse the prefix, controller and action <br />
# Create an application object<br />
# Run the application's worker.init function (if found)<br />
# Create a controller object<br />
# Run the controller's worker.init function (if found)<br />
# Run the contoller's worker.[action] method<br />
# Run the view, based on the controller's view_resolver function<br />
<br />
The application must supply a view_resolver function. It is assumed the worker.[action] method will return a table. This table is passed to the view_resolver and the view render functions. The format of the table is up to the application.<br />
<br />
= Building a Sample Application =<br />
<br />
For this demo, we will use alpine, busybox httpd, and haserl to create a simple "hostname" setting application. The Application name will be "helloworld", and it will have one controller, "hostname". The application code will reside at /var/lib/app.<br />
<br />
== Step 1 - Get the web interface going ==<br />
<br />
* Edit /etc/inetd.conf and add the following line: <br />
www stream tcp nowait root /bin/busybox httpd -h /var/lib/www<br />
* kill -HUP $( pidof inetd )<br />
* mkdir -p /var/lib/www/cgi-bin<br />
* mkdir -p /etc/helloworld<br />
* Use your browser to make sure that ''http://<hostname>/cgi-bin/helloword'' results in a 404 error.<br />
* copy mvc.lua to /var/lib/www/cgi-bin '''or'' to /usr/local/lib/lua/5.1<br />
* create /var/lib/www/cgi-bin/helloworld:<br />
#!/usr/bin/haserl --shell=lua<br />
<?<br />
require("mvc")<br />
mvc.dispatch(mvc:new())<br />
?><br />
* chmod +x /var/lib/www/cgi-bin/helloworld<br />
* Use your browser to go to ''http://<hostname>/cgi-bin/helloworld/hostname/get'' <br />
<br />
If you see this, everything is working!<br />
<br />
The following unhandled application error occured:<br />
<br />
<br />
./mvc.lua:62: attempt to call field '?' (a nil value)<br />
stack traceback:<br />
./mvc.lua:62: in function <./mvc.lua:52><br />
[C]: in function 'xpcall'<br />
./mvc.lua:52: in function 'dispatch'<br />
[string "..."]:6: in main chunk<br />
<br />
<br />
''What's happened:'' We created the basic application, and the mvc object ran, caught and reported the error.<br />
<br />
== Step 2. Configure the Application ==<br />
<br />
* Edit /etc/helloworld/helloworld.conf and add:<br />
<br />
# The helloworld configuration parameters<br />
<br />
appdir = /var/lib/app/<br />
<br />
(The trailing / is important)<br />
<br />
''What's happened:'' We told the application where it will reside. The ''':new''' method looks in several places for a configuration file named with the appname (''helloworld'')<br />
<br />
== Step 3. Create the model and controller ==<br />
<br />
* Create '''/var/lib/app/hostname-controller.lua'''<br />
<br />
-- The "hostname" controller<br />
module( ... , package.seeall)<br />
<br />
<br />
-- Initialization goes here, if there were any. This controller has no specific<br />
-- initialization steps<br />
init = function (self, parent)<br />
end<br />
<br />
-- Public methods. Any of these methods can be called directly from the client<br />
-- <prefix>/hostname/get<br />
get = function (self)<br />
return ( { hostname = self.model:get() } )<br />
end<br />
<br />
-- <prefix>/hostname/set<br />
set = function (self)<br />
return ( { hostname = self.model:set(self.clientdata.hostname) } )<br />
end<br />
<br />
* Create '''/var/lib/app/hostname-model.lua'''<br />
<br />
-- the hostname model functions<br />
module( ... , package.seeall)<br />
<br />
-- The model does not have an initializer. Use the controller (worker) for that.<br />
<br />
-- Public methods. Use a local table for private methods<br />
get = function (self)<br />
local f = io.popen("/bin/hostname")<br />
local n = f:read("*a") or "unknown"<br />
f:close()<br />
return ( n )<br />
end<br />
<br />
<br />
set = function (self, name)<br />
local f = io.open("/etc/hostname", "w")<br />
if f then<br />
f:write(name)<br />
f:close()<br />
end<br />
f = io.popen ("/bin/hostname -F /etc/hostname")<br />
f:close()<br />
return get(self)<br />
end<br />
<br />
* Use your browser to go to ''http://<hostname>/cgi-bin/helloworld/hostname/get'' <br />
<br />
Your controller and application did not specify a view resolver.<br />
The MVC framework has no view available. sorry.<br />
<br />
''What Happened:'' The mvc framework ran your controller (which ran your model code)!!! Success! Unfortunately, the framework doesn't know how to render the results, so we get the generic mvc:view_resolver results.<br />
<br />
== Step 4. Create an Application Controller ==<br />
<br />
We could fix the problem by creating a view_resolver in '''hostname-controller.lua''', but that would only work for that one controller. Instead, we will create a method in the ''application'' controller that will apply to all controllers.<br />
<br />
* Create '''/var/lib/app/helloworld-controller.lua'''<br />
<br />
-- The APPLICATION worker table. This gets loaded once for the application<br />
module( ... , package.seeall)<br />
<br />
-- A table for private methods<br />
local private = {}<br />
<br />
-- This function gets run when this module is loaded. Note that in this case,<br />
-- "self" refers to the object as a whole. In the other cases, "self" will<br />
-- refer to the "self.worker" table objects<br />
init = function (self, parent)<br />
-- do some final fixup on ourselves<br />
-- the framework doesn't provide a view_resolver, so we do<br />
self.view_resolver = private.view_resolver<br />
end<br />
<br />
-- Returns the function to render the view. We make it private so that nobody calls it as a method.<br />
private.view_resolver = function(self)<br />
local filename, file<br />
filename = self.conf.appdir .. self.conf.prefix .. self.conf.controller .. "-view.lsp"<br />
file = io.open(filename)<br />
if file then<br />
file:close()<br />
return haserl.loadfile(filename)<br />
else<br />
return function() end -- return a blank screen<br />
end<br />
end<br />
<br />
* Create a '''/var/lib/app/hostname-view.lsp'''<br />
<br />
<? local view = ... ?><br />
Content-type: text/html<br />
<br />
<html><br />
<body><br />
&lt;h1>Hello World!&lt;/h1><br />
&lt;p>The hostname is <?= view.hostname ?>&lt;/p><br />
</body><br />
</html><br />
<br />
* Use your browser to go to ''http://<hostname>/cgi-bin/helloworld/hostname/get'' <br />
<br />
Hello World!<br />
<br />
The hostname is Alpine <br />
<br />
<br />
''What Happened:'' All functions in a module are normally public methods. The init function in the Application controller is actually <sometable>.worker.init. Since we don't want the view_resolver to be a public method (e.g. ''http://hostname/cgi-bin/helloworld/hostname/view_resover'') we put it in a private table. We then override the Application's view_resolver method with our new method. Note that the active view_resolver is a method of the object itself, not of the object's worker table, so we must set self.view_resolver. (The init function is the only function where self is the the object as a whole. All other functions receive self as object.worker) <br />
<br />
<br />
The view resolver uses haserl's loadfile function to process the "lsp" style page. We make the function generic so that it will work with any controller. We then define a simple .lsp file.<br />
<br />
When the application runs, it runs all the way through, looks for a '''hostname.view_resolver''' function, and when it can't find one, uses the '''application.view_resolver ''' function instead. Life is good!<br />
<br />
== Step 5. Get User Input ==<br />
<br />
* Set the hostname with: ''http://<hostname>/cgi-bin/helloworld/hostname/set?hostname=Desert'' <br />
<br />
The following unhandled application error occured:<br />
<br />
<br />
/var/lib/app//hostname-model.lua:18: bad argument #1 to 'write' (string expected, got nil)<br />
stack traceback:<br />
[C]: in function 'write'<br />
/var/lib/app//hostname-model.lua:18: in function 'set'<br />
/var/lib/app//hostname-controller.lua:19: in function '?'<br />
./mvc.lua:62: in function <./mvc.lua:52><br />
[C]: in function 'xpcall'<br />
./mvc.lua:52: in function 'dispatch'<br />
[string "..."]:6: in main chunk<br />
<br />
The mvc framework does not know how to get user input. That is the application's responsibility. So let's edit the application controller and add clientdata:<br />
<br />
* Edit '''/var/lib/app/helloworld-controller.lua''' and add this to the init function:<br />
<br />
-- The application must populate the clientdata table<br />
self.clientdata = FORM<br />
* Set the hostname with: ''http://<hostname>/cgi-bin/helloworld/hostname/set?hostname=Desert'' <br />
<br />
Hello World!<br />
<br />
The hostname is Desert <br />
<br />
<br />
''What Happened:'' Since the application could be CLI, Web, or GUI, the framework makes no assumptions on how to get user input to the controller. So the Application controller must do that. In this case, we just accept FORM from haserl.<br />
<br />
== Step 6. Move the Controller and Application ==<br />
<br />
This step is just to show that the framework is flexible. We're going to change the name of the application and where the controller is, at the same time.<br />
<br />
<br />
* mv /etc/helloworld /etc/acf<br />
* mv /etc/acf/helloworld.conf /etc/acf/acf.conf<br />
* mv /var/lib/www/cgi-bin/helloworld /var/lib/www/cgi-bin/acf<br />
* mkdir /var/lib/app/alpine-base<br />
* mv /var/lib/app/hostname* /var/lib/app/alpine-base<br />
* mv /var/lib/app/helloworld-controller.lua /var/lib/app/acf-controller.lua<br />
* Go to ''http://<hostname>/cgi-bin/acf/alpine-base/hostname/get<br />
<br />
== Summary ==<br />
<br />
To build an application, you must provide:<br />
<br />
# The config file<br />
# A <application>-controller.lua - with a view_resolver (and exception_handler, if desired)<br />
# <controller>-controller.lua and optionally <controller>-model.lua<br />
# A function to produce the view output</div>Macbrodyhttps://wiki.alpinelinux.org/w/index.php?title=Alpine_Configuration_Framework_Design&diff=1533Alpine Configuration Framework Design2007-09-18T06:26:47Z<p>Macbrody: Copied page from old wiki</p>
<hr />
<div>The Alpine Configuration Framework (ACF) is a mvc-style application for configuring an Alpine device. These pages document some of the underlying principles of the framework<br />
<br />
* [[Introduction to the mvc.lua core module]] (The core "mvc" part of the application)<br />
* [[ACF core principles]] (Things that are standard across the application)</div>Macbrodyhttps://wiki.alpinelinux.org/w/index.php?title=Creating_patches&diff=1532Creating patches2007-09-18T06:25:43Z<p>Macbrody: Copied page from old wiki</p>
<hr />
<div>= Creating patches for aports =<br />
<br />
After you did a checkout of the svn-sources you might want to add your changes to the '''apk-packages''' you build. ''(note: this applies to packages only to apk packages in aports directory)''<br />
<br />
The easiest way is the following:<br />
<br />
# Go to the package you want to edit, for example dhcp:<br />
% cd ~/SVN/alpine-builder/trunk/packages/aports/dhcp<br />
<br />
<br />
Make sure you have the upstream precompiled binary package:<br />
% aports/dhcp% scp username@deva:/var/www/localhost/htdocs/alpine/v1.3/binpkgs/dhcp-3.0.3-r9.bin.tar.bz2 ~/SVN/alpine-builder/trunk/packages/binpkgs<br />
<br />
<br />
Clean up unpack the binary package as .orig copy.<br />
% make clean && make orig<br />
<br />
Make your chages<br />
% vim work/data/etc/init.d/dhcp<br />
<br />
Now make sure you have no stale files lying around like ''work/data/etc/init.d/dhcp~''.<br />
Check that everything looks ok<br />
% make diff<br />
<br />
Create the patch directory if it does not exist:<br />
% mkdir -p patches<br />
<br />
Create the patch. It must has the .patch extension. Try to give it a meaningful name.<br />
% make diff > patches/10-mypatch.patch<br />
<br />
Rebuild the package with the patch.<br />
% make clean && make<br />
<br />
Test your package and verify it works as expected.<br />
<br />
Add it to svn:<br />
% svn add patches/10-mypatch.patch<br />
<br />
You can send the patch(es) to the [http://lists.alpinelinux.org/mailman/listinfo/alpine-devel alpine-devel] mailing list if you dont have svn commit access,</div>Macbrodyhttps://wiki.alpinelinux.org/w/index.php?title=Setting_up_the_build_environment_1.7&diff=1531Setting up the build environment 1.72007-09-18T06:23:55Z<p>Macbrody: Copied page from old wiki</p>
<hr />
<div>Quick note on how to set up a build environment.<br />
<br />
In this document the build environment will be created in /opt/alpine/1.7. You can ofcourse place it anywhere you have space.<br />
You will need a few Gigabytes to have enough space for kernel cmpiling and storing all the binary packages and iso image.<br />
<br />
== Requirements ==<br />
You need a 2.6 kernel to use the chroot build environment.<br />
<br />
* '''Note:''' Make sure your running kernel supports 16bit UIDs for backward compatibility. uCLibc needs them. Check it with:<br />
<br />
zcat /proc/config.gz | grep CONFIG_UID16<br />
<br />
<br />
== Step-by-step ==<br />
All packages are downloaded from http://dl.alpinelinux.org/alpine/v1.7<br />
<br />
* Download latest buildroot package from [http://dl.alpinelinux.org/alpine/v1.7/buildroot/] and unpack it in /opt/alpine, using the --preserve-permissions option and create a symblink named 1.7 for the development branch.<br />
<br />
sudo mkdir -p /opt/alpine<br />
cd /opt/alpine<br />
wget -q -O - http://dl.alpinelinux.org/alpine/v1.7/buildroot/alpine-buildroot-1.7.2.tar.bz2 | sudo tar -vjxp<br />
sudo ln -s alpine-buildroot-1.7.2 1.7<br />
<br />
<br />
* Copy your DNS configuration to the build environment and mount proc.<br />
<br />
sudo cp /etc/resolv.conf /opt/alpine/1.7/etc/<br />
sudo mount -t proc proc /opt/alpine/1.7/proc<br />
sudo mount -o bind /dev /opt/alpine/1.7/dev<br />
<br />
* Enter the chroot<br />
<br />
sudo chroot /opt/alpine/1.7 /bin/bash --login<br />
<br />
Now we are in the build environment chroot.<br />
<br />
* Download latest portage snapshot [http://mirror.gentoo.se/snapshots/portage-latest.tar.bz2 portage-latest.tar.bz2] from Gentoo and unpack it to /usr<br />
<br />
cd /usr<br />
wget -q -O - http://mirror.gentoo.se/snapshots/portage-latest.tar.bz2 portage-latest.tar.bz2 | tar -vjx<br />
<br />
* Check out the alpine-portage overlay from svn.<br />
<br />
svn co svn://svn.alpinelinux.org/alpine-portage/trunk /usr/alpine-portage<br />
<br />
* Download all the [http://dl.alpinelinux.org/alpine/v1.7/tbz2 tbz2] packages into the var/cache/packages directory. This is probably easiest with rsync.<br />
<br />
rsync -rauv rsync://rsync.alpinelinux.org/alpine/v1.7/tbz2/* /var/cache/packages/<br />
<br />
* Check out the alpine-builder scripts in usr/src/<br />
<br />
svn co svn://svn.alpinelinux.org/alpine-builder/trunk /usr/src/alpine<br />
<br />
* Configure portage to use the config from alpine-builder.<br />
<br />
rm -r /etc/make.conf /etc/portage<br />
ln -s /usr/src/alpine/buildroot/etc/make.conf /etc<br />
ln -s /usr/src/alpine/buildroot/etc/portage /etc<br />
<br />
* Update the portage tree (this takes some time first time you do it)<br />
<br />
emerge --sync<br />
<br />
* Install the kernel sources, using the downloaded tbz2. (-k makes emerge use precompiled packages. -u installs only packages that are new that currently installed)<br />
<br />
emerge -k =hardened-sources-2.6.20-r5<br />
<br />
Note that its a "precompiled" source package. It means it contains the kernel sources.<br />
<br />
* Make sure that /usr/src/linux points to your kernel version:<br />
<br />
cd /usr/src<br />
rm -f linux<br />
ln -s linux-2.6.20-hardened-r5 linux<br />
<br />
* Build the iso image<br />
<br />
cd /usr/src/alpine<br />
make<br />
<br />
If you get failures while building kernel drivers then you can workaround that by commenting out the specific in ''/usr/src/alpine/kernel/generic/drivers''.</div>Macbrody