text:
// ----------------------------------------------------------------------------------
//
// Copyright Microsoft Corporation
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
// http://www.apache.org/licenses/LICENSE-2.0
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
// ----------------------------------------------------------------------------------

using Microsoft.Azure.Graph.RBAC.Version1_6;
using Microsoft.Azure.Graph.RBAC.Version1_6.Models;
using Microsoft.Azure.ServiceManagemenet.Common.Models;
using Microsoft.Azure.Test;
using Microsoft.WindowsAzure.Commands.ScenarioTest;
using Microsoft.WindowsAzure.Commands.Test.Utilities.Common;
using Xunit;
using Xunit.Abstractions;

namespace Microsoft.Azure.Commands.Resources.Test.ScenarioTests
{
    public class ActiveDirectoryTests : RMTestBase
    {
        XunitTracingInterceptor interceptor { get; set; }

        public ActiveDirectoryTests(ITestOutputHelper output)
        {
            interceptor = new XunitTracingInterceptor(output);
            XunitTracingInterceptor.AddToContext(interceptor);
        }

        [Fact]
        [Trait(Category.AcceptanceType, Category.CheckIn)]
        public void TestGetAllADGroups()
        {
            const string scriptMethod = "Test-GetAllADGroups";
            ADGroup newGroup = null;
            var controllerAdmin = ResourcesController.NewInstance;

            controllerAdmin.RunPsTestWorkflow(
                // scriptBuilder
                () =>
                {
                    newGroup = CreateNewAdGroup(controllerAdmin);
                    return new[] { scriptMethod };
                },
                // initialize
                null,
                // cleanup
                () =>
                {
                    DeleteAdGroup(controllerAdmin, newGroup);
                },
                TestUtilities.GetCallingClass(),
                TestUtilities.GetCurrentMethodName());
        }

        [Fact]
        [Trait(Category.AcceptanceType, Category.CheckIn)]
        public void TestGetADGroupWithSearchString()
        {
            const string scriptMethod = "Test-GetADGroupWithSearchString '{0}'";
            ADGroup newGroup = null;
            var controllerAdmin = ResourcesController.NewInstance;

            controllerAdmin.RunPsTestWorkflow(
                // scriptBuilder
                () =>
                {
                    newGroup = CreateNewAdGroup(controllerAdmin);
                    return new[] { string.Format(scriptMethod, newGroup.DisplayName) };
                },
                // initialize
                null,
                // cleanup
                () =>
                {
                    DeleteAdGroup(controllerAdmin, newGroup);
                },
                TestUtilities.GetCallingClass(),
                TestUtilities.GetCurrentMethodName());
        }

        [Fact]
        [Trait(Category.AcceptanceType, Category.CheckIn)]
        public void TestGetADGroupWithBadSearchString()
        {
            ResourcesController.NewInstance.RunPsTest("Test-GetADGroupWithBadSearchString");
        }

        [Fact]
        [Trait(Category.AcceptanceType, Category.CheckIn)]
        public void TestGetADGroupWithObjectId()
        {
            const string scriptMethod = "Test-GetADGroupWithObjectId '{0}'";
            ADGroup newGroup = null;
            var controllerAdmin = ResourcesController.NewInstance;

            controllerAdmin.RunPsTestWorkflow(
                // scriptBuilder
                () =>
                {
                    newGroup = CreateNewAdGroup(controllerAdmin);
                    return new[] { string.Format(scriptMethod, newGroup.ObjectId) };
                },
                // initialize
                null,
                // cleanup
                () =>
                {
                    DeleteAdGroup(controllerAdmin, newGroup);
                },
                TestUtilities.GetCallingClass(),
                TestUtilities.GetCurrentMethodName());
        }

        [Fact]
        [Trait(Category.AcceptanceType, Category.CheckIn)]
        public void TestGetADGroupSecurityEnabled()
        {
            const string scriptMethod = "Test-GetADGroupSecurityEnabled '{0}' '{1}'";
            ADGroup newGroup = null;
            var controllerAdmin = ResourcesController.NewInstance;

            controllerAdmin.RunPsTestWorkflow(
                // scriptBuilder
                () =>
                {
                    newGroup = CreateNewAdGroup(controllerAdmin);
                    return new[] { string.Format(scriptMethod, newGroup.ObjectId, newGroup.SecurityEnabled) };
                },
                // initialize
                null,
                // cleanup
                () =>
                {
                    DeleteAdGroup(controllerAdmin, newGroup);
                },
                TestUtilities.GetCallingClass(),
                TestUtilities.GetCurrentMethodName());
        }

        [Fact]
        [Trait(Category.AcceptanceType, Category.CheckIn)]
        public void TestGetADGroupWithBadObjectId()
        {
            ResourcesController.NewInstance.RunPsTest("Test-GetADGroupWithBadObjectId");
        }

        [Fact]
        [Trait(Category.AcceptanceType, Category.CheckIn)]
        public void TestGetADGroupWithUserObjectId()
        {
            const string scriptMethod = "Test-GetADGroupWithUserObjectId '{0}'";
            User newUser = null;
            var controllerAdmin = ResourcesController.NewInstance;

            controllerAdmin.RunPsTestWorkflow(
                // scriptBuilder
                () =>
                {
                    newUser = CreateNewAdUser(controllerAdmin);
                    return new[] { string.Format(scriptMethod, newUser.ObjectId) };
                },
                // initialize
                null,
                // cleanup
                () =>
                {
                    DeleteAdUser(controllerAdmin, newUser);
                },
                TestUtilities.GetCallingClass(),
                TestUtilities.GetCurrentMethodName());
        }

        [Fact]
        [Trait(Category.AcceptanceType, Category.CheckIn)]
        public void TestGetADGroupMemberWithGroupObjectId()
        {
            const string scriptMethod = "Test-GetADGroupMemberWithGroupObjectId '{0}' '{1}' '{2}'";
            User newUser = null;
            ADGroup newGroup = null;
            var controllerAdmin = ResourcesController.NewInstance;

            controllerAdmin.RunPsTestWorkflow(
                // scriptBuilder
                () =>
                {
                    newUser = CreateNewAdUser(controllerAdmin);
                    newGroup = CreateNewAdGroup(controllerAdmin);

                    string memberUrl = string.Format(
                        "{0}{1}/directoryObjects/{2}",
                        controllerAdmin.GraphClient.BaseUri.AbsoluteUri,
                        controllerAdmin.GraphClient.TenantID,
                        newUser.ObjectId);

                    controllerAdmin.GraphClient.Groups.AddMember(newGroup.ObjectId, new GroupAddMemberParameters(memberUrl));

                    return new[] { string.Format(scriptMethod, newGroup.ObjectId, newUser.ObjectId, newUser.DisplayName) };
                },
                // initialize
                null,
                // cleanup
                () =>
                {
                    DeleteAdUser(controllerAdmin, newUser);
                    DeleteAdGroup(controllerAdmin, newGroup);
                },
                TestUtilities.GetCallingClass(),
                TestUtilities.GetCurrentMethodName());
        }

        [Fact]
        [Trait(Category.AcceptanceType, Category.CheckIn)]
        public void TestGetADGroupMemberWithBadGroupObjectId()
        {
            ResourcesController.NewInstance.RunPsTest("Test-GetADGroupMemberWithBadGroupObjectId");
        }

        [Fact]
        [Trait(Category.AcceptanceType, Category.CheckIn)]
        public void TestGetADGroupMemberWithUserObjectId()
        {
            const string scriptMethod = "Test-GetADGroupMemberWithUserObjectId '{0}'";
            User newUser = null;
            var controllerAdmin = ResourcesController.NewInstance;

            controllerAdmin.RunPsTestWorkflow(
                // scriptBuilder
                () =>
                {
                    newUser = CreateNewAdUser(controllerAdmin);
                    return new[] { string.Format(scriptMethod, newUser.ObjectId) };
                },
                // initialize
                null,
                // cleanup
                () =>
                {
                    DeleteAdUser(controllerAdmin, newUser);
                },
                TestUtilities.GetCallingClass(),
                TestUtilities.GetCurrentMethodName());
        }

        [Fact]
        [Trait(Category.AcceptanceType, Category.CheckIn)]
        public void TestGetADGroupMemberFromEmptyGroup()
        {
            const string scriptMethod = "Test-GetADGroupMemberFromEmptyGroup '{0}'";
            ADGroup newGroup = null;
            var controllerAdmin = ResourcesController.NewInstance;

            controllerAdmin.RunPsTestWorkflow(
                // scriptBuilder
                () =>
                {
                    newGroup = CreateNewAdGroup(controllerAdmin);
                    return new[] { string.Format(scriptMethod, newGroup.ObjectId) };
                },
                // initialize
                null,
                // cleanup
                () =>
                {
                    DeleteAdGroup(controllerAdmin, newGroup);
                },
                TestUtilities.GetCallingClass(),
                TestUtilities.GetCurrentMethodName());
        }

        [Fact]
        [Trait(Category.AcceptanceType, Category.CheckIn)]
        public void TestGetADServicePrincipalWithObjectId()
        {
            const string scriptMethod = "Test-GetADServicePrincipalWithObjectId '{0}'";
            ServicePrincipal newServicePrincipal = null;
            Application app = null;
            var controllerAdmin = ResourcesController.NewInstance;

            controllerAdmin.RunPsTestWorkflow(
                // scriptBuilder
                () =>
                {
                    app = CreateNewAdApp(controllerAdmin);
                    newServicePrincipal = CreateNewAdServicePrincipal(controllerAdmin, app.AppId);
                    return new[] { string.Format(scriptMethod, newServicePrincipal.ObjectId) };
                },
                // initialize
                null,
                // cleanup
                () =>
                {
                    DeleteAdServicePrincipal(controllerAdmin, newServicePrincipal);
                    DeleteAdApp(controllerAdmin, app);
                },
                TestUtilities.GetCallingClass(),
                TestUtilities.GetCurrentMethodName());
        }

        [Fact]
        [Trait(Category.AcceptanceType, Category.CheckIn)]
        public void TestGetADServicePrincipalWithBadObjectId()
        {
            ResourcesController.NewInstance.RunPsTest("Test-GetADServicePrincipalWithBadObjectId");
        }

        [Fact]
        [Trait(Category.AcceptanceType, Category.CheckIn)]
        public void TestGetADServicePrincipalWithUserObjectId()
        {
            const string scriptMethod = "Test-GetADServicePrincipalWithUserObjectId '{0}'";
            User newUser = null;
            var controllerAdmin = ResourcesController.NewInstance;

            controllerAdmin.RunPsTestWorkflow(
                // scriptBuilder
                () =>
                {
                    newUser = CreateNewAdUser(controllerAdmin);
                    return new[] { string.Format(scriptMethod, newUser.ObjectId) };
                },
                // initialize
                null,
                // cleanup
                () =>
                {
                    DeleteAdUser(controllerAdmin, newUser);
                },
                TestUtilities.GetCallingClass(),
                TestUtilities.GetCurrentMethodName());
        }

        [Fact]
        [Trait(Category.AcceptanceType, Category.CheckIn)]
        public void TestGetADServicePrincipalWithSPN()
        {
            const string scriptMethod = "Test-GetADServicePrincipalWithSPN '{0}'";
            ServicePrincipal newServicePrincipal = null;
            Application app = null;
            var controllerAdmin = ResourcesController.NewInstance;

            controllerAdmin.RunPsTestWorkflow(
                // scriptBuilder
                () =>
                {
                    app = CreateNewAdApp(controllerAdmin);
                    newServicePrincipal = CreateNewAdServicePrincipal(controllerAdmin, app.AppId);
                    return new[] { string.Format(scriptMethod, newServicePrincipal.ServicePrincipalNames[1]) };
                },
                // initialize
                null,
                // cleanup
                () =>
                {
                    DeleteAdServicePrincipal(controllerAdmin, newServicePrincipal);
                    DeleteAdApp(controllerAdmin, app);
                },
                TestUtilities.GetCallingClass(),
                TestUtilities.GetCurrentMethodName());
        }

        [Fact]
        [Trait(Category.AcceptanceType, Category.CheckIn)]
        public void TestGetADServicePrincipalWithBadSPN()
        {
            ResourcesController.NewInstance.RunPsTest("Test-GetADServicePrincipalWithBadSPN");
        }

        [Fact]
        [Trait(Category.AcceptanceType, Category.CheckIn)]
        public void TestGetADServicePrincipalWithSearchString()
        {
            const string scriptMethod = "Test-GetADServicePrincipalWithSearchString '{0}'";
            ServicePrincipal newServicePrincipal = null;
            Application app = null;
            var controllerAdmin = ResourcesController.NewInstance;

            controllerAdmin.RunPsTestWorkflow(
                // scriptBuilder
                () =>
                {
                    app = CreateNewAdApp(controllerAdmin);
                    newServicePrincipal = CreateNewAdServicePrincipal(controllerAdmin, app.AppId);
                    return new[] { string.Format(scriptMethod, newServicePrincipal.DisplayName) };
                },
                // initialize
                null,
                // cleanup
                () =>
                {
                    DeleteAdServicePrincipal(controllerAdmin, newServicePrincipal);
                    DeleteAdApp(controllerAdmin, app);
                },
                TestUtilities.GetCallingClass(),
                TestUtilities.GetCurrentMethodName());
        }

        [Fact]
        [Trait(Category.AcceptanceType, Category.CheckIn)]
        public void TestGetADServicePrincipalWithBadSearchString()
        {
            ResourcesController.NewInstance.RunPsTest("Test-GetADServicePrincipalWithBadSearchString");
        }

        [Fact]
        [Trait(Category.AcceptanceType, Category.CheckIn)]
        public void TestGetAllADUser()
        {
            const string scriptMethod = "Test-GetAllADUser";
            User newUser = null;
            var controllerAdmin = ResourcesController.NewInstance;

            controllerAdmin.RunPsTestWorkflow(
                // scriptBuilder
                () =>
                {
                    newUser = CreateNewAdUser(controllerAdmin);
                    return new[] { string.Format(scriptMethod) };
                },
                // initialize
                null,
                // cleanup
                () =>
                {
                    DeleteAdUser(controllerAdmin, newUser);
                },
                TestUtilities.GetCallingClass(),
                TestUtilities.GetCurrentMethodName());
        }

        [Fact]
        [Trait(Category.AcceptanceType, Category.CheckIn)]
        public void TestGetADUserWithObjectId()
        {
            const string scriptMethod = "Test-GetADUserWithObjectId '{0}'";
            User newUser = null;
            var controllerAdmin = ResourcesController.NewInstance;

            controllerAdmin.RunPsTestWorkflow(
                interceptor,
                // scriptBuilder
                () =>
                {
                    newUser = CreateNewAdUser(controllerAdmin);
                    return new[] { string.Format(scriptMethod, newUser.ObjectId) };
                },
                // initialize
                null,
                // cleanup
                () =>
                {
                    DeleteAdUser(controllerAdmin, newUser);
                },
                TestUtilities.GetCallingClass(),
                TestUtilities.GetCurrentMethodName());
        }

        [Fact]
        [Trait(Category.AcceptanceType, Category.CheckIn)]
        public void TestGetADUserWithMail()
        {
            const string scriptMethod = "Test-GetADUserWithMail '{0}'";
            User newUser = null;
            var controllerAdmin = ResourcesController.NewInstance;

            controllerAdmin.RunPsTestWorkflow(
                // scriptBuilder
                () =>
                {
                    newUser = CreateNewAdUser(controllerAdmin);
                    return new[] { string.Format(scriptMethod, newUser.UserPrincipalName) };
                },
                // initialize
                null,
                // cleanup
                () =>
                {
                    DeleteAdUser(controllerAdmin, newUser);
                },
                TestUtilities.GetCallingClass(),
                TestUtilities.GetCurrentMethodName());
        }

        [Fact]
        [Trait(Category.AcceptanceType, Category.CheckIn)]
        public void TestGetADUserWithBadObjectId()
        {
            ResourcesController.NewInstance.RunPsTest("Test-GetADUserWithBadObjectId");
        }

        [Fact]
        [Trait(Category.AcceptanceType, Category.CheckIn)]
        public void TestGetADUserWithGroupObjectId()
        {
            const string scriptMethod = "Test-GetADUserWithGroupObjectId '{0}'";
            ADGroup newGroup = null;
            var controllerAdmin = ResourcesController.NewInstance;

            controllerAdmin.RunPsTestWorkflow(
                // scriptBuilder
                () =>
                {
                    newGroup = CreateNewAdGroup(controllerAdmin);
                    return new[] { string.Format(scriptMethod, newGroup.ObjectId) };
                },
                // initialize
                null,
                // cleanup
                () =>
                {
                    DeleteAdGroup(controllerAdmin, newGroup);
                },
                TestUtilities.GetCallingClass(),
                TestUtilities.GetCurrentMethodName());
        }

        [Fact]
        [Trait(Category.AcceptanceType, Category.CheckIn)]
        public void TestGetADUserWithUPN()
        {
            const string scriptMethod = "Test-GetADUserWithUPN '{0}'";
            User newUser = null;
            var controllerAdmin = ResourcesController.NewInstance;

            controllerAdmin.RunPsTestWorkflow(
                // scriptBuilder
                () =>
                {
                    newUser = CreateNewAdUser(controllerAdmin);
                    return new[] { string.Format(scriptMethod, newUser.UserPrincipalName) };
                },
                // initialize
                null,
                // cleanup
                () =>
                {
                    DeleteAdUser(controllerAdmin, newUser);
                },
                TestUtilities.GetCallingClass(),
                TestUtilities.GetCurrentMethodName());
        }

        [Fact(Skip = "Currently not working.")]
        public void TestGetADUserWithFPOUPN()
        {
            ResourcesController.NewInstance.RunPsTest("Test-GetADUserWithFPOUPN");
        }

        [Fact]
        [Trait(Category.AcceptanceType, Category.CheckIn)]
        public void TestGetADUserWithBadUPN()
        {
            ResourcesController.NewInstance.RunPsTest("Test-GetADUserWithBadUPN");
        }

        [Fact]
        [Trait(Category.AcceptanceType, Category.CheckIn)]
        public void TestGetADUserWithSearchString()
        {
            const string scriptMethod = "Test-GetADUserWithSearchString '{0}'";
            User newUser = null;
            var controllerAdmin = ResourcesController.NewInstance;

            controllerAdmin.RunPsTestWorkflow(
                // scriptBuilder
                () =>
                {
                    newUser = CreateNewAdUser(controllerAdmin);
                    return new[] { string.Format(scriptMethod, newUser.DisplayName) };
                },
                // initialize
                null,
                // cleanup
                () =>
                {
                    DeleteAdUser(controllerAdmin, newUser);
                },
                TestUtilities.GetCallingClass(),
                TestUtilities.GetCurrentMethodName());
        }

        [Fact]
        [Trait(Category.AcceptanceType, Category.CheckIn)]
        public void TestGetADUserWithBadSearchString()
        {
            ResourcesController.NewInstance.RunPsTest("Test-GetADUserWithBadSearchString");
        }

        [Fact]
        [Trait(Category.AcceptanceType, Category.CheckIn)]
        public void TestNewADApplication()
        {
            ResourcesController.NewInstance.RunPsTest("Test-NewADApplication");
        }

        [Fact]
        [Trait(Category.AcceptanceType, Category.CheckIn)]
        public void TestNewADServicePrincipalWithoutApp()
        {
            ResourcesController.NewInstance.RunPsTest("Test-NewADServicePrincipalWithoutApp");
        }

        [Fact(Skip = "Not working in playback.")]
        [Trait(Category.AcceptanceType, Category.CheckIn)]
        public void TestCreateDeleteAppPasswordCredentials()
        {
            ResourcesController.NewInstance.RunPsTest("Test-CreateDeleteAppPasswordCredentials");
        }

        [Fact(Skip = "Not working in playback.")]
        [Trait(Category.AcceptanceType, Category.CheckIn)]
        public void TestCreateDeleteSpPasswordCredentials()
        {
            ResourcesController.NewInstance.RunPsTest("Test-CreateDeleteSpPasswordCredentials");
        }

        [Fact]
        [Trait(Category.AcceptanceType, Category.CheckIn)]
        public void TestNewADServicePrincipal()
        {
            const string scriptMethod = "Test-NewADServicePrincipal '{0}'";
            Application application = null;
            var controllerAdmin = ResourcesController.NewInstance;

            controllerAdmin.RunPsTestWorkflow(
                // scriptBuilder
                () =>
                {
                    application = CreateNewAdApp(controllerAdmin);
                    return new[] { string.Format(scriptMethod, application.AppId) };
                },
                // initialize
                null,
                // cleanup
                () =>
                {
                    DeleteAdApp(controllerAdmin, application);
                },
                TestUtilities.GetCallingClass(),
                TestUtilities.GetCurrentMethodName());
        }

        private User CreateNewAdUser(ResourcesController controllerAdmin)
        {
            var name = TestUtilities.GenerateName("aduser");
            var parameter = new UserCreateParameters
            {
                DisplayName = name,
                UserPrincipalName = name + "@" + controllerAdmin.UserDomain,
                AccountEnabled = true,
                MailNickname = name + "test",
                PasswordProfile = new PasswordProfile
                {
                    ForceChangePasswordNextLogin = false,
                    Password = TestUtilities.GenerateName("adpass") + "0#$"
                }
            };

            return controllerAdmin.GraphClient.Users.Create(parameter);
        }

        private ADGroup CreateNewAdGroup(ResourcesController controllerAdmin)
        {
            var parameter = new GroupCreateParameters
            {
                DisplayName = TestUtilities.GenerateName("adgroup"),
                MailNickname = TestUtilities.GenerateName("adgroupmail")
            };
            return controllerAdmin.GraphClient.Groups.Create(parameter);
        }

        private Application CreateNewAdApp(ResourcesController controllerAdmin)
        {
            var appName = TestUtilities.GenerateName("adApplication");
            var url = string.Format("http://{0}/home", appName);
            var appParam = new ApplicationCreateParameters
            {
                AvailableToOtherTenants = false,
                DisplayName = appName,
                Homepage = url,
                IdentifierUris = new[] { url },
                ReplyUrls = new[] { url }
            };

            return controllerAdmin.GraphClient.Applications.Create(appParam);
        }

        private ServicePrincipal CreateNewAdServicePrincipal(ResourcesController controllerAdmin, string appId)
        {
            var spParam = new ServicePrincipalCreateParameters
            {
                AppId = appId,
                AccountEnabled = true
            };

            return controllerAdmin.GraphClient.ServicePrincipals.Create(spParam);
        }

        private void DeleteAdUser(ResourcesController controllerAdmin, User user)
        {
            if (user != null)
            {
                controllerAdmin.GraphClient.Users.Delete(user.ObjectId);
            }
        }
        private void DeleteAdGroup(ResourcesController controllerAdmin, ADGroup group)
        {
            if (group != null)
            {
                controllerAdmin.GraphClient.Groups.Delete(group.ObjectId);
            }
        }
        private void DeleteAdApp(ResourcesController controllerAdmin, Application app)
        {
            if (app != null)
            {
                controllerAdmin.GraphClient.Applications.Delete(app.ObjectId);
            }
        }

        private void DeleteAdServicePrincipal(ResourcesController controllerAdmin, ServicePrincipal newServicePrincipal)
        {
            if (newServicePrincipal != null)
            {
                controllerAdmin.GraphClient.ServicePrincipals.Delete(newServicePrincipal.ObjectId);
            }
        }
    }
}


text:
/**
 * @module  node-attach
 * @author  lifesinger@gmail.com
 */
KISSY.add('node-attach', function(S, undefined) {

    var DOM = S.DOM, Event = S.Event,
        nodeTypeIs = DOM._nodeTypeIs,
        isKSNode = DOM._isKSNode,
        NP = S.Node.prototype,
        NLP = S.NodeList.prototype,
        GET_DOM_NODE = 'getDOMNode',
        GET_DOM_NODES = GET_DOM_NODE + 's',
        HAS_NAME = 1,
        ONLY_VAL = 2,
        ALWAYS_NODE = 4;

    function normalGetterSetter(isNodeList, args, valIndex, fn) {
        var elems = this[isNodeList ? GET_DOM_NODES : GET_DOM_NODE](),
            args2 = [elems].concat(S.makeArray(args));

        if (args[valIndex] === undefined) {
            return fn.apply(DOM, args2);
        } else {
            fn.apply(DOM, args2);
            return this;
        }
    }

    function attach(methodNames, type) {
        S.each(methodNames, function(methodName) {
            S.each([NP, NLP], function(P, isNodeList) {

                P[methodName] = (function(fn) {
                    switch (type) {
                        // fn(name, value, /* other arguments */): attr, css etc.
                        case HAS_NAME:
                            return function() {
                                return normalGetterSetter.call(this, isNodeList, arguments, 1, fn);
                            };

                        // fn(value, /* other arguments */): text, html, val etc.
                        case ONLY_VAL:
                            return function() {
                                return normalGetterSetter.call(this, isNodeList, arguments, 0, fn);
                            };

                        // parent, next 等返回 Node/NodeList 的方法
                        case ALWAYS_NODE:
                            return function() {
                                var elems = this[isNodeList ? GET_DOM_NODES : GET_DOM_NODE](),
                                    ret = fn.apply(DOM, [elems].concat(S.makeArray(arguments)));
                                return ret ? new S[S.isArray(ret) ? 'NodeList' : 'Node'](ret) : null;
                            };

                        default:
                            return function() {
                                // 有非 undefined 返回值时,直接 return 返回值;没返回值时,return this, 以支持链式调用。
                                var elems = this[isNodeList ? GET_DOM_NODES : GET_DOM_NODE](),
                                    ret = fn.apply(DOM, [elems].concat(S.makeArray(arguments)));
                                return ret === undefined ? this : ret;
                            };
                    }
                })(DOM[methodName]);
            });
        });
    }

    // selector
    S.mix(NP, {
        /**
         * Retrieves a node based on the given CSS selector.
         */
        one: function(selector) {
            return S.one(selector, this[0]);
        },

        /**
         * Retrieves a nodeList based on the given CSS selector.
         */
        all: function(selector) {
            return S.all(selector, this[0]);
        }
    });

    // dom-data
    attach(['data', 'removeData'], HAS_NAME);

    // dom-class
    attach(['hasClass', 'addClass', 'removeClass', 'replaceClass', 'toggleClass']);

    // dom-attr
    attach(['attr', 'removeAttr'], HAS_NAME);
    attach(['val', 'text'], ONLY_VAL);

    // dom-style
    attach(['css'], HAS_NAME);
    attach(['width', 'height'], ONLY_VAL);

    // dom-offset
    attach(['offset'], ONLY_VAL);
    attach(['scrollIntoView']);

    // dom-traversal
    attach(['parent', 'next', 'prev', 'siblings', 'children'], ALWAYS_NODE);
    attach(['contains']);

    // dom-create
    attach(['html'], ONLY_VAL);
    attach(['remove']);

    // dom-insertion
    S.each(['insertBefore', 'insertAfter'], function(methodName) {
        // 目前只给 Node 添加,不考虑 NodeList(含义太复杂)
        NP[methodName] = function(refNode) {
            DOM[methodName].call(DOM, this[0], refNode);
            return this;
        };
    });
    S.each([NP, NLP], function(P, isNodeList) {
        S.each(['append', 'prepend'], function(insertType) {
            // append 和 prepend
            P[insertType] = function(html) {
                return insert.call(this, html, isNodeList, insertType);
            };
            // appendTo 和 prependTo
            P[insertType + 'To'] = function(parent) {
                return insertTo.call(this, parent, insertType);
            };
        });
    });

    function insert(html, isNodeList, insertType) {
        if (html) {
            S.each(this, function(elem) {
                var domNode;

                // 对于 NodeList, 需要 cloneNode, 因此直接调用 create
                if (isNodeList || S.isString(html)) {
                    domNode = DOM.create(html);
                } else {
                    if (nodeTypeIs(html, 1) || nodeTypeIs(html, 3)) domNode = html;
                    if (isKSNode(html)) domNode = html[0];
                }

                DOM[insertType](domNode, elem);
            });
        }
        return this;
    }

    function insertTo(parent, insertType) {
        if ((parent = S.get(parent)) && parent.appendChild) {
            S.each(this, function(elem) {
                DOM[insertType](elem, parent);
            });
        }
        return this;
    }

    // event-target
    S.mix(NP, S.EventTarget);
    NP._supportSpecialEvent = true;
    NP._addEvent = function(type, handle, capture) {
        Event._simpleAdd(this[0], type, handle, capture);
    };
    NP._removeEvent = function(type, handle, capture) {
        Event._simpleRemove(this[0], type, handle, capture);
    };
    delete NP.fire;

    S.mix(NLP, S.EventTarget);
    delete NLP.fire;
});

redpajama_set_name: RedPajamaGithub


text:
module Language.BinaryTree.AST where

data IntTree = Node IntTree IntTree | Leaf Int
  deriving (Show,Eq)

t1 :: IntTree
t1 = Node (Leaf 1) (Node (Leaf 1) (Leaf 1))

t2 :: IntTree
t2 = Node (Leaf 1) (Leaf 2)


text:
.section {
	display: table;
	table-layout: fixed;
	width: 100%;
}

.section .left {
	display: table-cell;
	width: 300px;
	vertical-align: top;
}

.section .right {
	display: table-cell;
	vertical-align: top;
	text-align: right;
	font-size: 18px;
}

.section .right img {
	padding-bottom: 20px;
}


text:
@if(method_exists('\\'.$controller, 'create'))

@endif

    @if(!$exclude->contains('destroy'))
    <button class="btn btn-default btn-sm"></button>
    @endif


text:
// Copyright Yahoo. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
#pragma once

#include <vespa/vespalib/util/bits.h>

namespace vespalib {

/**
 * @brief Crc32 class
 *
 * This has fast Crc32 calculation base on table lookup.
 **/
class crc_32_type
{
public:
    crc_32_type() : _c(uint32_t(-1)) { }
    void process_block(const void *start, const void *end) { process_bytes(start, (const uint8_t *)end-(const uint8_t *)start); }
    void process_bytes(const void *start, size_t sz);
    uint32_t checksum() const { return _c ^ uint32_t(-1); }
    static uint32_t crc(const void * v, size_t sz);
private:
    uint32_t _c;
    class CrcTableInit
    {
    public:
        CrcTableInit();
        static uint32_t crc(uint8_t v);
    };
    static uint32_t _crc[256];
    static CrcTableInit _crcTableInit;
};

}


text:
import re

from ovs.db import error

def textToNroff(s, font=r'\fR'):
    def escape(match):
        c = match.group(0)

        # In Roman type, let -- in XML be \- in nroff.  That gives us a way to
        # write minus signs, which is important in some places in manpages.
        #
        # Bold in nroff usually represents literal text, where there's no
        # distinction between hyphens and minus sign.  The convention in nroff
        # appears to be to use a minus sign in such cases, so we follow that
        # convention.
        #
        # Finally, we always output - as a minus sign when it is followed by a
        # digit.
        if c.startswith('-'):
            if c == '--' and font == r'\fR':
                return r'\-'
            if c != '-' or font in (r'\fB', r'\fL'):
                return c.replace('-', r'\-')
            else:
                return '-'

        if c == '\\':
            return r'\e'
        elif c == '"':
            return r'\(dq'
        elif c == "'":
            return r'\(cq'
        elif c == ".":
            # groff(7) says that . can be escaped by \. but in practice groff
            # still gives an error with \. at the beginning of a line.
            return font + "."
        else:
            raise error.Error("bad escape")

    # Escape - \ " ' . as needed by nroff.
    s = re.sub('(-[0-9]|--|[-"\'\\\\.])', escape, s)
    return s

def escapeNroffLiteral(s, font=r'\fB'):
    return font + r'%s\fR' % textToNroff(s, font)

def inlineXmlToNroff(node, font, to_upper=False):
    if node.nodeType == node.TEXT_NODE:
        if to_upper:
            return textToNroff(node.data.upper(), font)
        else:
            return textToNroff(node.data, font)
    elif node.nodeType == node.ELEMENT_NODE:
        if node.tagName in ['code', 'em', 'option']:
            s = r'\fB'
            for child in node.childNodes:
                s += inlineXmlToNroff(child, r'\fB')
            return s + font
        elif node.tagName == 'ref':
            s = r'\fB'
            if node.hasAttribute('column'):
                s += node.attributes['column'].nodeValue
                if node.hasAttribute('key'):
                    s += ':' + node.attributes['key'].nodeValue
            elif node.hasAttribute('table'):
                s += node.attributes['table'].nodeValue
            elif node.hasAttribute('group'):
                s += node.attributes['group'].nodeValue
            elif node.hasAttribute('db'):
                s += node.attributes['db'].nodeValue
            else:
                raise error.Error("'ref' lacks required attributes: %s" % node.attributes.keys())
            return s + font
        elif node.tagName == 'var' or node.tagName == 'dfn':
            s = r'\fI'
            for child in node.childNodes:
                s += inlineXmlToNroff(child, r'\fI')
            return s + font
        else:
            raise error.Error("element <%s> unknown or invalid here" % node.tagName)
    else:
        raise error.Error("unknown node %s in inline xml" % node)

def pre_to_nroff(nodes, para, font):
    s = para + '\n.nf\n'
    for node in nodes:
        if node.nodeType != node.TEXT_NODE:
            fatal("<pre> element may only have text children")
        for line in node.data.split('\n'):
            s += escapeNroffLiteral(line, font) + '\n.br\n'
    s += '.fi\n'
    return s

def blockXmlToNroff(nodes, para='.PP'):
    s = ''
    for node in nodes:
        if node.nodeType == node.TEXT_NODE:
            s += textToNroff(node.data)
            s = s.lstrip()
        elif node.nodeType == node.ELEMENT_NODE:
            if node.tagName in ['ul', 'ol']:
                if s != "":
                    s += "\n"
                s += ".RS\n"
                i = 0
                for liNode in node.childNodes:
                    if (liNode.nodeType == node.ELEMENT_NODE
                        and liNode.tagName == 'li'):
                        i += 1
                        if node.tagName == 'ul':
                            s += ".IP \\(bu\n"
                        else:
                            s += ".IP %d. .25in\n" % i
                        s += blockXmlToNroff(liNode.childNodes, ".IP")
                    elif (liNode.nodeType != node.TEXT_NODE
                          or not liNode.data.isspace()):
                        raise error.Error("<%s> element may only have <li> children" % node.tagName)
                s += ".RE\n"
            elif node.tagName == 'dl':
                if s != "":
                    s += "\n"
                s += ".RS\n"
                prev = "dd"
                for liNode in node.childNodes:
                    if (liNode.nodeType == node.ELEMENT_NODE
                        and liNode.tagName == 'dt'):
                        if prev == 'dd':
                            s += '.TP\n'
                        else:
                            s += '.TQ .5in\n'
                        prev = 'dt'
                    elif (liNode.nodeType == node.ELEMENT_NODE
                          and liNode.tagName == 'dd'):
                        if prev == 'dd':
                            s += '.IP\n'
                        prev = 'dd'
                    elif (liNode.nodeType != node.TEXT_NODE
                          or not liNode.data.isspace()):
                        raise error.Error("<dl> element may only have <dt> and <dd> children")
                    s += blockXmlToNroff(liNode.childNodes, ".IP")
                s += ".RE\n"
            elif node.tagName == 'p':
                if s != "":
                    if not s.endswith("\n"):
                        s += "\n"
                    s += para + "\n"
                s += blockXmlToNroff(node.childNodes, para)
            elif node.tagName in ('h1', 'h2', 'h3'):
                if s != "":
                    if not s.endswith("\n"):
                        s += "\n"
                nroffTag = {'h1': 'SH', 'h2': 'SS', 'h3': 'ST'}[node.tagName]
                s += '.%s "' % nroffTag
                for child_node in node.childNodes:
                    s += inlineXmlToNroff(child_node, r'\fR',
                                          to_upper=(nroffTag == 'SH'))
                s += '"\n'
            elif node.tagName == 'pre':
                fixed = node.getAttribute('fixed')
                if fixed == 'yes':
                    font = r'\fL'
                else:
                    font = r'\fB'
                s += pre_to_nroff(node.childNodes, para, font)
            else:
                s += inlineXmlToNroff(node, r'\fR')
        else:
            raise error.Error("unknown node %s in block xml" % node)
    if s != "" and not s.endswith('\n'):
        s += '\n'
    return s


text:
Ejercicios de Jose Manuel Rosell Sánchez
========================================

## Sesión 17-octubre-2014

Tema 1
======

###Ejercicio 1

El servidor ha sido sacado de la página web de *PcComponentes*, y se puede consultar [aquí.](http://www.pccomponentes.com/fujitsu_primergy_rx300_s8_formato_rack.html)

* La amortización a 4 años sería:
	* 627,27€ * 0,25 = 156,8175€ al año.

* La amortización a 7 años sería:
	* 627,27€ * 0,10 = 62,727€ primer y segundo año
	* 627,27€ * 0,20 = 125,534€ tercer, cuarto y quinto año
	* 627,27€ * 0,10 = 62,727€ sexto y séptimo año

La amortización nunca puede superar el 25% de la base imponible (base sin IVA) del servidor

###Ejercicio 2

Máquina | Cores CPU | RAM (GB) | Almacenamiento (GB) | Precio/año
--- | --- | --- | --- | ---
Amazon m3.large | 2 | 7.5 | 32 SSD | 959,95€
HP ProDesk 600 G1 | 4 | 4 | 500 S-ATA | 639€

- Si se usa el 1% del tiempo:
	* Amazon = 365 dias * 0,01 = 4 días * 2,63€/día = 10,52€/año
	* HP = 4 días * 1,75€/día = 7€/año

- Si se usa el 10% del tiempo:
	* Amazon = 365 dias * 0,1 = 37 días * 2,63€/día = 97,31€/año
	* HP = 37 días * 1,75€/día = 64,75€/año

###Ejercicio 3

####Apartado 1

* Para alojar varios clientes en un sólo servidor utilizaría virualización a nivel de sistema operativo, ya que como el anfitrión y el cliente utilizan el mismo sistema operativo, la comunicación entre ambos es mucho más fácil.

* Para crear un sistema eficiente de web + middleware + base de datos utilizaría una virtualización de aplicaciones, debido a que una base de datos consume muchos recursos y si se quiere que sea eficiente lo mejor es utilizar una virtualización a nivel de aplicación.

* Para un sistema de prueba de software e integración continua utilizaría una virtualización de entornos de desarrollo para reproducir los entornos de desarrollo fielmente.

####Apartado 2

```
#!/bin/bash
VARIABLE=Hola
SALUDO=mundo
echo
echo "$VARIABLE "" $SALUDO"
echo
```

Para empaquetarlo se descarga el directorio y se hace `make`. Despues, se accede al directorio y se ejecuta `cde <ruta_del_archivo_a_empaqutar`. El portable del script tiene el nombre de `<nombre_del_scritp.cde>`.

###Ejercicio 4

Comandos del tutorial:
	* docker version
	* docker search tutorial
	* docker pull learn/tutorial
	* docker run learn/tutorial echo "hello world"
	* docker run learn/tutorial apt-get install -y ping
	* docker commit 698 learn/ping
	* docker run learn/ping ping google.com
	* docker inspect efe
	* docker push learn/ping

###Ejercicio 5

Para instalar con el comando `sudo apt-get install git` se instala git. Con el comando `git --version` se puede ver la versión instalad de Git.

###Ejercicio 6

####Apartado 1

Para crear un repositorio vamos a GitHub y lo creamos pulsando sobre el simbolo "+" que hay al lado de nuestro nombre de usuario. Para clonar el repositorio, copiamos la dirección que aparece en el menú de la derecha y desde línea de comandos escribimos: `git clone <dirección repositorio>`

####Apartado 2

Para modificar el archivo README, nos colocamos en el directorio clonado anteriormente he iniciamos Git utilizando `git init`. Modificamos el archivo README. Una vez modificado, utilizamos `git add README` y posteriorment `git commit -m "Un comentario"`. Ya esta listo para sincronizarlo con el servidor, para ello ejecutamos `git push origin master`. Si recargamos la página de GitHub nos aparecera el fichero README con la modificación realizada.

###Ejercicio 7

Sí esta instalado por defecto, y el directorio contiene:

```
blkio	cpuacct     devices	hugetlb	      perf_event
cpu 	cpuset	    freezer	memory	      systemd
```

###Ejercicio 8

####Apartado 1

Creamos tres grupos de control utilizando `mkdir`en el directorio `/sys/fs/cgroup`.

Creamos en el directorio `/sys/fs/cgroup/cpuset` el usuario *buenos*. Buscamos los procesos que hay mediante `ps` y el proceso de firefox se lo asignamos al usuario mediante el comando `echo xxx > /cgroup/buenos/tasks`, donde *xxx* se sustituye por el PID del proceso del navegador.

Repetimos el proceso cambiando el nombre de usuario por *regular* al que le asignamos la tarea del procesador de textos. Y al último usuario le ponemos el nombre *malos* y le asignamos la tarea bash.

Uso de cada usuario con su tarea:
	* **Buenos** = 1014638829
	* **Regular** = 135538
	* **Malos** = 37121973

####Apartado 2

###Ejercicio 9

####Apartado 2

Para crear el fichero *cgconfig.conf* se utiliza el comando `mount {<controller> = <path>}`. Para asignar la prioridad se utiliza
```
group <name> {
       	[permissions]
       		<controller> {
       	         <param name> = <param value>;
		}
	}
```

Un ejemplo donde se da menos prioridad a los procesos de usuario sería:
```
mount {cpu = /cgroup/cpu}

group usuario {
	cpu {
		cpu.shares="10";
            }
	}

group sistema
	{ cpu {
		cpu.shares="20";
	      }
	}
```

####Apartado 3

Se ha utilizado el navegador Firefox para comprobar los efectos de migración. Se utilizan los subgrupos *buenos* y *malos* pertenecientes al grupo *teestoyviendo*. Al primer subgrupo se le asigna el núcleo 0 y al segundo grupo se le asigna el grupo 4. Se le asigna el proceso del navegador al subgrupo *buenos* y teniendo un uso de un 0.7% de uso del procesador. Posteriormente se le pasa la tarea al subgrupo *malos* con el comando `cgclassify -g memory,cpu:malos 3369`. En el cambio, el núclo 4 usa un 2% de la CPU.

###Ejercicio 10

* **Modelo de procesador**: Intel(R) Core(TM) i3 CPU M 350 @ 2.27GHz
* **Salida de la orden**: flags		: fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush dts acpi mmx fxsr sse sse2 ss ht tm pbe syscall nx rdtscp lm constant_tsc arch_perfmon pebs bts rep_good nopl xtopology nonstop_tsc aperfmperf pni dtes64 monitor ds_cpl vmx est tm2 ssse3 cx16 xtpr pdcm sse4_1 sse4_2 popcnt lahf_lm arat dtherm tpr_shadow vnmi flexpriority ept vpid

###Ejercicio 11

El nçucleo instalado en mi ordenador contiene el módulo KVM. El resultado de la ejecución del comando `kmv-ok`es:

```
INFO: /dev/kvm exists
KVM acceleration can be used
```

###Ejercicio12

Un ejemplo de Saas sería la web de [phixr](http://es.phixr.com/photo/userindex), que es un editor de fotos online. No necesitas instalar nada en la máquina local, solo tienes que acceder a la web y subir la foto que deseas modificar. Esto tiene evidentes problemas de privacidad y la incertidumbre de como la web puede utilizar las fotos que edites desde su web.

## Sesión 7-Noviembre-2014

Tema 2
======

###Ejercicio 1

Se instala **virtualenv** para Python con la orden `sudo apt-get install libc6-dev python-dev python-virtualenv`.

###Ejercicio 2

He creado una cuenta gratuita en **OpenShift**, con mi dirección de correo electrónico.

###Ejercicio 3

Se puede acceder al blog creado en WordPress desde OpenShift [en la esta URL](http://php-primeraapp.rhcloud.com/).

###Ejercicio 4

Para crear un script para un documento desde la dirección [script.google.com](script.google.com), de elige la opción *Drive* del menu que aparece. Se abre una ventana de script con dos funciones por defecto:
```
function listFilesInFolder(id) {
  var folder = DriveApp.getFolderById(id);
  var contents = folder.getFiles();
  var file;
  var name;

  while(contents.hasNext()) {
    file = contents.next();
    name = file.getName();
    Logger.log(name);
  }
};

function moveFileToFolder(fileId, targetFolderId) {
  var targetFolder = DriveApp.getFolderById(targetFolderId);
  var file = DriveApp.getFileById(fileId);
  var currentFolders = file.getParents();
  while (currentFolders.hasNext()) {
    var currentFolder = currentFolders.next();
    currentFolder.removeFile(file);
  }
  targetFolder.addFile(file);
};
```
Se puede cambiar el nombre del proyecto en la parte superior izquierda pinchando y poniendo el nombre que se desee. En la parte de debajo de la barra de herramientas, donde aparece el simbolo del play, a la derecha de esta posición se puede seleccionar la función que se va a ejecutar.

###Ejercicio 5

El lenguaje de programación que utilizo habitualmente es **JAVA** y el sistema de automatización para la construcción que utilizo es **ant**. Para compilar un proyecto en JAVA utilizando ant se puede utilizar la instrucción: `ant -buildfile build.xml`.

###Ejercicio 6

###Ejercicio 7

El entorno de pruebas para el lenguaje de programación *Python* es *UnitTest*, aunque comúnmente se denomina *PyUnit*. [En este enlace](http://magmax.org/blog/2011/09/27/python-pruebas-2/) podemos encontrar un pequeño ejemplo de como hacer pruebas a una función en Python, codificado desde cualquier editor de texto y ejecutado desde la línea de comandos.

## Sesión 24-Noviembre-2014

Tema 3
======

###Ejercicio 1

Se crea un archivo .iso a partir de cualquier archivo con la orden `genisoimage -o prueba_iso.iso prueba_iso.md`, donde *prueba_iso.iso* es el archivo que queremos obtener y *prueba_iso.md* el fichero a partir del cual generar el archivo .iso. Creamos un directorio y creamos un espacio de nombres en ese directorio con la orden `sudo unshare miDirectorio`. Ahora montamos el archivo .iso en este nombre de espacios con la orden `mount -o loop prueba_iso.md /mnt/miDirectorio`.

###Ejercicio 2
1. Con el comando `brctl show` muestra todos los puentes configurados en el sistema operativo. En mi caso particular, existe uno, con el nombre *docker0*
2. Creamos una interfaz virtual con el comando `sudo brctl addbr prueba`. Para asignarla a la interfaz ethernet se utiliza el siguiente comando `sudo brctl addif prueba eth0`

## Sesión 1-Diciembre-2014

Tema 4
======

###Ejercicio 1

En Ubuntu 14.04 se instala con el comando `sudo apt-get install lxc`.

###Ejercicio 2

Al instalar el contenedor, se crea la interfaz puente *lxcbr0*, con las siguientes características:

```
4: lxcbr0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UNKNOWN group default
    link/ether e2:33:7a:19:67:f9 brd ff:ff:ff:ff:ff:ff
    inet 10.0.3.1/24 brd 10.0.3.255 scope global lxcbr0
       valid_lft forever preferred_lft forever
    inet6 fe80::e033:7aff:fe19:67f9/64 scope link
       valid_lft forever preferred_lft forever

```
 donde tiene una ip *10.0.3.1/24* que no es local, ya que las locales son del tipo *192.168.x.x*, simula como si fuese otra máquina diferente, aunque está alojada en la misma máquina.

###Ejercicio 3
1. Creado en el *ejercicio 2*, se puede arrancar el contenedor con el siguiente comando: `sudo lxc-start -n una-caja`, donde *una-caja* es el contenedor que tiene instalado el sistema operativop Debian.

2.

###Ejercicio 4
1. Para instalar *lxc-webpanel* se necesitan permisos root, para ello primero de todo ejecutamos `sudo su` y seguidamente ejecutamos `wget http://lxc-webpanel.github.com/tools/install.sh -O - | bash`, y con esto tenemos instalado *lxc-webpanel*. Para gestionar los contenedores, accedemos a la url **localhost:5000** y como usuario ponemos *admin* y como contraseña *admin*.

2. Una vez dentro del panel para restringir los recursos al contenedor *una-caja*, pulsamos sobre el nombre del contendor. Nos aparece la configuración del contenedor, en *CPU Shares* ponemos 1024, en la opción *CPU* ponemos 1 (que indica que solo puede ejecutar un procesador), y, por último, en *Memory Limit* ponemos 1024 MB ( que indica que solo puede utilizar 1GB de memoria RAM). Cuando tenemos todo configurado, pulsamos sobre el botón *Apply* para aplicar los cambios.

###Ejercicio 5

###Ejercicio 6
1. Para instalar *juju* se utilizan las siguientes órdenes:
```
sudo add-apt-repository ppa:juju/stable
sudo apt-get update && sudo apt-get install juju-core
```
Ejecutando `juju version` muestra la versión instalada. En mi caso muestra:

> 1.20.13-trusty-amd64

2. Primero debemos instalar un taper, para ello ejecutamos la orden `juju bootstrap`. Una vez creado el taper ejecutamos la orden `juju deploy mysql` para instalar mysql en el taper.

###Ejercicio 7
1. Para desmontar ejecutamos en orden secuencial:
```
juju remove-service mysql
sudo juju destroy-machine 1
```

Para ver las máquinas se utiliza `juju status`. **Nunca se elimina la unidad 0**.

2. Añadimos una 'máquina' nueva con la orden `sudo juju add-machine` y seguidamente le instalamos mysql con la orden `juju deploy mysql`. Ahora añadimos *mediawiki* con `juju deploy mediawiki`, y una vez añadido creamos una relación entre mysql y mediawiki, para ello ejecutamos `juju add-relation mediawiki:slave mysql:db`. Ejecutando `juju status` vemos lo siguiente:
```
environment: local
machines:
  "0":
    agent-state: started
    agent-version: 1.20.13.1
    dns-name: localhost
    instance-id: localhost
    series: trusty
    state-server-member-status: has-vote
  "2":
    agent-state: started
    agent-version: 1.20.13.1
    dns-name: 10.0.3.250
    instance-id: jmrosell-local-machine-2
    series: trusty
    hardware: arch=amd64
services:
  mediawiki:
    charm: cs:trusty/mediawiki-3
    exposed: false
    relations:
      slave:
      - mysql
    units:
      mediawiki/0:
        agent-state: started
        agent-version: 1.20.13.1
        machine: "2"
        public-address: 10.0.3.250
  mysql:
    charm: cs:trusty/mysql-12
    exposed: false
    relations:
      cluster:
      - mysql
      db:
      - mediawiki
```

Lo exponemos para su uso público con `sudo juju expose mediawiki`

3.
```
/#!/bin/bash
juju add-machine
juju deploy mediawiki
juju deploy mysql
juju add-relation mediawiki:slave mysql:db
juju expose mediawiki
```

###Ejercicio 8
Instalamos *libvirt* con:
> sudo apt-get install kvm libvirt-bin
Añadimos un usuario al grupo que va a trabajar con las máquinas virtuales:
> sudo adduser $USER libvirtd

###Ejercicio 9
Instalamos un contenedor con la orden:
> sudo virt-install --name ubuntu --ram 512 --disk path=/home/ubuntu,size=4 -c /home/JMRosell/Descargas/lubuntu-14.10-desktop-i386.iso

Donde el nombre del contenedor es *ubuntu*, con 512 MB de memoria RAM, el sitio donde se va a alojar (/home/ubuntu), cuanto tamaño tiene el contenedor 4 GB y por último el path donde se encuentra el archivo ISO que vamos a montar en el contenedor.

###Ejercicio 10

Para instalar *docker* en Ubuntu hay que ejecutar:

> $ sudo apt-get -y install docker.io

> $ ln -sf /usr/bin/docker.io /usr/local/bin/docker

> $ sed -i '$acomplete -F _docker docker' /etc/bash_completion.d/docker.io

Opcionalmente se puede configurar *Docker* para empezar cuando se arranca el servidor, para ello ejecutar:

> update-rc.d docker.io defaults

###Ejercicio 11

1. Vamos a instalar la imagen alternativa a Ubuntu llamada *tutumcloud*, para ello nos descagamos el [repositorio de GitHub](https://github.com/tutumcloud/tutum-ubuntu) de *tutum* con la orden `git clone`. Nos posicionamos en el directorio y ejecutamos `sudo docker -t tutum/ubuntu:latest .

###Ejercicio 12

###Ejercicio 13

###Ejercicio 14


text:
namespace csapex
{
enum class TracingType
{
    PROCESS,
    SLOT_CALLBACK,
    OTHER
};
}

#endif  // TRACING_TYPE_H