My new CloudStack-driven cloud is being managed by a cluster that consists of 8 virtual machines that are running on 2 different physical hosts. I can shut down any of these hosts at any moment, but it won’t affect the cloud-management service.

Sometimes it’s necessary to maintain 2 different CloudStack setups (let’s call them Cloud-A and Cloud-B) sharing the same IP-address ranges. For example, we might need that when we’re building a new CloudStack-driven environment and going to move all the virtual infrastructure from the old setup to the new one, but as we can’t just make move everything in a couple of hours (let’s say, we have about a thousand of VMs), we have to let 2 different CloudStack-driven virtual datacenters use the same networks. We should understand that we might have to maintain 2 different CloudStack setups for a few days or weeks or even months, so we have to take care about the situation when someone deploys a new VM or assign a new IP-address to a currently running VM. It means that both CloudStack setups should understand that the IP-address has been allocated, otherwise we might come to the situation when both CloudStacks will assign the same IP-address to their VMs and we’ll face a major trouble.

We can solve it by making a simple script that would look up what IP-addresses are being in the “Allocated” state in Cloud-A and make them “Allocated” to a certain account in Cloud-B. Then the script would do the same to mark as “Allocated” in Cloud-A the addresses that are really assigned to some instances in Cloud-B. Also it would be great if the script would mark as “Free” the IP-addresses that aren’t being used, of course.

I’m going to add some functionality (for example, notifications about the IP-address that are already having the same assigned/free state in both clouds), so you’re welcome to get the latest revision on GitHub.

Each element of the ACS-driven infrastructure is represented as a Moose-sugared Perl object, has attributes and executes methods. All kinds of elements consume (inherit) the same Moose role (MonkeyMan::CloudStack::API::Roles::Element) which makes that class an element.

Elements getting to know what they shall do to perform some work, are looking up the element’s vocabulary (MonkeyMan::CloudStack::API::Vocabulary;), the vocabulary configures the element like DNA. 🙂

Perl

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

88

89

90

91

92

93

94

95

96

97

98

99

100

101

102

103

104

105

106

107

108

109

110

111

112

113

114

115

116

117

118

119

120

121

our%vocabulary_tree=(

type=>'Account',

name=>'account',

entity_node=>'account',

actions=>{

list=>{

request=>{

command=>'listAccounts',

async=>0,

paged=>1,

parameters=>{

all=>{

required=>0,

command_parameters=>{'listall'=>'true'},

},

accounttype=>{

required=>0,

command_parameters=>{'accounttype'=>'<%VALUE%>'},

},

filter_by_id=>{

required=>0,

command_parameters=>{'id'=>'<%VALUE%>'},

},

filter_by_name=>{

required=>0,

command_parameters=>{'name'=>'<%VALUE%>'},

},

filter_by_domainid=>{

required=>0,

command_parameters=>{'domainid'=>'<%VALUE%>'}

}

}

},

response=>{

response_node=>'listaccountsresponse',

results=>{

element=>{

return_as=>[qw(dom element id)],

queries=>['/<%OUR_RESPONSE_NODE%>/<%OUR_ENTITY_NODE%>'],

required=>0,

multiple=>1

},

id=>{

return_as=>[qw(value)],

queries=>['/<%OUR_RESPONSE_NODE%>/<%OUR_ENTITY_NODE%>/id'],

required=>0,

multiple=>1

},

}

}

},

create=>{

request=>{

command=>'createAccount',

async=>0,

paged=>0,

parameters=>{

type=>{

required=>1,

command_parameters=>{'accounttype'=>'<%VALUE%>'},

},

name=>{

required=>1,

command_parameters=>{'username'=>'<%VALUE%>'},

},

email=>{

required=>1,

command_parameters=>{'email'=>'<%VALUE%>'},

},

first_name=>{

required=>1,

command_parameters=>{'firstname'=>'<%VALUE%>'},

},

last_name=>{

required=>1,

command_parameters=>{'lastname'=>'<%VALUE%>'},

},

password=>{

required=>1,

command_parameters=>{'password'=>'<%VALUE%>'},

},

account=>{

required=>0,

command_parameters=>{'account'=>'<%VALUE%>'},

},

domain=>{

required=>0,

command_parameters=>{'domainid'=>'<%VALUE%>'},

},

time_zone=>{

required=>0,

command_parameters=>{'timezone'=>'<%VALUE%>'},

},

network_domain=>{

required=>0,

command_parameters=>{'networkdomain'=>'<%VALUE%>'},

}

}

},

response=>{

response_node=>'createaccountresponse',

results=>{

element=>{

return_as=>[qw(dom element id)],

queries=>['/<%OUR_RESPONSE_NODE%>/<%OUR_ENTITY_NODE%>'],

required=>0,

multiple=>1

},

id=>{

return_as=>[qw(value)],

queries=>['/<%OUR_RESPONSE_NODE%>/<%OUR_ENTITY_NODE%>/id'],

required=>0,

multiple=>1

}

}

}

}

}

);

# Yes, I'd definitely would translate it yo YAML, but I'd like it to stay Perl-executable

Yes, that’s what MonkeyMan knows about the Domain infrastructure element in the ACS-driven cloud. And when I needed to teach it how to handle with another infrastructure element – an account, I’d just added it as a separate vocabulary:

I had started to play music in the same year when I heard Amy Jade Winehouse, so I consider her as my teacher of music. I had no teachers besides of her. I started to play to write a song for her, to say how much grateful I am for showing me things that I never thought about before. I started to play and very soon after that (in a year) my teacher expelled me to the street, so I’ve been wandering everywhere with my guitar and amp, playing on streets of my city and in places where no one plays ever. Snow, rain, wind or sun – nothing can stop me. I can walk playing my tunes all the day long (and I usually do it at least once per week) and I feel so much grateful to the teacher for giving me these tunes. She guides me and, I believe, she’ll do it forever (please!).

It’s a pretty common occurrence when you have 2 hosts pinging each other and some packets are being lost. And sometimes you need to make sure, that the routing device in between of these host really receives a request, forwards this request to the target, receives the reply and forwards it back to the request’s initiator. If you’re lucky enough to run tcpdump on this intermediate device (if it runs some Unix-like OS, e.g. Linux or FreeBSD), you can wrap it to the script that will analyze each transit packet to find out what exactly is going wrong.

If you watch the tcpdump output with the naked eye, you’ll see the following pattern:

It reads the output of tcpdump and prints an alert message when the usual pattern gets broken. When some request or some reply is absent or the seq-number is unexpected, it will print something like that:

Sometimes it’s not enough to estimate the packet loss ratio only, but to make sure that a TCP-connections are stable. Run the “server” instance (sockping -m server -p 65513) on some host and run the “client” (sockping -m client -h 13.13.13.13 -p 65513) on another one, and the “client” will connect to the “server” and then it’ll be sending probe messages and expecting replies. If the TCP-session is broken, the “server” states it to STDERR.

What if people influence on each other much more than we tend to believe? Did you ever assume that some events in other people’s lives, some traits of their destinies can occasionaly exude on our own lifeways? What if the more we interact with certain people and the more impact they have on us, the more circumstances of their lives can recur in our own lives? And what if each person (even the ones we meet in early childhood) leave some imprint on our future lives? And what if it happens not because we’ve “learned” something from these people or intentionally “got” something from them, but just because the reality works this way, so we repeat even things that we consider as undesirable? What if we always inherit some random (are they really random?) things from their scenarios even if we don’t want that? What do you think?